[comp.lang.scheme] data structures <--> functions

johnson@mimsy.UUCP (Greg Johnson) (12/02/87)

Summary:

Expires:

References:

Sender:

Followup-To:

Distribution:

Keywords:



In Lisp(s), one is able to build a list whose `car' is the atom `lambda',
and then apply this object as a function to arguments:

(setq add2 '(lambda (x) (+ 2 x)))
(lambda (x) (+ 2 x))

(add2 45)
47

Scheme seems to lack this property.  So does ML.  In short, the pun that
exists in classic lisps between data structures and functions seems to have
been abandoned.  Unless you write an interpreter subroutine, you cannot have
a program build a data structure and then use it as an executable function.

Is there some `sanctioned' way that a data structure that `looks' like a
lambda abstraction can be turned into a closure?  I tried opening a file for
writing, writing the object out, closing the file, opening it for reading,
and reading the object in using various read primitives, but that didn't
work.

The C Scheme interpreter I have (release 4.1.1) has an undocumented function
named `eval' (surprise!) that appears to take two arguments, an object
to be interpreted and an environment relative to which the interpretation
should take place.  By reading Scheme source code, functions to create
and manipulate environments can be found.

A more general question, for those well imbued in the Lisp culture:  how
much of a loss is it (or rather, `would it be' if there is in fact some
sanctioned, clean, efficient way to do the above) not to have a mechanism
for lisp programs to build their own functions?

- Greg Johnson
  johnson@mimsy.umd.edu

JAR@AI.AI.MIT.EDU (Jonathan A Rees) (12/03/87)

    Date: 2 Dec 87 19:14:11 GMT
    From: johnson at mimsy.umd.edu (Greg Johnson)

    I tried opening a file for writing, writing the object out, closing
    the file, opening it for reading, and reading the object in using
    various read primitives, but that didn't work.

Try something like

    (define evaluate
      (lambda (expression)
        (call-with-output-file "temp"
          (lambda (port)
	    (write `(define temp ,expression) port)))
	(load "temp")
	temp))

if you can manage to do so without making yourself ill.

jeem@utai.UUCP (12/04/87)

In article <9597@mimsy.UUCP>, Greg Johnson asks how much of a loss would it be
to not have a mechanism for a lisp program to build a data structure and then
use it as an executable function?

An analogous question: How much of a loss would it be if all of a standard
stored-program computer's instructions had to reside in read-only memory?

The answer in both cases is that, while the vast majority of programmers would
not be directly inconvenienced by the lack of meta-level facilities , it would
be absolutely crippling to the system programmers that have to supply the
editors, compilers, linkers, and debuggers for that system.

JAR@AI.AI.MIT.EDU (Jonathan A Rees) (12/05/87)

    Date: Sat, 5 Dec 87 14:06:59 +0100
    From: Oliver Laumann <net%TUB.BITNET at MITVMA.MIT.EDU>
    To:   scheme-request at mc.lcs.mit.edu

    In Scheme you can easily achieve this by first evaluating the list and then
    applying the result (a procedure) to the argument 45.  Try the following:

	 (define add2 '(lambda (x) (+ 2 x)))
	 ((eval add2 (the-environment)) 45)            -->  47

There is some disagreement here over what exactly "Scheme" means.  The
Revised^3 Report has no EVAL procedure, and no (THE-ENVIRONMENT) special
form, but most Scheme implementations, apparently including the one
you're referring to, do have some kind of EVAL.

There were several reasons for excluding EVAL from the report, including
  (a) there is no general agreement among Scheme designers as to what
      environment EVAL should evaluate expressions with respect to, or
      whether EVAL should take an explicit environment object as an
      argument;
  (b) it is not clear how to give a formal semantics to EVAL;
  (c) EVAL interacts poorly with selective linking.
On the other hand, EVAL is undeniably useful in particular special
situations.  (Most of the time that one would be tempted to use EVAL in
ancient Lisps, procedures or ad-hoc interpreters will serve in Scheme.)
EVAL will probably continue to be supported as an unofficial extension in
most implementations for the foreseeable future, and it will probably
continue to not be standardized for a while.  The same is true of
macros.  This is what happens when a standard is created by a committee.