[pitch] Eliminate the "T1 -> T2" syntax, require "(T1) -> T2"

We currently accept function type syntax without parentheses, like:

  Int -> Float
  String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

  (Int) -> Float
  (String) -> ()

Thoughts?

-Chris

To me, the unparenthesized style suggests that the input and output are peers, which feels more natural for the sort of value-to-value transform/predicate where this most commonly occurs. Parenthesizing the input feels fussier, which contributes to a sense that the argument is just one component to producing the result.

The parentheses are grammatically unnecessary in most cases (by frequency of use in higher-use programming, not by feature count). Our grammar generally allows grammatically-unnecessary parentheses to be omitted (except the C-style for loop, until we killed it) — I guess you could count function call syntax, but we had strong reasons there that don't seem to apply here. We notably chose to deviate from C statement grammar specifically to allow unnecessary parentheses to be omitted. This would feel weirdly inconsistent with that.

I guess the flip side is that call and declaration syntax both require parentheses (unless the only argument is a trailing closure), but again, we had strong justifications for that: declarations would always be ambiguous without parens, and calls would have serious problems (and the style-wars factor would be much larger, especially now with mandatory keyword arguments by default).

John.

···

On Apr 14, 2016, at 9:57 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

Didn't know that T -> U was even legal, which more or less sums up my opinion on this.

Does it meet Swift's philosophy? Yes
Does it enhance the language? I believe it does
Is it still required in a post-splatted world? Probably not
Eliminating a language inconsistency, especially a meaningless one? Yes.

-- E, unless I'm missing something big here

···

On Apr 14, 2016, at 10:57 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

+1

···

On Apr 14, 2016, at 11:57 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1. The only times I've ever had to use this outside of HoFs were dirty, dirty hacks that probably should have used this anyway. I can stomach an extra bit of syntax everywhere if it means removing an inconsistency in the wider language.

~Robert Widmann

2016/04/15 0:57、Chris Lattner via swift-evolution <swift-evolution@swift.org> のメッセージ:

···

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Chris,

The proposed syntax looks and reads so much better! +1.

···

