unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Placement of defines
@ 2008-12-18 17:00 Sebastian Tennant
  0 siblings, 0 replies; 7+ messages in thread
From: Sebastian Tennant @ 2008-12-18 17:00 UTC (permalink / raw)
  To: guile-user

Hi all,

Having read this interesting thread:

 http://sourceware.org/ml/guile/1999-08/msg00118.html

I understand that internal definitions may not occur anywhere other than
at the beginning of the body of the enclosing expression, which explains
why this works:

 ((lambda (x) (define bar x) (display bar)) "foo\n")

while this doesn't:

 ((lambda (x) (set! x "baz\n") (define bar x) (display bar)) "foo\n")

Firstly, perhaps this could/should be mentioned in the manual?

(info "(guile) Internal Definitions") currently reads:

"A `define' form which appears inside the body of a `lambda', `let',
 `let*', `letrec' or equivalent expression is called an "internal
 definition"."

May I suggest this reads:

"`Define' forms may only appear at the beginning of the body of a
 `lambda', `let', `let*', `letrec' or equivalent expression, and when
 they do they constitute what are known as "internal definitions"."

or words to that effect.

Secondly, there is some talk in the above-mentioned thread of an
extension to R5RS Scheme that allows define forms to occur anywhere
within the body of the enclosing expression, making for much more
readable code.

The thread is approx 8.5 years old now, and I was just wondering why the
extension never made it into Guile, the readable code argument being a
pretty compelling one IMHO.

Sebastian





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
       [not found] <cmu-lmtpd-18264-1229620135-1@mail-imap1.uio.no>
@ 2008-12-18 17:31 ` Kjetil S. Matheussen
  2008-12-18 18:47   ` Sebastian Tennant
  0 siblings, 1 reply; 7+ messages in thread
From: Kjetil S. Matheussen @ 2008-12-18 17:31 UTC (permalink / raw)
  To: guile-user


Sebastian Tennant:
>
> Hi all,
>
> Having read this interesting thread:
>
> http://sourceware.org/ml/guile/1999-08/msg00118.html
>
> I understand that internal definitions may not occur anywhere other than
> at the beginning of the body of the enclosing expression, which explains
> why this works:
>
> ((lambda (x) (define bar x) (display bar)) "foo\n")
>
> while this doesn't:
>
> ((lambda (x) (set! x "baz\n") (define bar x) (display bar)) "foo\n")
>
> Firstly, perhaps this could/should be mentioned in the manual?
>
> (info "(guile) Internal Definitions") currently reads:
>
> "A `define' form which appears inside the body of a `lambda', `let',
> `let*', `letrec' or equivalent expression is called an "internal
> definition"."
>
> May I suggest this reads:
>
> "`Define' forms may only appear at the beginning of the body of a
> `lambda', `let', `let*', `letrec' or equivalent expression, and when
> they do they constitute what are known as "internal definitions"."
>
> or words to that effect.
>

That's definitely an improvement!



> Secondly, there is some talk in the above-mentioned thread of an
> extension to R5RS Scheme that allows define forms to occur anywhere
> within the body of the enclosing expression, making for much more
> readable code.
>
> The thread is approx 8.5 years old now, and I was just wondering why the
> extension never made it into Guile, the readable code argument being a
> pretty compelling one IMHO.
>

Yes, this limitation in Scheme is a horrible pest. There's no
decent reason why you shouldn't be allowed to use define other
places than right after a lambda, except the long discussion
involved how it should behave in various situations. But even
inconsistant behaviour between implementations would be better
than the current situation where you either have to rewrite
perfectly fine expressions or use various types of lets or
lambdas in more or less ridiculous ways:

- ((lambda (x) (set! x "baz\n") (define bar x) (display bar)) "foo\n")
+ ((lambda (x) (set! x "baz\n") (let () (define bar x) (display bar) "foo\n"))




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
  2008-12-18 17:31 ` Kjetil S. Matheussen
@ 2008-12-18 18:47   ` Sebastian Tennant
  2008-12-18 20:57     ` Ludovic Courtès
  0 siblings, 1 reply; 7+ messages in thread
From: Sebastian Tennant @ 2008-12-18 18:47 UTC (permalink / raw)
  To: guile-user

