[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: What's so cool about Scheme?
Mike Newhall wrote:
> At 12:18 AM 2003.06.04 -0400, Anton van Straaten wrote:
> >This is what I've been arguing against. I don't see how
> code=data without closures leads to funarg problems, unless
> the language already has a funarg problem.
> If you have code=data, and no proper closures, and you want
> some higher-order functionality, you will be forced to pass code
> as data as functional arguments. A natural thing to want to do
> is to reference a local variable in that functional argument
> external to that functional argument. The only way to do that is
> to capture the environment at the location the functional
> argument is defined, and a closure does that. It seems to me
> then that if you naively start out with a language that has only
> code=data (like old LISP), you will at some point want to extend
> that language with closures to fix this problem (as Scheme did).
> I don't see why this is such a controversial point.
It's partly been a terminology issue. I think I understand you better now.
Old LISP didn't work the way you seem to be describing. In original LISP,
there was a LAMBDA construct which when evaluated, created a first-class
function which could be stored in variables, passed to and from functions,
etc. This, as I mentioned early on, is not what's usually referred to as
"code=data". This is a higher order function, which can be created as part
of the normal evaluation of a program, without the programmer explicitly
So early LISP had higher order functions, and that's why it suffered from
funarg problems. When one of these higher order functions is created,
variable binding can take place, before the function is ever executed.
These bindings can break if the function is subsequently executed in the
wrong context. IOW, old Lisp had funarg problems because it had higher
order functions without implementing closures correctly.
So this needs to be rewritten:
> It seems to me then that if you naively start out with a language
> that has only code=data (like old LISP), you will at some point
> want to extend that language with closures to fix this problem
> (as Scheme did).
...as something like: "if you naively start out with a language that has
higher-order functions but a broken closure implementation (like old LISP),
you will at some point want to fix the closure implementation". This still
has nothing to do with code=data.
You could rephrase the above-quoted paragraph to say something about how
with only code=data and eval, you might want a more powerful facility that
allows you to create something more closure-like. That's fine, but (a) it
doesn't follow in quite the same way as it did in the old Lisp case, where
there were actual bugs in the language that needed to be addressed, and (b)
it has little to do with funarg problems by the usual definition: with eval,
there's no distinct binding stage prior to execution, as there is when a
true higher order function is created, so there's no situation in which a
binding created in one context breaks in another, i.e. funarg problems don't