guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: definition in expression context, where definitions are not allowed


From: Taylan Ulrich Bayırlı/Kammer
Subject: Re: definition in expression context, where definitions are not allowed
Date: Sun, 11 Oct 2015 12:03:57 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Arne Babenhauserheide <address@hidden> writes:

>     (define (hello who)
>       (display "Hello ")
>       (define (world who)
>         (display who))
>       (world who)
>       (display "!")
>       (newline))

Let's look at a different example first, which works with the current
semantics:

  (let ()
    (define (odd? n) (if (zero? n) #f (even? (- n 1))))
    (define (even? n) (if (zero? n) #t (odd? (- n 2))))
    (even? 42))

That works because the internal definitions become 'letrec*' so they may
refer to each other, i.e. 'odd?' can refer to 'even?' in its body,
before 'even?' is really defined.

If your example also worked, than with the combination of the above,
users might ultimately also expect this to work:

  (let ()
    (define (hello)
      (display "Hello ")
      (world)
      (display "!")
      (newline))
    (display "Goodbye Eden, ")
    (define (world)
      (display "World"))
    (hello))

Just like in the top-level.  But that would require making the whole
procedure body a big 'letrec*' expression.  If I'm not mistaken that's
exactly what JavaScript does, called "var hoisting," where all variables
declared anywhere in a function become bound to a special 'undefined'
value at the beginning of the function, and these don't behave exactly
as undefined variables either.  In Guile too, variables "bound but not
defined yet" as created by 'letrec*' aren't checked for invalid access
because it would put overhead on every variable reference.  So that
would end up giving us those weird semantics as known from JS.

(IIRC, "strict mode" JS only allows variable declarations at the
beginning of a function body, just like internal defines in Scheme.)

Or maybe my example was a bit contrived, and/or we can teach users that
they should "group together" definitions that refer to each other, and
have those groups turn into nested 'letrec*' expressions (similar to
your proposal, just using 'letrec*' when there's multiple adjacent
'define' forms).  But that makes things more and more complicated, and
by the time we taught users that we could have probably just taught them
the simpler rule that internal 'define' forms may only appear at the
beginning of a body.

Does that make sense?

Taylan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]