How Nested Functions Work, part 1

Jari-Matti Mäkelä jmjmak at utu.fi.invalid
Wed Sep 2 05:09:06 PDT 2009


Nick Sabalausky wrote:

> "Jeremie Pelletier" <jeremiep at gmail.com> wrote in message
> news:h7h5i1$5mp$1 at digitalmars.com...
>>
>> While D is not the first place I see closures and nested functions, it is
>> the first language I come across that blends delegates, closures and
>> nested functions in a simple, elegant and intuitive manner.
>>
> 
> I almost agree. But not quite. D certainly handles much of it better than
> a lot of languages, and the syntax of the *actual* nested functions is
> nice. But there are still issues that bug the hell out of me.

> Quick! For each of these, valid or invalid?:
> 
> // A ////////////////////////
> void repeat(int n, delegate void(int i) dg)
> {
>     foreach(int i; 0..n)
>         dg(i);
> }
> repeat(5, delegate void(int i) { writefln("hi"); });
> 
> // B ////////////////////////
> void repeat(int n, void delegate(int i) dg)
> {
>     foreach(int i; 0..n)
>         dg(i);
> }
> repeat(5, void delegate(int i) { writefln("hi"); });
> 
> // C ////////////////////////
> void repeat(int n, delegate void(int i) dg)
> {
>     foreach(int i; 0..n)
>         dg(i);
> }
> repeat(5, void delegate(int i) { writefln("hi"); });
> 
> // D ////////////////////////
> void repeat(int n, void delegate(int i) dg)
> {
>     foreach(int i; 0..n)
>         dg(i);
> }
> repeat(5, delegate void(int i) { writefln("hi"); });
> 

Also keep in mind that to increase confusion, D still supports the old style 
C syntax for functions. It's true that when you make a distinction between 
delegates, functions, nested functions and lambdas, all kinds of 
inconsistencies may crop up. For example the above example is much simpler 
in Scala (but of course scalac doesn't produce efficient native code):

def foo(i: Int) = println("hi")

class c {
  def bar(i: Int) = println("hi")
}

object obj extends c

def scope = {
  def lambda = { i: Int => println("hi") }
  
  def repeat(n: Int, dg: Int => Unit) = 0.to(n-1).foreach { dg (_) }

  repeat(5, foo)
  repeat(5, obj.bar)
  repeat(5, (new c).bar)
  repeat(5, lambda)
  repeat(5, { i: Int => println("hi") })
}

As you can see, whatever you try to do, the type system cleanly stays out of 
the way.




More information about the Digitalmars-d mailing list