Nice TWiki > Dev > FeatureProposals > BlockCallSyntax (r1.6) TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Dev . { Changes | Index | Search | Go }
It would be good to allow a different syntax for method application in some circumstances. Specifically, it would be nice if:
foo
{
 baz();
}

could expand into

foo(()=> 
  { 
     baz();
  });

Basically, if a function call is followed immediately by a block, then the block is converted to a void->A function, where A is the return type of the function, and treated as the last argument to the function call. This part is easy to implement. But what if the block isn't the last argument or there are multiple blocks?

This would allow us to add features like C#'s 'using' keyword, without having to modify the syntax every time we want a new one: Do you have other examples than 'using'?


<A> A using(Disposable resource, void->A func)
{
  try
  {
     return func();
  }
  finally
  {
    resource.dispose();
  }
}

let stream = new FileInputStream("foo");
let value = using(stream) { char c = stream.read(); }

Of course, we might also want something other than a void->A function, perhaps we'd like to have a version of 'using' that doesn't require to first bind the used object to a name. We could solve this by instead expanding the block function into a function which takes exactly the same arguments, with the same names, that the named function takes:

//Assume an abstract interface for disposables here, makes the
//typing nicer.
<Disposable A, B> B using(A resource, A->B func)
{
  try
  {
     return func(resource: resource);
  }
  finally
  {
    resource.dispose();
  }
}

I think it's more consistent to allow argument of function types to be named.

<Disposable A, B> B using(A resource, (resource A)->B func)
{
  try
  {
     return func(resource);
  }
  finally
  {
    resource.dispose();
  }
}

so now we can do

using(new FileInputStream("foo"))
{
  //use the file input stream with the name 'resource':
  char c = resource.read();
}

which the compiler will translate to:

using(new FileInputStream("foo"), (FileInputStream resouce) =>
  {
    //use the file input stream with the name 'resource':
    char c = resource.read();
  });

-- BrynKeller - 31 Oct 2003

The problem with this is that you can't choose the name of the variable so you end up with an general name. And it would get problematic when you nest 'using statements'. I'd rather write something like the following although I have no idea how that would look like on the implementation side of the function.

using(myFile = new FileInputStream("foo"))
{
 //do something with it
}

added some comments in italic -- ArjanB - 08 Nov 2003


I don't know why anyone hasn't recognized it yet, but you are getting closer and closer to the syntax of Ruby. I like the stronly typed-ness of Nice, but Ruby has tons of cool syntax sugar that I would also like to see in Nice. Blocks (or Closures) are only one of them. Many classes in Ruby have been designed to make heavy use of blocks passed to methods. I don't like some of the Ruby syntax, such as the yield call. But still, it would be good for the Nice compiler developers to take a close look at Ruby, and to adopt what they like. It's interesting that Nice has already adopted quite a bit of what Ruby has. They are both interesting languages. I can see, though, that Nice can more easily handle enterprise level projects than Ruby. Here're some links to learn about Ruby:
http://www.ruby-lang.org/en/
http://www.sofer.com/ruby/
http://www.rubycentral.com/

-- TroyHeninger - 12 Nov 2003

Seems more obvious to look at groovy. Maybe Nice has more in common with FlowJava Jiazzi and MultiJava than with scripting languages.

-- IsaacGouy - 31 Dec 2003


Maybe I should look at C# using before commenting but...

How am I supposed to figure out that this

  loop(5) { doSomeThing(); }

is shorthand for this

  loop(5, () => { doSomeThing(); } );

That doesn't look like the same kind of thing; this does

  loop(5, { doSomeThing(); } );

Smalltalk avoids the ugly syntax because blocks (Smalltalk anonymous functions) are objects with defined methods, so we can write something equivalent to { doSomeThing(); }.loop(5) and still have consistent language.

  loop(5) { doSomeThing(); } doesn't seem to fit with the existing forms in the language - it doesn't look like function application; it looks like a keyword but it isn't a keyword.

-- IsaacGouy - 08 Jan 2004

I don't think you should look at it as a shorthand for something else. It's more like a user defined statement.

BTW we are considering making () => doSomeThing(); } equivalent to { doSomeThing(); )

-- ArjanB - 08 Jan 2004

Topic BlockCallSyntax . { Edit | Attach | Ref-By | Printable | Diffs | r1.16 | > | r1.15 | > | r1.14 | More }
Revision r1.6 - 08 Jan 2004 - 20:51 GMT - ArjanB
Parents: WebHome > FeatureProposals
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.