I'm playing around a bit with my own C like DSL grammar and would like some oppinions.

I've reserved the use of "(...)" for invocations. eg:


My grammar supports "trailing closures" , pretty much like Ruby's blocks that can be passed as the last argument of an invocation.

Currently my grammar support trailing closures like this:

   //parameterless closure passed as the last argument to foo


foo(1,2) [x]
    //closure with one argument (x) passed as the last argument to foo
    print (x);

The reason why I use [args] instead of (args) is that (args) is ambigious:

foo(1,2) (x)

There is no way in this case to tell if foo expects 3 arguments (int,int,closure(x)) or if foo expects 2 arguments and returns a closure with one argument(int,int) -> closure(x) So thats pretty much the reason why I use [] as for now.

I could change this to something like:

foo(1,2) : (x)


foo(1,2) (x) ->

So the actual question is, what do you think looks best?

[...] is somewhat wrist unfriendly.

let x = [a,b] 


  • If anyone is interested in this sort of things, here is what I have so far : rogeralsing.com/?s=plastic Jan 11, 2011 at 12:00
  • Out of interest, why are square brackets [...] wrist intensive? On my keyboard they are lowercase letters next to return, same keys as braces, easier to type than any of the other bracket types.
    – Orbling
    Jan 11, 2011 at 12:39
  • On my swedish keyboard they are altgr+8/9, so a bit wrist intensive.. Jan 11, 2011 at 13:16
  • Almost every language uses parentheses more often than square brackets, so if you're programming on a standard US keyboard, you should have them switched around so that parentheses are unshifted.
    – rwallace
    Aug 25, 2011 at 15:01

6 Answers 6


I like Groovy's syntax, which is

foo(1,2) { x ->
  • I've decided to use this approach , but with ":" as separator as for now... eg foo(1,2) {arg : arg.bar == 2} Jan 11, 2011 at 12:00
  • -> or => (C# style) is neat. better than lambda key word from ruby Jan 11, 2011 at 12:56

I like the C# syntax, nice and short
(x, y) => { /* code */ }

And to declare
Action< int, int>


I don't think bounding to C like syntax is good idea. I hope you checked Haskell syntax. If you're making a DSL, I think it's main purpose is abstraction of the domain. Basically, C like syntax is too verbose...

Haskell example:

-- Defining a function
add x y = x + y

-- Defining a lambda function ('\' means lambda character 'λ')
add = \ x y -> x + y

I have always thought they should be threated as any other regular parameter.

Consider javascript

 sort( sortFunctionGoesHere );

Invoked as:

sort( function( a, b ) {
    return b - a; 

So, I would rather have:

foo( int, int , closure(int) )

And use it like this:

foo( 1, 2, (x) {
  • The thing is, if you do this extensively, your code contains a lot of closing braces, that are hard to associate with their counterpart. Also, by convention, a trailing block quite clearly communicates iteration, whereas passing a function object could also be an asynchronous callback or an iteration block (and possibly other things).
    – back2dos
    Jan 11, 2011 at 11:29
  • Really? I didn't know that. I have seen this in Smalltalk and Javascript before, and in both, they were part of the parameters. It was until Ruby and the Groovy that I saw the form you mention. Anyway, interesting +1
    – OscarRyz
    Jan 11, 2011 at 12:12

First of all, the closure parameter should be a normal part of the parameter list.

Thus, there is no fundamental difference in declaration or usage. I strongly dislike Ruby introducing special cases with yield, non-first-class functions and an &-parameter.


function foreach(collection, f) 
  // code


foreach([1, 2, 3], print)

should work in any case.

That said, you can add syntactic sugar for providing a final lambda argument in a more convenient way. I see two major options, depending on your language design.

  1. Plain syntax sugar. I like @ammoQ's approach with

    foreach([1, 2, 3]) { x ->

    So f(args ...) { vars -> body } is literally translated to f(args ..., λvars -> body)

  2. That's the way i.e. Scala does it. As you mentioned

    There is no way in this case to tell if foo expects 3 arguments (int,int,closure(x)) or if foo expects 2 arguments and returns a closure with one argument(int,int) -> closure(x)

    Just use this idea - a function returning another function to be called is called currying, which is a very common pattern in functional programming.

    If you have curried functions in your language as Scala does, you just need a syntax for closures with { } being equal to regular parentheses. The rest is a regular call semantic. I.e.

    function foo(a, b)(c)(f) 
    foo(1, 2)(3) { x -> x + 1 }

Basically, defining the argument within the block is easier, because it resolves a lot of ambiguities, for example the way Groovy does it, as @ammoQ pointed out.

Ruby also does this, but is a little easier to parse than Groovy: foo(1,2) { |x,y| ... }

This can be simply parsed from left to right and it is simpler to read. Also, chances are good, you'll never allow | as a unary operator (i.e. at the beginning of a statement), so the risk of ambiguity is extremely low.

If that is too "wrist intense", I suppose foo(1,2) { <x,y> ... } might help on english keyboards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.