unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Damien Mattei <damien.mattei@gmail.com>
To: William ML Leslie <william.leslie.ttg@gmail.com>
Cc: Jean-Paul Roy <jean-paul.roy@unice.fr>,
	guile-devel <guile-devel@gnu.org>
Subject: Re: new function
Date: Wed, 22 Sep 2021 11:53:59 +0200	[thread overview]
Message-ID: <CADEOadeqRmNxq3zNt2Lbj5f3Fk6_gnUq_wtey7pBg9NC3cMcYA@mail.gmail.com> (raw)
In-Reply-To: <CAHgd1hHn8m2-YGkKYqB-ZcCQL7AxwsTg=BmM0NM+TwH4GdRbRA@mail.gmail.com>

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

i already do it this way for internal defines ,using a recursive macro that
build a list of variable using an accumulator. It can works but macro
expansion seems slow, it was not immediate at compilation on a little
example (oh nothing more that 2 seconds) but i'm not sure it is easily
maintainable, it is at the limit what macro can do i think ,for speed
reasons. In fact i can not really understand in Guile as it is based on C
and compiled when macro expansion happens,what is the time cost... so for
all those ,perhaps not objective reason ,i prefer to avoid.

On Wed, Sep 22, 2021 at 11:06 AM William ML Leslie <
william.leslie.ttg@gmail.com> wrote:

> 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: 24082 bytes --]

  reply	other threads:[~2021-09-22  9:53 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
2021-09-22  9:53       ` Damien Mattei [this message]
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=CADEOadeqRmNxq3zNt2Lbj5f3Fk6_gnUq_wtey7pBg9NC3cMcYA@mail.gmail.com \
    --to=damien.mattei@gmail.com \
    --cc=guile-devel@gnu.org \
    --cc=jean-paul.roy@unice.fr \
    --cc=william.leslie.ttg@gmail.com \
    /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).