Re: Define in let

2013-08-21 Thread Panicz Maciej Godek
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-08-21 Thread Panicz Maciej Godek
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

2013-08-21 Thread 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 

Cheers, Ralf Mattes




Re: Define in let

2013-08-21 Thread Panicz Maciej Godek
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

2013-08-21 Thread 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?

> 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-08-21 Thread Panicz Maciej Godek
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

2013-08-21 Thread Dmitry Bogatov

>> 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