better lambda support in the future?

Dima Dorfman dima at trit.invalid
Fri Dec 17 21:53:04 EST 2004


On 2004-12-18, Jeff Shannon <jeff at ccvcorp.com> wrote:
> Would OCaml (or some 
> other static language) have something that's equivalent to this?
>
> def f(x):
>     if x < 0:
>         def g(y):
>             return y * -1
>     else:
>         def g(y):
>             return y
>     return g
>
> foo = f(1)

Sure. You can't change a binding, but you can make it conditional:

  let f x =
    if x < 0
    then let g y = y * -1 in g
    else let g y = y in g

Idiomatic OCaml code would use a lambda (fun y -> y * -1), but it
doesn't have to, and that would just confuse the issue.

> I suppose it might be able to do something by compiling both of them, 
> (though I'm not sure how it'd track two different functions with the 
> same name in the same namespace...) but that seems a bit questionable to 
> me...

Both languages compile all three functions (f and the two versions of
g) once and choose which g to return at run-time. You can see this in
Python by examining the code object for f:

  >>> f.func_code.co_consts
  (None, 0, <code object g at 1c8120, file "<stdin>", line 3>,
   <code object g at 1cd1a0, file "<stdin>", line 6>)

The last two elements are the variants of g. At run-time, one of them
is loaded, made into a real function, and returned. All defs and
lambdas are compiled only once when the module is loaded even if they
depend on the environment or are referenced dynamically.

You can do this even in C (untested):

  typedef int fun(int);
  int g1(int y) { return y * -1; }
  int g2(int y) { return y; }
  fun *f(int x)
  {
      return x < 0 ? g1 : g2;
  }

C doesn't have language support for closures, though, so we end up
manually passing around (fun, arg) if we need free variables, but
there's nothing inherently dynamic about higher-order functions.



More information about the Python-list mailing list