On 15 April 2016 at 05:57, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

  Int -> Float
  String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

  (Int) -> Float
  (String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hmm... I don't think this is clearer:

    let fn: (Int) -> (Int) -> Int

I think it's much less readable and really, the () are syntactically redundant: the -> is really what distinguishes this as a function.

Also, this would look like a error now:

    let fn: (Int) -> ()

Did the user mean that it returns nothing, or did they forget the rest of the function signature?

I'd like to see more consistency and less redundancy, including special cases, in the language in general, but this change just seems to make it different in another way, but still not consistent throughout the language constructs.

-David

···

On Apr 14, 2016, at 9:57 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1 Makes language cleaner and more consistent.

···

On 15 Apr 2016, at 06:57, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

While it's technically correct, I agree with John's assessment that this is "fussy". `T -> U` doesn't confuse people and doesn't confuse the compiler; removing it would require extra punctuation for no particular reason. It would also become inconsistent with the paren-less `{ param in … }` syntax, which I think is very important for keeping usage sites simple and clean.

What I think we *should* eliminate, however, is using `Void` to mean "no arguments" in a closure type. `Void -> Int` should mean that the type takes one argument which happens to be an empty tuple. If you want no arguments, write `() -> Int`. Similarly, a typedef for a 2-tuple (like `Dictionary.Element`) should be recognized as one tuple parameter, not two singleton parameters. With that in place, `T -> U` becomes merely a convenient shorthand for the canonical form, `(T) -> U`.

I mean, it's not that big a deal; if you remove it, everyone will type extra parentheses and live with it. But recognize that doing so would improve the language, not the end-user experience.

···

--
Brent Royal-Gordon
Architechies

1 Like

Chris,

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

I don't care about this particular question too much, although I still prefer less parenthesis where possible.

But I fear that going this way, we'll soon arrive at requiring parenthesis for the block arguments:

do_something { foo in
  ...
}

and that (the parenthesis in blocks) is something I would love to avoid.

Note how all of your arguments would apply to the blocks as well.

A.

If the original rationale is gone, shouldn’t we also get rid of the empty tuple-type and replace it by a full-blown Void instead of Void being a typealis for the empty tuple?

(Int) -> Float
(String) -> Void
() -> Void
() -> Double

It looks more consistent to me.

···

On 15 Apr 2016, at 06:57, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I understand the reasoning, but I really like and often use the shorthand
notation. I hope that it stays.

···

On Fri, Apr 15, 2016 at 12:58 AM Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

  Int -> Float
  String -> ()

etc. The original rationale aligned with the fact that we wanted to treat
all functions as taking a single parameter (which was often of tuple type)
and producing a tuple value (which was sometimes a tuple, in the case of
void and multiple return values). However, we’ve long since moved on from
that early design point: there are a number of things that you can only do
in a parameter list now (varargs, default args, etc), implicit tuple splat
has been removed, and the compiler has long ago stopped modeling function
parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity
between parameter list and function types, and just require parenthesis on
the argument list. The types above can be trivially written as:

  (Int) -> Float
  (String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1, as I've always said.

By everyone but the purely-functional-programming crowd, ()s are
associated with functions; it makes sense to see them in the type, and
the non-uniformity created by seeing A->B in the places it's allowed is
not balanced by a widespread drop in syntactic noise.

···

on Thu Apr 14 2016, Chris Lattner <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

  Int -> Float
  String -> ()

etc. The original rationale aligned with the fact that we wanted to
treat all functions as taking a single parameter (which was often of
tuple type) and producing a tuple value (which was sometimes a tuple,
in the case of void and multiple return values). However, we’ve long
since moved on from that early design point: there are a number of
things that you can only do in a parameter list now (varargs, default
args, etc), implicit tuple splat has been removed, and the compiler
has long ago stopped modeling function parameters this way. Beyond
that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity
between parameter list and function types, and just require
parenthesis on the argument list. The types above can be trivially
written as:

  (Int) -> Float
  (String) -> ()

Thoughts?

--
Dave

Noooooo :(

I understand and appreciate the rationale, uniformity between declaration and use site being a good thing, but IMHO the proposal just brings unnecessary noise, far outweighing the small benefit of having the symmetry.

1. What I’m worried the most is the “parentheses blindness”. In higher-order functions, or just when I take a simple callback closure, there are just a lot of parentheses (add to that generics, and there’s a lot of angled brackets too). And it just becomes hard to instantly decipher. To me, `func blah(f: Int -> Float) -> String` is easier to read that `func blah(f: (Int) -> Float) -> String`. Or just notice how noisy `(f: () -> ())` is. This is why I like the convention of using `Void` for void-returning functions. There’s less noise in `(f: () -> Void)`, and even better in `(f: Int -> Void)`. I don’t have to mentally match parentheses, because whenever possible, there’s just one set of parens around the main function declaration. When punctuation like parentheses is used sparingly, it carries a lot of weight. Requiring parentheses around T in T -> U doesn’t seem to have a significant reason aside from style/taste.

2. I’m not convinced at all that `(Foo) -> Bar` is immediately more obvious to people. I don’t have data to back it up, but my intuition is that `Foo -> Bar` is simple and understandable. “A function from Foo to Bar”, I’m thinking. I don’t have to mentally parse the vacuous parentheses, just to conclude that there’s, in fact, just one parameter. And when there is more than one parameter, the parentheses in `(Foo, Bar) -> Baz` instantly carry more weight.

3. Swift has been really good at removing unnecessary punctuation. Parentheses in if statements, semicolons, shortcut forms of closures, etc. This is a good thing. As I said before, using punctuation only when it matters makes it stand out, and in places where it doesn’t, by removing it we’re increasing the signal-to-noise ratio. To me, parentheses in `(Foo) -> Bar` don’t matter. I can see why one could argue for them, or prefer them, but it seems like a merely stylistic choice. Let’s keep them where it matters, and leave this to personal preference.

Best,
— Radek

···

On 15 Apr 2016, at 06:57, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

How would this proposal affect curried functions? Would this:

   func foo(int: Int) -> Int -> String -> String

become this?

   func foo(int: Int) -> (((Int) -> String) -> String)

As I understand, that transformation is an accurate representation of the actual return type of “foo”, but it’s certainly going to raise some complaints among the functional Swift community if required.

-BJ

···

We currently accept function type syntax without parentheses, like:

Int ->Float
String ->()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) ->Float
(String) ->()

Thoughts?

-Chris

How would this proposal affect curried functions? Would this:

  func foo(int: Int) -> Int -> String -> String

become this?

  func foo(int: Int) -> (((Int) -> String) -> String)

As I understand, that transformation is an accurate representation of the actual return type of “foo”, but it’s certainly going to raise some complaints among the functional Swift community if required.

-BJ

···

We currently accept function type syntax without parentheses, like:

Int ->Float
String ->()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) ->Float
(String) ->()

Thoughts?

-Chris

After some discussions, I support this proposal and think this will make Swift more consistent and clear about where is parameters and where is result type. Especially this important in code like:
Int -> String -> Void -> Float
which IMO should be
(Int) -> (String) -> (Void) -> Float
as Int/String/Void are parameters, Float is result type.

But IMO not just "require parenthesis on the argument list", but also disallow parenthesis in result type in meaning of tuple of single argument(as we discussed in this thread with @Anton), disallow placing () in (), disallow Void in () in result - to prevent all these ((((())))) (((Void))) etc in parameters and in result type.

@Chris, would you form a proposal for this subject?

···

On 15.04.2016 7:57, Chris Lattner via swift-evolution wrote:

We currently accept function type syntax without parentheses, like:

  Int -> Float
  String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

  (Int) -> Float
  (String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

We currently accept function type syntax without parentheses, like:

To me, the unparenthesized style suggests that the input and output are peers, which feels more natural for the sort of value-to-value transform/predicate where this most commonly occurs. Parenthesizing the input feels fussier, which contributes to a sense that the argument is just one component to producing the result.
The parentheses are grammatically unnecessary in most cases (by frequency of use in higher-use programming, not by feature count).

I agree with your point that many simple higher order programming examples (e.g. map, filter, etc) take a single argument. That said, I don’t agree that this means that we should syntactically privilege this special case. In many places in the Swift grammar we aim for consistency, even if it means a bit more punctuation in specific cases.

Our grammar generally allows grammatically-unnecessary parentheses to be omitted (except the C-style for loop, until we killed it) — I guess you could count function call syntax, but we had strong reasons there that don't seem to apply here. We notably chose to deviate from C statement grammar specifically to allow unnecessary parentheses to be omitted. This would feel weirdly inconsistent with that.

We allow parens to be omitted from control flow expressions, where they are redundant with paren exprs. I don’t see how that translates to our type grammar.

I guess the flip side is that call and declaration syntax both require parentheses (unless the only argument is a trailing closure), but again, we had strong justifications for that: declarations would always be ambiguous without parens, and calls would have serious problems (and the style-wars factor would be much larger, especially now with mandatory keyword arguments by default).

Right, but regardless of *why* we always require parens on Decls and ApplyExprs, we really do (and that isn’t going to change). Being consistent between func decls and function types is quite important IMO.

-Chris

···

On Apr 14, 2016, at 10:21 PM, John McCall <rjmccall@apple.com> wrote:

On Apr 14, 2016, at 9:57 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

If the original rationale is gone, shouldn’t we also get rid of the empty tuple-type and replace it by a full-blown Void instead of Void being a typealis for the empty tuple?

This could be done, but it would make the language larger and less consistent. It would require introducing a new concept (a first class Void type). Further, at some point we may have the ability to define algorithms over arbitrary width tuples (e.g. perhaps like C++ variadic templates) and that benefits from having the empty tuple as a base case.

-Chris

···

On Apr 15, 2016, at 5:11 AM, David Hart <david@hartbit.com> wrote:

(Int) -> Float
(String) -> Void
() -> Void
() -> Double

It looks more consistent to me.

On 15 Apr 2016, at 06:57, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

We currently accept function type syntax without parentheses, like:

Int -> Float
String -> ()

etc. The original rationale aligned with the fact that we wanted to treat all functions as taking a single parameter (which was often of tuple type) and producing a tuple value (which was sometimes a tuple, in the case of void and multiple return values). However, we’ve long since moved on from that early design point: there are a number of things that you can only do in a parameter list now (varargs, default args, etc), implicit tuple splat has been removed, and the compiler has long ago stopped modeling function parameters this way. Beyond that, it eliminates one potential style war.

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

Thoughts?

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I see your concern, and while someone might propose that, I would be pretty strongly against it. The closure parameter syntax is already magical in many ways (e.g. you can elide the "-> ReturnType” before in, so I don’t see a reason to mechanically force alignment with type syntax. Further, closures are written much more often than function types, so terseness is a lot more beneficial.

-Chris

···

On Apr 15, 2016, at 12:47 AM, Andrey Tarantsov <andrey@tarantsov.com> wrote:

Chris,

Given all this, I think it makes sense to go for syntactic uniformity between parameter list and function types, and just require parenthesis on the argument list. The types above can be trivially written as:

(Int) -> Float
(String) -> ()

I don't care about this particular question too much, although I still prefer less parenthesis where possible.

But I fear that going this way, we'll soon arrive at requiring parenthesis for the block arguments:

do_something { foo in
  ...
}

and that (the parenthesis in blocks) is something I would love to avoid.