Re: [dssslist] in reply to: "define inside let body"

Subject: Re: [dssslist] in reply to: "define inside let body"
From: tmcd@xxxxxxxxx
Date: Wed, 9 Feb 2005 13:00:34 -0600 (CST)
> >Hi, I am trying to understand the dsssl standard document
> >(ISO/IEC 10179:1996(E). Trying to put this example to work with
> >openjade, part 8.4 "Definitions" of the document, at top level:
> >
> >(define p
> >   (let ((x 5))
> >     (define foo (lambda (y) (bar x y)))
> >     (define bar (lambda (a b) (+ (* a b) a)))
> >     (foo (+ x 3)))
> >)
>
> Hi,
> I'am rather inexperienced but I'll try to answer.
> The former should look like:

The example above is right out of the DSSSL spec, page 43.  I don't
have a net connection right now, btu I suspect that Googling for
"dsssl96b.pdf" would find it.  Look for "dsssl96f.pdf" too: it's the
table of contents.

> (define p
>    (let ((x 5)
>      (foo (lambda (y) (bar x y)))
>      (bar (lambda (a b) (+ (* a b) a))))
>      (foo (+ x 3)))
> )
>
> It won't work anyway because of recursive definitions, but now at
> least it should be accepted by jade.

See "NOTE 9" quoted below.  I'm not sure that it won't work, but I
haven't tried it.  In any event, "letrec", which was mentioned as the
equivalent expansion, makes it work.

> >According the standard. body is described (in the same page) as
> >
> > [69] body=definition* expression
>
> In your code you repeat expression part 3 times, so it is not very
> correct.

The BNF listed on pages 42 and 43 are

    [66] definition = variable-definition | procedure-definition

    Definitions may take two possible forms.

    [67] variable-definition = (define variable expression)

    This syntax is primitive.

    [68] procedure-definition = (define (variable formal-argument-list) body)

    This form is equivalent to

    (define variable
        (lambda (variable formal-argument-list) body)).

    A definition that does not occur within an expression is known as
    a top-level definition.

    A top-level definition

    (define variable expression)

    evaluates expression in the top-level environment and binds
    variable to the result in the top-level environment.

    The expression in a top-level definition shall not be evaluated
    until all top-level variables that would be referenced by
    evaluating the expression have been defined.

    NOTE 9 This constraint does not prevent the definition of mutually
    recursive procedures, because evaluating a lambda expression does
    not reference variables that occur free within it.

    It shall be an error if it is impossible to evaluate all the
    expressions occurring in top-level definitions in such a way that
    this constraint is not violated. ...

    [69] body = definition* expression

    Definitions may also occur at the beginning of a body. These are
    known as internal definitions. The variable defined by an internal
    definition is local to the body. The region of the binding is the
    entire body. For example,

        (let ((x 5))
            (define foo (lambda (y) (bar x y)))
            (define bar (lambda (a b) (+ (* a b) a)))
            (foo (+ x 3)))          =>   45

So in that example, "definition" is repeated 2 times:

    1: (define foo (lambda (y) (bar x y)))
    2: (define bar (lambda (a b) (+ (* a b) a)))

and expression appears once:

     (foo (+ x 3)))

It's a bit of a pity that OpenJade doesn't allow it: I could have
gotten rid of a few "let" blocks that way.  If it allowed definitions
before any _expression_ (extending the standard), a LOT of "let"
blocks would go away.  Still, it's easy enough to work around.

-- 
Tim McDaniel; Reply-To: tmcd@xxxxxxxxx

Current Thread