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 – Roger Johansson Jan 11 '11 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 '11 at 12:39
  • On my swedish keyboard they are altgr+8/9, so a bit wrist intensive.. – Roger Johansson Jan 11 '11 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 '11 at 15:01

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} – Roger Johansson Jan 11 '11 at 12:00
  • -> or => (C# style) is neat. better than lambda key word from ruby – Lukasz Madon Jan 11 '11 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 '11 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 '11 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, privacy policy and cookie policy

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