Nice TWiki > Dev > FeatureProposals > BlockCallSyntax (r1.3) 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

Topic BlockCallSyntax . { Edit | Attach | Ref-By | Printable | Diffs | r1.16 | > | r1.15 | > | r1.14 | More }
Revision r1.3 - 12 Nov 2003 - 03:13 GMT - TroyHeninger
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.