Quoth "Kjetil S. Matheussen" <k.s.matheussen@notam02.no>:
> Yes, this limitation in Scheme is a horrible pest. There's no
> decent reason why you shouldn't be allowed to use define other
> places than right after a lambda, except the long discussion
> involved how it should behave in various situations. But even
> inconsistant behaviour between implementations would be better
> than the current situation where you either have to rewrite
> perfectly fine expressions or use various types of lets or
> lambdas in more or less ridiculous ways:
>
> - ((lambda (x) (set! x "baz\n") (define bar x) (display bar)) "foo\n")
> + ((lambda (x) (set! x "baz\n") (let () (define bar x) (display bar) "foo\n"))

Your 'let' workaround gave me an idea.

I use this macro to bind lots of variables dynamically within my
scripts by wrapping calls to it in a map procedure:

 (define-macro (definer var val)                  ;var must be a symbol
   `(module-define! (current-module) ,var ,val))

and it happens to work fine as a workaround for the restriction on
define placements in lambdas and lets :)

 guile> ((lambda (x) (set! x "baz\n") (definer 'bar x) (display bar)) "foo\n")
 baz
 guile> 

It (the macro) won't work properly if you need/want to compile your
scheme code though.

If that's the case you should use this macro instead:

 (define-macro (definer var val)                  ;var must be a string
   `(define ,(string->symbol var) ,val))

I prefer the former macro definition because I don't need to compile my
code and

 (definer "foo" "bar")

seems somehow uglier and less intuitive than:

 (definer 'foo "bar")

to me.

Incidentally, perhaps you can tell me why the first argument to this
compile-friendly macro has to be a string for it to work.

 guile> (define-macro (definer var val)
          `(define ,var ,val))
 guile> (definer 'foo "bar")

appears to have worked, but...

 guile> foo
 ERROR: Unbound variable: foo
 ABORT: (unbound-variable)

it hasn't.

Sebastian





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
  2008-12-18 18:47   ` Sebastian Tennant
@ 2008-12-18 20:57     ` Ludovic Courtès
  2008-12-19 11:18       ` Sebastian Tennant
  0 siblings, 1 reply; 7+ messages in thread
From: Ludovic Courtès @ 2008-12-18 20:57 UTC (permalink / raw)
  To: guile-user

Sebastian Tennant <sebyte@smolny.plus.com> writes:

> Incidentally, perhaps you can tell me why the first argument to this
> compile-friendly macro has to be a string for it to work.
>
>  guile> (define-macro (definer var val)
>           `(define ,var ,val))
>  guile> (definer 'foo "bar")
>
> appears to have worked, but...
>
>  guile> foo
>  ERROR: Unbound variable: foo
>  ABORT: (unbound-variable)

Try this:

  (definer foo "bar")

Thanks,
Ludo'.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
  2008-12-18 20:57     ` Ludovic Courtès
@ 2008-12-19 11:18       ` Sebastian Tennant
  0 siblings, 0 replies; 7+ messages in thread
From: Sebastian Tennant @ 2008-12-19 11:18 UTC (permalink / raw)
  To: guile-user

Quoth ludo@gnu.org (Ludovic Courtès):
> Sebastian Tennant <sebyte@smolny.plus.com> writes:
>
>> Incidentally, perhaps you can tell me why the first argument to this
>> compile-friendly macro has to be a string for it to work.
>>
>>  guile> (define-macro (definer var val)
>>           `(define ,var ,val))
>>  guile> (definer 'foo "bar")
>>
>> appears to have worked, but...
>>
>>  guile> foo
>>  ERROR: Unbound variable: foo
>>  ABORT: (unbound-variable)
>
> Try this:
>
>   (definer foo "bar")

Yes it works.

Damn.

After much experimenting and head scratching...

Question: When is a variable not a variable?

  Answer: When it's about to become the name of a variable.

:)

Seb





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
       [not found] <cmu-lmtpd-21674-1229672512-0@mail-imap1.uio.no>
@ 2008-12-19 17:10 ` Kjetil S. Matheussen
  2008-12-27 15:19   ` Sebastian Tennant
  0 siblings, 1 reply; 7+ messages in thread
From: Kjetil S. Matheussen @ 2008-12-19 17:10 UTC (permalink / raw)
  To: guile-user


Sebastian Tennant:
>
> Quoth "Kjetil S. Matheussen" <k.s.matheussen@notam02.no>:
>> Yes, this limitation in Scheme is a horrible pest. There's no
>> decent reason why you shouldn't be allowed to use define other
>> places than right after a lambda, except the long discussion
>> involved how it should behave in various situations. But even
>> inconsistant behaviour between implementations would be better
>> than the current situation where you either have to rewrite
>> perfectly fine expressions or use various types of lets or
>> lambdas in more or less ridiculous ways:
>>
>> - ((lambda (x) (set! x "baz\n") (define bar x) (display bar)) "foo\n")
>> + ((lambda (x) (set! x "baz\n") (let () (define bar x) (display bar) "foo\n"))
>
> Your 'let' workaround gave me an idea.
>
> I use this macro to bind lots of variables dynamically within my
> scripts by wrapping calls to it in a map procedure:
>
> (define-macro (definer var val)                  ;var must be a symbol
>   `(module-define! (current-module) ,var ,val))
>
> and it happens to work fine as a workaround for the restriction on
> define placements in lambdas and lets :)
>
> guile> ((lambda (x) (set! x "baz\n") (definer 'bar x) (display bar)) "foo\n")
> baz
> guile>
>

Unfortunately, it's not the same. "definer" defines a global variable:

guile> bar
"baz
"





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Placement of defines
  2008-12-19 17:10 ` Kjetil S. Matheussen
@ 2008-12-27 15:19   ` Sebastian Tennant
  0 siblings, 0 replies; 7+ messages in thread
From: Sebastian Tennant @ 2008-12-27 15:19 UTC (permalink / raw)
  To: guile-user

Quoth "Kjetil S. Matheussen" <k.s.matheussen@notam02.no>:
>> Sebastian Tennant:
>> guile> ((lambda (x) (set! x "baz\n") (definer 'bar x) (display bar)) "foo\n")
>> baz
>> guile>
>>
>
> Unfortunately, it's not the same. "definer" defines a global variable:
>
> guile> bar
> "baz
> "

Good point.  That hadn't occurred to me.  Thanks.

Seb





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-12-27 15:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-18 17:00 Placement of defines Sebastian Tennant
     [not found] <cmu-lmtpd-18264-1229620135-1@mail-imap1.uio.no>
2008-12-18 17:31 ` Kjetil S. Matheussen
2008-12-18 18:47   ` Sebastian Tennant
2008-12-18 20:57     ` Ludovic Courtès
2008-12-19 11:18       ` Sebastian Tennant
     [not found] <cmu-lmtpd-21674-1229672512-0@mail-imap1.uio.no>
2008-12-19 17:10 ` Kjetil S. Matheussen
2008-12-27 15:19   ` Sebastian Tennant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).