Re: Define in let
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)))
Re: Define in let
2013/8/20 David Pirotte > 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)
Re: Define in let
On Wed, Aug 21, 2013 at 08:52:02AM +0200, Panicz Maciej Godek wrote: > 2013/8/20 David Pirotte > > > 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
Re: Define in let
2013/8/21 Ralf Mattes > On Wed, Aug 21, 2013 at 08:52:02AM +0200, Panicz Maciej Godek wrote: > > 2013/8/20 David Pirotte > > > > > 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
Re: Define in let
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
Re: Define in let
2013/8/21 Ralf Mattes > 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! :)
Re: Define in let
>> 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 , 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. pgpvUD2foKato.pgp Description: PGP signature