You could do it the same way python does it: have `def` be a macro that inspects its body for assignments to symbols, and then let-bind them at the top of the function. On Wed, 22 Sep 2021, 6:45 pm Damien Mattei, wrote: > Hi Taylan, > > i have used Module System Reflection, and it works almost for what i > wanted to do,the only big problem is that it creates variable binding > global, seen from every where and that breaks my example code, by the way i > will display for everybody an example of use of such a macro,so everyone > can understand the Scheme extension i want to do. I try to extend the > language, so i'm in a way construncting code from outside but not > completely, you can consider yes if you consider macro is a way to > construct code from outside in the way it expand in a new code from > another... hash table is not solution,too complex, need a global > variable... it try to make thing as simple as possible to keep speed > expansion and code up,so do not use recursive macro expansion,for now > things are fast. > > Here is a partial solving probleme solution with Module System Reflection > but i hope to be able to create local lexical scoping variable not only > global ones,because instead i will have to use 2 different assignment > operators (one replacing define and one replacing set!) and want things as > simple as possible and Scheme-like but Python in a function creates only > variables global to the function,i can include an option to do that too in > Scheme+ . > > So here is the assignment operator and an example code explaining its > caveats: > > *Preview:* > > (define-syntax <- > (syntax-rules () > ((_ var expr) (let* ((modul (current-module)) > (exist-var (module-variable modul (quote var)))) > (if exist-var > (module-set! modul (quote var) expr) > (module-define! modul (quote var) expr)))))) > > > notice that the <- operator defined above has been removed of the > arrays,vectors,etc support for readability, here i focus only on "simple" > scheme variable ,arrays,vectors is working great already. > > *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 > > > note that condx (conditionnal with pre execution) is just a cond allowing > to execute code before testin next condition and so on... > > here how it "compiles" in Guile Scheme+: > > scheme@(guile-user)> (load "SssDyna.scm") > ;;; note: source file > /home/mattei/Dropbox/git/library-FunctProg/SssDyna.scm > ;;; newer than compiled > /home/mattei/.cache/guile/ccache/3.0-LE-8-4.2/home/mattei/Dropbox/git/library-FunctProg/SssDyna.scm.go > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > ;;; or pass the --no-auto-compile argument to disable. > ;;; compiling /home/mattei/Dropbox/git/library-FunctProg/SssDyna.scm > ;;; SssDyna.scm:73:8: warning: possibly unbound variable `array-ref-set!' > ;;; SssDyna.scm:192:28: warning: possibly unbound variable `ยง' > ;;; SssDyna.scm:400:2: warning: possibly unbound variable `dyn' > ;;; SssDyna.scm:408:10: warning: possibly unbound variable `dyn' > ;;; SssDyna.scm:408:21: warning: possibly unbound variable `dyn' > ;;; SssDyna.scm:411:15: warning: possibly unbound variable `c' > ;;; SssDyna.scm:413:10: warning: possibly unbound variable `c' > ;;; SssDyna.scm:415:15: warning: possibly unbound variable `R' > ;;; SssDyna.scm:417:10: warning: possibly unbound variable `c' > ;;; SssDyna.scm:417:24: warning: possibly unbound variable `R' > ;;; SssDyna.scm:417:24: warning: possibly unbound variable `R' > ;;; SssDyna.scm:417:18: warning: possibly unbound variable `s' > ;;; SssDyna.scm:418:33: warning: possibly unbound variable `s' > ;;; SssDyna.scm:408:2: warning: possibly unbound variable `s' > ;;; SssDyna.scm:423:22: warning: possibly unbound variable `R' > ;;; SssDyna.scm:423:42: warning: possibly unbound variable `c' > ;;; SssDyna.scm:423:54: warning: possibly unbound variable `R' > ;;; SssDyna.scm:423:22: warning: possibly unbound variable `R' > ;;; SssDyna.scm:423:42: warning: possibly unbound variable `c' > ;;; SssDyna.scm:423:54: warning: possibly unbound variable `R' > ;;; SssDyna.scm:423:15: warning: possibly unbound variable `s' > ;;; SssDyna.scm:424:30: warning: possibly unbound variable `s' > ;;; SssDyna.scm:408:2: warning: possibly unbound variable `s' > ;;; compiled > /home/mattei/.cache/guile/ccache/3.0-LE-8-4.2/home/mattei/Dropbox/git/library-FunctProg/SssDyna.scm.go > > it compiles well, you will notice that variables seems unbound to compiler > because they are created *dynamically* by the macro of <- operator but > that is not a problem. > > They create well but they create globally. > > i ran the test code example like this: > (define L-init '(1 3 4 16 17 24 45 64 197 256 275 323 540 723 889 915 1040 > 1041 1093 1099 1111 1284 1344 1520 2027 2500 2734 3000 3267 3610 4285 5027)) > > (define t-init 35267) > > (define ls (length L-init)) > > (define dyna (make-array 0 {ls + 1} {t-init + 1})) > > (define (one-two b) > (if b 1 2)) > it search if exist a solution to the subset sum problem on the list L-init > with sum being 35267, > there exist such a solution so the return answer must be #t. > > with global definitions the return value is wrong (#f) because variables > are created globallly. > the problem is in those lines: > [exec {R <- (rest L)}] > will assign (rest L) to R, but R is a global variable! ,R must be local to > function, it is worse than Python because <- create toplevel variables !!!, > and then when i execute: > [else {s <- {(subset-sum-guile R {t - c}) or (subset-sum-guile R t)}} > the first clause of or run well: (subset-sum-guile R {t - c}) > but modify R as it is not a local variable and then the second clause of > or: (subset-sum-guile R t) return wrong result because it is called with R > containing a bad value: > (subset-sum-guile L-init t-init) > #f > scheme@(guile-user)> R > () > R exist now at top-level !!! > > the solution to make the code run well in this case was just to create a > local variables,using another assignment operator <+ that add a local > variable in local lexical scope the way define do it: > [exec {R <- (rest L)}] is equivalent to [exec (define R (rest L))] > and then the code succeed again and return #t value. > > So i want now to have by default a lexical scope for <- and new variables > to be local to the nested block ,not global, even not local to function (as > in Python) even if in this particuliar example code would have run well > with local scoping. (but note that if <- is called on an already existing > variable of a different scope,upper or global,or top-level, i want ot be > able to set! it) > I want to be able to control the scoping of variables so i can make this > assignment operator the way i want,and also propose different assignment > operators with different variable scope. > > Damien > > > On Sun, Sep 19, 2021 at 11:39 PM Taylan Kammer > wrote: > >> On 19.09.2021 09:54, Damien Mattei wrote: >> > hello, >> > i'm developing an extension to Scheme >> > and i need a procedure or macro that define a variable only if it is >> not bind and if it is just set! it. >> > >> > I can not do it in Guile or any Scheme,and i'm desperately searching a >> way to do that. I finally conclude that it can be done only by adding it in >> the language. >> > >> > Can someone include a such function in Guile next release? >> > i know guile have a predicate defined? to test binfing of a vairable >> but writing a macro with it is not possible because define can be used in >> an expression context. >> > >> > Thank in advance for any help >> > Damien >> >> What is the utility of such a function? Since Scheme is lexically scoped, >> it's generally obvious whether a variable has already been defined or not, >> rendering such an operation useless. >> >> If you're constructing code from outside input so that you don't know >> whether a provided variable name represents a variable that's already been >> defined or not, then you could use the module reflection API: >> >> >> https://www.gnu.org/software/guile/manual/html_node/Module-System-Reflection.html >> >> Sounds like 'module-define!' does exactly what you ask for. I wonder what >> exactly your use-case is though. Chances are that your use-case is best >> served with a simple data structure like a hash table... >> >> -- >> Taylan >> >