guile-devel
[Top][All Lists]
Advanced

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

Re: new function


From: Maxime Devos
Subject: Re: new function
Date: Thu, 23 Sep 2021 20:00:15 +0200
User-agent: Evolution 3.34.2

Damien Mattei schreef op do 23-09-2021 om 19:27 [+0200]:
> yes i know parsing the whole code is the only portable solution, but it is 
> slow,even on a few dozen of lines the slowing is visible ,so i can even think 
> of that on one thousand lines...
> 
> I finally succeed in Guile with simple piece of code to make my example run 
> with a single assignment operator <-  , here i define for variable the 
> assignment operator <$ , <- is working with arrays too:
> 
> Preview:
> 
> (define-syntax <$
>   
>   (lambda (s)
>     
>     (syntax-case s ()
>       
>       ((_ var value)
>        
>        (case (syntax-local-binding #'var)
>        
>          ((lexical) #'(begin
>                       (display "<$ : lexical scope : ")
>                       (display (quote var))
>                       (newline)
>                       (set! var value)))
>        
>        ((displaced-lexical) #'(begin
>                                 (display "<$ : displaced-lexical scope : ")
>                                 (display (quote var))
>                                 (newline)
>                                 (set! var value)))
>        
>          ((global) #'(begin
>                      (display "<$ : global scope : ")
>                      (display (quote var))
>                      (newline)
>                      (define var value)))
>        
>          (else #'(begin
>                  (display "<$ : unknow variable scope :")
>                  (display (quote var))
>                  (error "<$ : unknow variable scope : "))))))))
> 
> 
> it allows this Scheme+ code to run with a single assignment operator (note in 
> some case the operator is also a definition of variable,but it is invisible 
> for the programmer, it has the duality of define and set!):
> 
> Preview:
> 
> (define (subset-sum-guile L t)
> 
>   {ls <- (length L)}
>   {dyn <- dyna[ls t]}
> 
> ;; dyna[ls][t] means 0: unknown solution, 1: solution found, 2: no solution
>   
>   (condx [{dyn <> 0} (one? dyn)]
>        [(null? L) {dyna[ls t] <- 2}  #f] ;; return #f
>        
>        [exec {c <- (first L)}]         
>        ;; c is the solution
>        [{c = t} {dyna[ls t] <- 1}  #t]  ;; return #t
>        
>        [exec {R <- (rest L)}]  
>        ;; continue searching a solution in the rest
>        [{c > t} {s <- (subset-sum-guile R t)}
>                 {dyna[ls t] <- (one-two s)}
>                 s] ;; return boolean value
>                       
>        ;; else : c < t at this point
>        ;; c is part of a solution OR not part of a solution
>        [else {s <- {(subset-sum-guile R {t - c}) or (subset-sum-guile R t)}}
>              {dyna[ls t] <- (one-two s)}
>              s])) ;; return boolean value
> 
>      
> 
> some people were sceptic about the possibility to make it, but it works, i do 
> not say it is portable code.
> 
> When i run the program with debug i see that:
> scheme@(guile-user)> (subset-sum-guile  L-init t-init)
> <$ : global scope : ls
> <$ : global scope : dyn
>  
> <$ : global scope : c
> <$ : global scope : R
> <$ : global scope : s
> <$ : global scope : ls
> <$ : global scope : dyn
>  
> <$ : global scope : c
> .... hundreds of lines.....
> #t
> 
> all variable are global,

No, they are local, even though syntax-local-binding returns 'global'.
'syntax-local-binding' doesn't know we will be defining a local variable
with the same name later, so it says 'global' instead of 'lexical' or
'displaced-lexical'.

There is no such thing as ‘global to the body of the function’, what you are
descrbing is local variables.

The macro <$ you have defined won't work for the "hello world" example I sent
you:

(define (#{hello/won't-work}# language)
  (cond ((equal? language "dutch")
         (<$ message "Hallo wereld"))
        ((equal? language "english")
         (<$ message "Hello world")))
  (display message)
  (newline))
While compiling expression:
Syntax error:
unknown file:70:9: definition in expression context, where definitions are not 
allowed, in form (define message "Hallo wereld")

The following does, however:

(define (hello language)
  (<$ message #f)
  (cond ((equal? language "dutch")
         (<$ message "Hallo wereld"))
        ((equal? language "english")
         (<$ message "Hello world")))
  (display message)
  (newline))

Possibly this limitation of <$ is acceptable to you though.

> but they are just global to the body of the function,not at toplevel,so there 
> is no risk of breaking the code logic it is just that if we want to see 
> lexical scope we need a more nested example,it is strange because i thought 
> that the condx macro creates nestled code for each conditional clauses...
> 
> to see the lexical scope we can use this example:
> scheme@(guile-user)> 
> (condx [exec {k <- 1}]
>     [{k = 1} {k <- {k + 1}} {k + 1}]
>     [else 'never])
> <$ : global scope : k
> <$ : lexical scope : k
> $3 = 3
> here the lexical scope is well visible :-)
> but if k had existed at toplevel it is not modified :-( :
> scheme@(guile-user)> (define k 0)
> scheme@(guile-user)> 
> (condx [exec {k <- 1}]
>            [{k = 1} {k <- {k + 1}} {k + 1}]
>            [else 'never])
> <$ : global scope : k
> <$ : lexical scope : k
> $4 = 3
> scheme@(guile-user)> k
> $5 = 0
> 
> :-(
>  probably beause syntax-local-binding only works in the current lexical 
> environment ?
> https://www.gnu.org/software/guile/docs/master/guile.html/Syntax-Transformer-Helpers.html
> but not at toplevel ???
> Scheme Procedure: syntax-local-binding id [#:resolve-syntax-parameters?=#t]
> Resolve the identifer id, a syntax object, within the current lexical 
> environment
> 
> for this reason i still searching a solution that would be a mix of 
> syntax-local-binding and Module System Reflection .

Use the second return value of syntax-local-binding.
Or just use set! instead of <$ and <- to modify global variables,
and use <- and <$ for local variables only.

Greetings,
Maxime.

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

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