unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: William ML Leslie <william.leslie.ttg@gmail.com>
To: Damien Mattei <damien.mattei@gmail.com>
Cc: guile-devel <guile-devel@gnu.org>
Subject: Re: new function
Date: Wed, 22 Sep 2021 19:06:01 +1000	[thread overview]
Message-ID: <CAHgd1hHn8m2-YGkKYqB-ZcCQL7AxwsTg=BmM0NM+TwH4GdRbRA@mail.gmail.com> (raw)
In-Reply-To: <CADEOaddrFV-yQdObQ5QPsKCiXnvzVp1gzLq10oCUGR3nG2zH1A@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 9380 bytes --]

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, <damien.mattei@gmail.com> 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 <taylan.kammer@gmail.com>
> 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
>>
>

[-- Attachment #2: Type: text/html, Size: 22984 bytes --]

  reply	other threads:[~2021-09-22  9:06 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-19  7:54 new function Damien Mattei
2021-09-19 14:41 ` Matt Wette
2021-09-19 14:43   ` Matt Wette
2021-09-19 21:38 ` Taylan Kammer
2021-09-21 12:26   ` Damien Mattei
2021-09-22  8:44   ` Damien Mattei
2021-09-22  9:06     ` William ML Leslie [this message]
2021-09-22  9:53       ` Damien Mattei
2021-09-22 18:51         ` Taylan Kammer
2021-09-22 21:52           ` William ML Leslie
2021-09-23  8:40             ` Damien Mattei
2021-09-23 19:03             ` Taylan Kammer
2021-09-23 17:27           ` Damien Mattei
2021-09-23 18:00             ` Maxime Devos
2021-09-23 20:27             ` Taylan Kammer
2021-09-23 20:42               ` Damien Mattei
2021-09-23 20:48               ` Taylan Kammer
2021-09-23 21:53                 ` Damien Mattei
2021-09-24  4:41                   ` Damien Mattei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHgd1hHn8m2-YGkKYqB-ZcCQL7AxwsTg=BmM0NM+TwH4GdRbRA@mail.gmail.com' \
    --to=william.leslie.ttg@gmail.com \
    --cc=damien.mattei@gmail.com \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).