Lambda vs. function

Waldemar Horwat waldemar at google.com
Fri Oct 17 12:39:52 PDT 2008


Dave Herman wrote:
>> What is your point?  To write a recursive factorial I'd write either:
>>
>> lambda f(x) {
>> if (x == 0)
>>   1;
>> else
>>   f(x - 1);
>> }
>>
>> or:
>>
>> function f(x) {
>> if (x == 0)
>>   return 1;
>> else
>>   return f(x - 1);
>> }
> 
> Right, good, so far we're on the same page.
> 
>> Either one is subject to having to jump out of try-catch blocks if you 
>> have them.  You still have all the same issues of whether f is in the 
>> tail position or not.
> 
> Yes and no. Try-catch does need to be kept in the continuation 
> regardless of whether we're talking about a tail-recursive 
> function/return form or a tail-recursive lambda form. But the point is 
> that, if you want function/return to be properly tail-calling, then in 
> these two functions:
> 
>     function f() {
>         try {
>             if (test())
>                 return g();
>         }
>         catch (e) { }
>     }
> 
>     function f() {
>         if (test())
>             return g();
>     }
> 
> return has different behavior. In the first one, you first evaluate g() 
> and then return. In the second one, you first return and then evaluate 
> g(). By contrast, if you write these in lambda-style, you get:
> 
>     lambda f() {
>         try {
>             if (test())
>                 g()
>         }
>         catch (e) { }
>     }
> 
>     lambda f() {
>         if (test())
>             g()
>     }
> 
> Now there's no question about any control effect.

Again, what is your point?  The first function f behaves the same way as the first lambda f, so what is the advantage you're claiming for lambda?  What you appear to be saying is that wrapping the call to g() inside another statement indicates that it will not be tail-recursive.  In that case what will things like the following do?

lambda h(x) {
  switch (x) {
    case 1:
      g();
      break;
    case 2:
      ...
  }
}

lambda k(x) {
  with (x) {
    g();
  }
}

lambda i(x) {
  if (x) {
    g();
  } else {
    ...
  }
}

lambda l():type1 {
  g(); // Produces type2
}

All of these wrap the call to g in another statement.

    Waldemar


More information about the Es-discuss mailing list