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.
signature.asc
Description: This is a digitally signed message part