* Define in let
@ 2013-08-20 16:39 Dmitry Bogatov
2013-08-20 16:57 ` Thompson, David
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Dmitry Bogatov @ 2013-08-20 16:39 UTC (permalink / raw)
To: guile-user
[-- Attachment #1: Type: text/plain, Size: 536 bytes --]
It seems following is invalid:
(let ((a 2))
(define (foo x) (+ a x)))
I prefer to reduce scope of variable as much as possible, so
I find this restriction unconvinent. Is is part of standard or technical
limitation? Is it any workaround?
Please, keep in CC, I am not subscribed.
--
Best regards, Dmitry Bogatov <KAction@gnu.org>,
Free Software supporter and netiquette guardian.
git clone git://kaction.name/rc-files.git --depth 1
GPG: 54B7F00D
Html mail and proprietary format attachments are forwarded to /dev/null.
[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
@ 2013-08-20 16:57 ` Thompson, David
2013-08-20 17:02 ` Taylan Ulrich B.
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Thompson, David @ 2013-08-20 16:57 UTC (permalink / raw)
To: Dmitry Bogatov; +Cc: Guile User
[-- Attachment #1: Type: text/plain, Size: 863 bytes --]
On Tue, Aug 20, 2013 at 12:39 PM, Dmitry Bogatov <KAction@gnu.org> wrote:
>
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
> I prefer to reduce scope of variable as much as possible, so
> I find this restriction unconvinent. Is is part of standard or technical
> limitation? Is it any workaround?
>
The problem is that you have an invalid `let` form. You need an expression
besides `define`.
Something like this would be valid:
(let ((a 2))
(define (foo x) (+ a x))
(foo 4))
>
> Please, keep in CC, I am not subscribed.
>
> --
> Best regards, Dmitry Bogatov <KAction@gnu.org>,
> Free Software supporter and netiquette guardian.
> git clone git://kaction.name/rc-files.git --depth 1
> GPG: 54B7F00D
> Html mail and proprietary format attachments are forwarded to /dev/null.
>
- Dave Thompson
[-- Attachment #2: Type: text/html, Size: 1559 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
2013-08-20 16:57 ` Thompson, David
@ 2013-08-20 17:02 ` Taylan Ulrich B.
2013-08-20 17:18 ` John B. Brodie
` (3 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Taylan Ulrich B. @ 2013-08-20 17:02 UTC (permalink / raw)
To: Dmitry Bogatov; +Cc: guile-user
Dmitry Bogatov <KAction@gnu.org> writes:
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
> I prefer to reduce scope of variable as much as possible, so
> I find this restriction unconvinent. Is is part of standard or technical
> limitation? Is it any workaround?
>
> Please, keep in CC, I am not subscribed.
>
> --
> Best regards, Dmitry Bogatov <KAction@gnu.org>,
> Free Software supporter and netiquette guardian.
> git clone git://kaction.name/rc-files.git --depth 1
> GPG: 54B7F00D
> Html mail and proprietary format attachments are forwarded to /dev/null.
No Scheme standard so far has supported such a thing, and neither Guile.
It would be neat, I had the idea too (it would allow re-use of the
semantics of `begin' and thus be coherent/orthogonal in a way), but I
think it's a non-trivial change, probably both to the implementation of
Guile and the semantics for `let' that have been well-understood ever
since very old Lisps: that `let' is a thin wrapper around a call to an
in-place `lambda'.
(let ((a x)
(b y))
...)
is just
((lambda (a b)
...)
x y)
in pretty much any Lisp.
Note that you can do
(define foo
(let ((a 2))
(lambda (x) (+ a x))))
and if you want to define multiple things that use that `a' binding, you
could use `define-values', but Guile doesn't have that yet (there's a
hacky in-Scheme definition in R7RS-small if you want something quick):
(define-values (foo bar)
(let ((a 2))
(values
(lambda (x) (+ a x))
(lambda (y) (* a y)))))
Taylan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
2013-08-20 16:57 ` Thompson, David
2013-08-20 17:02 ` Taylan Ulrich B.
@ 2013-08-20 17:18 ` John B. Brodie
2013-08-20 17:19 ` Ian Price
` (2 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: John B. Brodie @ 2013-08-20 17:18 UTC (permalink / raw)
To: Dmitry Bogatov; +Cc: guile-user
On 08/20/2013 12:39 PM, Dmitry Bogatov wrote:
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
> I prefer to reduce scope of variable as much as possible, so
> I find this restriction unconvinent. Is is part of standard or technical
> limitation? Is it any workaround?
use a lambda form rather than a define:
(letrec ((a 2)
(foo (lambda (x) (+ a x))))
(foo 3))
>
> Please, keep in CC, I am not subscribed.
>
> --
> Best regards, Dmitry Bogatov <KAction@gnu.org>,
> Free Software supporter and netiquette guardian.
> git clone git://kaction.name/rc-files.git --depth 1
> GPG: 54B7F00D
> Html mail and proprietary format attachments are forwarded to /dev/null.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
` (2 preceding siblings ...)
2013-08-20 17:18 ` John B. Brodie
@ 2013-08-20 17:19 ` Ian Price
2013-08-20 17:52 ` Mike Gran
2013-08-20 21:01 ` David Pirotte
5 siblings, 0 replies; 14+ messages in thread
From: Ian Price @ 2013-08-20 17:19 UTC (permalink / raw)
To: Dmitry Bogatov; +Cc: guile-user
Dmitry Bogatov <KAction@gnu.org> writes:
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
> I prefer to reduce scope of variable as much as possible, so
> I find this restriction unconvinent. Is is part of standard or technical
> limitation? Is it any workaround?
It's not a limitation, but a misunderstanding. Define creates a binding
in the _current_ scope, not the top level one.
--
Ian Price -- shift-reset.com
"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
` (3 preceding siblings ...)
2013-08-20 17:19 ` Ian Price
@ 2013-08-20 17:52 ` Mike Gran
2013-08-20 21:01 ` David Pirotte
5 siblings, 0 replies; 14+ messages in thread
From: Mike Gran @ 2013-08-20 17:52 UTC (permalink / raw)
To: Dmitry Bogatov, guile-user@gnu.org
> From: Dmitry Bogatov <KAction@gnu.org>
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
Perhaps something like
(let* ((a 2)
(foo (lambda (x) (+ a x))))
(foo
-Mike
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 16:39 Define in let Dmitry Bogatov
` (4 preceding siblings ...)
2013-08-20 17:52 ` Mike Gran
@ 2013-08-20 21:01 ` David Pirotte
2013-08-21 6:52 ` Panicz Maciej Godek
2013-08-21 15:42 ` Dmitry Bogatov
5 siblings, 2 replies; 14+ messages in thread
From: David Pirotte @ 2013-08-20 21:01 UTC (permalink / raw)
To: Dmitry Bogatov; +Cc: guile-user
Hello,
> It seems following is invalid:
>
> (let ((a 2))
> (define (foo x) (+ a x)))
>
> I prefer to reduce scope of variable as much as possible, so
> I find this restriction unconvinent. Is is part of standard or technical
> limitation? Is it any workaround?
Section '3.4.7 Example 2: A Shared Persistent Variable' is probably what you want?
Cheers,
David
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 21:01 ` David Pirotte
@ 2013-08-21 6:52 ` Panicz Maciej Godek
2013-08-21 6:55 ` Panicz Maciej Godek
2013-08-21 9:28 ` Ralf Mattes
2013-08-21 15:42 ` Dmitry Bogatov
1 sibling, 2 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2013-08-21 6:52 UTC (permalink / raw)
To: David Pirotte; +Cc: guile-user@gnu.org, Dmitry Bogatov
[-- Attachment #1: Type: text/plain, Size: 1971 bytes --]
2013/8/20 David Pirotte <david@altosw.be>
> Hello,
>
> > It seems following is invalid:
> >
> > (let ((a 2))
> > (define (foo x) (+ a x)))
> >
> > I prefer to reduce scope of variable as much as possible, so
> > I find this restriction unconvinent. Is is part of standard or technical
> > limitation? Is it any workaround?
>
The Scheme's idiomatic way to achieve the effect that you
probably want would be
(define foo #f)
(let ((a 2))
(set! foo (lambda (x) (+ a x))))
Although it allows to achieve the desired effect, it doesn't
express the programmer's intention quite clearly.
If you're interested, I recently wrote a macro that would
allow to get the same in a IMHO slightly more elegant way, i.e.
(publish
(define (foo x) (+ a x))
where
(define a 2))
The macro's definition (procedural) follows.
Regards.
=============================
(define-macro (publish . definitions)
(define (interface-name interface)
(match interface
((head . tail)
(interface-name head))
((? symbol? name)
name)))
(let-values (((public-definitions where&private-definitions)
(split-before (equals? 'where) definitions)))
`(begin ,@(map (match-lambda
((define-variant interface . body)
`(define ,(interface-name interface) #f)))
public-definitions)
(let ()
,@(match where&private-definitions
(('where . private-definitions)
private-definitions)
(() '()))
,@(map (match-lambda
((define-variant interface . body)
(let ((name (interface-name interface)))
`(set! ,name
(let ()
(,define-variant ,interface . ,body)
,name)))))
public-definitions)))))
[-- Attachment #2: Type: text/html, Size: 2967 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-21 6:52 ` Panicz Maciej Godek
@ 2013-08-21 6:55 ` Panicz Maciej Godek
2013-08-21 9:28 ` Ralf Mattes
1 sibling, 0 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2013-08-21 6:55 UTC (permalink / raw)
To: David Pirotte; +Cc: guile-user@gnu.org, Dmitry Bogatov
[-- Attachment #1: Type: text/plain, Size: 330 bytes --]
Sorry, the macro definition relies on a few additional functions,
in particular on the (ice-9 match) and (srfi srfi-1) modules and
the following definitions:
(define (split-before criterion list)
(split-at list (or (list-index criterion list)
(length list))))
(define (equals? x) (lambda(y)(equal? x y)))
[-- Attachment #2: Type: text/html, Size: 469 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-21 6:52 ` Panicz Maciej Godek
2013-08-21 6:55 ` Panicz Maciej Godek
@ 2013-08-21 9:28 ` Ralf Mattes
2013-08-21 10:17 ` Panicz Maciej Godek
1 sibling, 1 reply; 14+ messages in thread
From: Ralf Mattes @ 2013-08-21 9:28 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user@gnu.org, Dmitry Bogatov, David Pirotte
On Wed, Aug 21, 2013 at 08:52:02AM +0200, Panicz Maciej Godek wrote:
> 2013/8/20 David Pirotte <david@altosw.be>
>
> > Hello,
> >
> > > It seems following is invalid:
> > >
> > > (let ((a 2))
> > > (define (foo x) (+ a x)))
> > >
> > > I prefer to reduce scope of variable as much as possible, so
> > > I find this restriction unconvinent. Is is part of standard or technical
> > > limitation? Is it any workaround?
> >
>
> The Scheme's idiomatic way to achieve the effect that you
> probably want would be
> (define foo #f)
> (let ((a 2))
> (set! foo (lambda (x) (+ a x))))
I'd say this is extremly contorted and non-schemish.
What's wrong with:
(define foo
(let ((a 2))
(lambda (arg) (+ a arg))))
This is the basic let-over-lambda closure ....
Cheers, Ralf Mattes
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-21 9:28 ` Ralf Mattes
@ 2013-08-21 10:17 ` Panicz Maciej Godek
2013-08-21 10:32 ` Ralf Mattes
0 siblings, 1 reply; 14+ messages in thread
From: Panicz Maciej Godek @ 2013-08-21 10:17 UTC (permalink / raw)
To: Ralf Mattes; +Cc: guile-user@gnu.org, Dmitry Bogatov, David Pirotte
[-- Attachment #1: Type: text/plain, Size: 2172 bytes --]
2013/8/21 Ralf Mattes <rm@seid-online.de>
> On Wed, Aug 21, 2013 at 08:52:02AM +0200, Panicz Maciej Godek wrote:
> > 2013/8/20 David Pirotte <david@altosw.be>
> >
> > > Hello,
> > >
> > > > It seems following is invalid:
> > > >
> > > > (let ((a 2))
> > > > (define (foo x) (+ a x)))
> > > >
> > > > I prefer to reduce scope of variable as much as possible, so
> > > > I find this restriction unconvinent. Is is part of standard or
> technical
> > > > limitation? Is it any workaround?
> > >
> >
> > The Scheme's idiomatic way to achieve the effect that you
> > probably want would be
> > (define foo #f)
> > (let ((a 2))
> > (set! foo (lambda (x) (+ a x))))
>
> I'd say this is extremly contorted and non-schemish.
> What's wrong with:
>
> (define foo
> (let ((a 2))
> (lambda (arg) (+ a arg))))
>
> This is the basic let-over-lambda closure ....
>
>
You're right, but it only works if you want to export only one symbol
from a lexical scope. If you wanted a few procedures accessing
a single scope, you'd either need to use the solution with 'set!',
or -- as Taylan suggested -- have a "define-values" form.
Actually, I think should also be possible to write a "define-values"
macro using the method I presented
(define-macro (define-values symbols . body)
(let ((value-identifiers (map gensym (map symbol->string symbols))))
`(begin
,@(map (lambda(x)`(define ,x #f)) symbols)
(let-values ((,value-identifiers ,@body))
,@(map (lambda(symbol value)`(set! ,symbol ,value))
symbols
value-identifiers)))))
So we can say that guile already has that ;]
I don't know however how to write this using define-syntax, the
idea is to transform
(define-values (symbol1 symbol2 ...) body ...)
into
(begin
(define symbol1 #f)
(define symbol2 #f)
...
(let-values (((value1 value2 ...) (begin body ...))
(set! symbol1 value1)
(set! symbol2 value2)
...)
but somehow we need to generate identifiers for symbol1 symbol2 ...
(here I wrote symbolically value1 value2 ..., but I'd appreciate if someone
more competent could provide a syntax-rules-based solution)
regards
[-- Attachment #2: Type: text/html, Size: 3368 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-21 10:17 ` Panicz Maciej Godek
@ 2013-08-21 10:32 ` Ralf Mattes
2013-08-21 11:01 ` Panicz Maciej Godek
0 siblings, 1 reply; 14+ messages in thread
From: Ralf Mattes @ 2013-08-21 10:32 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user@gnu.org
On Wed, Aug 21, 2013 at 12:17:43PM +0200, Panicz Maciej Godek wrote:
> You're right, but it only works if you want to export only one symbol
> from a lexical scope. If you wanted a few procedures accessing
> a single scope, you'd either need to use the solution with 'set!',
> or -- as Taylan suggested -- have a "define-values" form.
Yes, but was that the OP's question?
> Actually, I think should also be possible to write a "define-values"
> macro using the method I presented
[... snip ...]
> but somehow we need to generate identifiers for symbol1 symbol2 ...
> (here I wrote symbolically value1 value2 ..., but I'd appreciate if someone
> more competent could provide a syntax-rules-based solution)
Maybe it's time to point out that this question is in the Scheme-FAQ ;-)
[http://community.schemewiki.org/?scheme-faq-language] - Section
"Is there a way to define top-level closures?" (sorry, bad webdesign,
no wa to link directlyto the topic). The answer not only mentions
'define-values but also links to an implementation:
[http://community.schemewiki.org/?scheme-faq-macros#multidefine]
that uses 'syntax-rules
HTH RalfD
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-21 10:32 ` Ralf Mattes
@ 2013-08-21 11:01 ` Panicz Maciej Godek
0 siblings, 0 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2013-08-21 11:01 UTC (permalink / raw)
To: Ralf Mattes; +Cc: guile-user@gnu.org
[-- Attachment #1: Type: text/plain, Size: 1449 bytes --]
2013/8/21 Ralf Mattes <rm@seid-online.de>
> On Wed, Aug 21, 2013 at 12:17:43PM +0200, Panicz Maciej Godek wrote:
> > You're right, but it only works if you want to export only one symbol
> > from a lexical scope. If you wanted a few procedures accessing
> > a single scope, you'd either need to use the solution with 'set!',
> > or -- as Taylan suggested -- have a "define-values" form.
>
> Yes, but was that the OP's question?
>
>
Well, if the question is "to reduce scope of variable as much as possible",
then I think that the issue of defining multiple procedures within the same
scope is a part of that question, even if it wasn't posited directly
> > Actually, I think should also be possible to write a "define-values"
> > macro using the method I presented
> [... snip ...]
> > but somehow we need to generate identifiers for symbol1 symbol2 ...
> > (here I wrote symbolically value1 value2 ..., but I'd appreciate if
> someone
> > more competent could provide a syntax-rules-based solution)
>
> Maybe it's time to point out that this question is in the Scheme-FAQ ;-)
> [http://community.schemewiki.org/?scheme-faq-language] - Section
> "Is there a way to define top-level closures?" (sorry, bad webdesign,
> no wa to link directlyto the topic). The answer not only mentions
> 'define-values but also links to an implementation:
> [http://community.schemewiki.org/?scheme-faq-macros#multidefine]
> that uses 'syntax-rules
>
> Thanks! :)
[-- Attachment #2: Type: text/html, Size: 2738 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Define in let
2013-08-20 21:01 ` David Pirotte
2013-08-21 6:52 ` Panicz Maciej Godek
@ 2013-08-21 15:42 ` Dmitry Bogatov
1 sibling, 0 replies; 14+ messages in thread
From: Dmitry Bogatov @ 2013-08-21 15:42 UTC (permalink / raw)
To: David Pirotte; +Cc: guile-user
[-- Attachment #1: Type: text/plain, Size: 797 bytes --]
>> It seems following is invalid:
>>
>> (let ((a 2))
>> (define (foo x) (+ a x)))
>>
>> I prefer to reduce scope of variable as much as possible, so
>> I find this restriction unconvinent. Is is part of standard or technical
>> limitation? Is it any workaround?
>
> Section '3.4.7 Example 2: A Shared Persistent Variable' is probably what you want?
Yes, although it is a bit too verbose.
(define (foo x)
(let ((a 2))
(+ a x0)))
is enough for my puroses, although solution about define-values seems
intresting. Thanks all!
--
Best regards, Dmitry Bogatov <KAction@gnu.org>,
Free Software supporter and netiquette guardian.
git clone git://kaction.name/rc-files.git --depth 1
GPG: 54B7F00D
Html mail and proprietary format attachments are forwarded to /dev/null.
[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-08-21 15:42 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-20 16:39 Define in let Dmitry Bogatov
2013-08-20 16:57 ` Thompson, David
2013-08-20 17:02 ` Taylan Ulrich B.
2013-08-20 17:18 ` John B. Brodie
2013-08-20 17:19 ` Ian Price
2013-08-20 17:52 ` Mike Gran
2013-08-20 21:01 ` David Pirotte
2013-08-21 6:52 ` Panicz Maciej Godek
2013-08-21 6:55 ` Panicz Maciej Godek
2013-08-21 9:28 ` Ralf Mattes
2013-08-21 10:17 ` Panicz Maciej Godek
2013-08-21 10:32 ` Ralf Mattes
2013-08-21 11:01 ` Panicz Maciej Godek
2013-08-21 15:42 ` Dmitry Bogatov
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).