From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Damien Mattei Newsgroups: gmane.lisp.guile.devel Subject: Re: new function Date: Wed, 22 Sep 2021 10:44:48 +0200 Message-ID: References: <147c2fb4-75d6-7cf6-4f4a-4edd996b0a4a@gmail.com> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000089ce8c05cc918709" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7459"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Jean-Paul Roy , guile-devel@gnu.org To: Taylan Kammer Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Wed Sep 22 10:45:38 2021 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mSxsn-0001gi-Lx for guile-devel@m.gmane-mx.org; Wed, 22 Sep 2021 10:45:37 +0200 Original-Received: from localhost ([::1]:42228 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mSxsl-0008Dt-DB for guile-devel@m.gmane-mx.org; Wed, 22 Sep 2021 04:45:35 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:55820) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSxsG-0008Dk-4X for guile-devel@gnu.org; Wed, 22 Sep 2021 04:45:04 -0400 Original-Received: from mail-il1-x134.google.com ([2607:f8b0:4864:20::134]:46865) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mSxsD-000438-7u for guile-devel@gnu.org; Wed, 22 Sep 2021 04:45:03 -0400 Original-Received: by mail-il1-x134.google.com with SMTP id h20so1854820ilj.13 for ; Wed, 22 Sep 2021 01:45:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Ns6QNRS0sxEiqvvAgezz7akSptow2OKgvf6B85Bbk8o=; b=nRhf25I8sFEBTGR5pU04PAGRsmmbPnlbxFYGrAVFz51G1AlUxH/qCjaAP2NuzKCOkr cysDlgDfcdJyRqZKFHDeZYVT7XBEzijSO0ID8g2BqzH/WmGa7C8cXuA2Dl2suh1BS/dy Mdo0ZOAnIR8EXafdNHY+NGsPa08VJBp8VXnSEM3suvj8iIVeuZx//qrhy4YVaFlYDxrb z0EmTqbyEsbyrxqLZ0laeztqjAduTSTZ40SbNbJ6wKLWFZKopBtUUqAIAc7oCjm2heqj qYtuaAQrIarVVvGW9cwVRPrXTu1l0pYF6125p+GyrQEII1Ee6ysIB4UHN9wMpyM4Yzy7 uWqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Ns6QNRS0sxEiqvvAgezz7akSptow2OKgvf6B85Bbk8o=; b=G/GGyEl319wAy/awX/EaY+MvxZEP/StSBwvUXf68CPjNFv1M4BUaK3Oa68O1y13qNh HHxi6Ip0dqQJgwyro/fl+T1Ww3qCZliaRlL7q2RQbn15Fof25EyYS1P5iQ8g1F9qad4B DOdJ0M1tvGVos9dM2cM01Q0lDFOF83U5MJaIELvquLHqLnGtcFsdlDpPAZV5wNSAad++ 5ZW4khG93ndab2eV2yOW6HpuwiFahKB1yrzhfGgVY0IO6ak1IKZfHRcdtOJE85Mm8PR/ QcgXGf14I3faMsQApeCaInux4SmcfFDa584F6u9wg2F3xGwlHumJtY6Y3G+YvLRM0wV3 M4nA== X-Gm-Message-State: AOAM533pnxU7vNPB4WbxFS9hiA8k2Op2NB7GQCrb7w5wMmVpse1s4+dW E6v92LpojCAP+01BVUkEfxpE7IKlrj+Mvo8AiEwzpyXuBHA= X-Google-Smtp-Source: ABdhPJxXg8zI+DcO5Tr1Igqp34Hb+zp6phRYhleEZqjimoTVH9iOv/SA6EXQgbsNV7vWyC++5ncZXzMyrkgMwkRgZWE= X-Received: by 2002:a05:6e02:48d:: with SMTP id b13mr24675346ils.171.1632300299831; Wed, 22 Sep 2021 01:44:59 -0700 (PDT) In-Reply-To: <147c2fb4-75d6-7cf6-4f4a-4edd996b0a4a@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::134; envelope-from=damien.mattei@gmail.com; helo=mail-il1-x134.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_FONT_LOW_CONTRAST=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.io gmane.lisp.guile.devel:20873 Archived-At: --00000000000089ce8c05cc918709 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 soluti= on (condx [{dyn <> 0} (one? dyn)] [(null? L) {dyna[ls t] <- 2} #f] ;; return #f =09 [exec {c <- (first L)}]=09 ;; c is the solution [{c =3D t} {dyna[ls t] <- 1} #t] ;; return #t =09 [exec {R <- (rest L)}]=09 ;; 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 =09 ;; 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.sc= m ;;; newer than compiled /home/mattei/.cache/guile/ccache/3.0-LE-8-4.2/home/mattei/Dropbox/git/libra= ry-FunctProg/SssDyna.scm.go ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=3D0 ;;; 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 `=C2=A7' ;;; 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/libra= ry-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 no= t > 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 bu= t > 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 bee= n > defined or not, then you could use the module reflection API: > > > https://www.gnu.org/software/guile/manual/html_node/Module-System-Reflect= ion.html > > Sounds like 'module-define!' does exactly what you ask for. I wonder wha= t > 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 > --00000000000089ce8c05cc918709 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
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, see= n from every where and that breaks my example code, by the way i will displ= ay for everybody an example of use of such a macro,so everyone can understa= nd the Scheme extension i want to do. I try to extend the language, so i= 9;m in a way construncting code from outside but not completely, you can co= nsider 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 p= ossible to keep speed expansion and code up,so do not use recursive macro e= xpansion,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 assignm= ent operators (one replacing define and one replacing set!) and want things= as simple as possible and Scheme-like but Python in a function creates onl= y variables global to the function,i can include an option to do that too i= n Scheme+ .
So here is th= e assignment operator and an example code explaining its caveats:

Preview:

=20
(define-syntax <-
  (syntax-rules ()
    ((_ var expr) (let* ((modul (current-=
module))
			 (exist-var (mo=
dule-variable modul (quote =
var))))
		    (if exist-var
			(module-set! modul (quote var) expr)
			(module-define! modul (<=
span style=3D"color:rgb(251,102,10);font-weight:bold">quote var) expr))))))
=20
=


notice that the <- operator defi= ned above has been removed of the arrays,vectors,etc support for readabilit= y, here i focus only on "simple" scheme variable ,arrays,vectors = is working great already.

Preview= :

=20
(define (subset-sum-guile L =
t)

  {ls <- (length L)}
  {dyn <- <=
span style=3D"color:rgb(251,102,10)">dyna[ls t]}
 =20
  ;; dyna[ls][t] means 0: unknown solution, 1: solution found, 2: =
no solution
 =20
  (condx [{dyn <> 0} (one? dyn)]
	 [(null? L) =
{dyna[ls t] <- 2}  #f] ;; return #f
	=20
	 [exec {c <- (first L)}]	=20
	 ;; c is the solution
	 [{c =3D t} {dyna[ls t] <- 1}  #t]  ;; return #t
	=20
	 [exec {R <- (rest L)}]	=20
	 ;; continue searching a solution in the rest
	 [{c > t} {s &=
lt;- (subset-sum-guile R t=
)}
	          {dyna[ls t] <- (on=
e-two s)}
		  s] ;; return boolean value
		=09
	 ;; else : c < t at this point
	 ;; c is part of a solution OR not part of a solution
	 [else {s <- =
{(subset-sum-g=
uile R {t - c}) or (subset-sum-guile R<=
/span> t)}}
	       {dyna[ls t] <- (one-t=
wo s)}
	       s])) ;; return boolean value
=20

= note that condx (conditionnal with pre execution) is just a cond allowing t= o execute code before testin next condition and so on...

here how it "compiles" in Guile Scheme+:

scheme@(guile-user)> (load &quo= t;SssDyna.scm")
;;; note: source file /home/mattei/Dropbox/git/libr= ary-FunctProg/SssDyna.scm
;;; =C2=A0 =C2=A0 =C2=A0 newer than compiled /= home/mattei/.cache/guile/ccache/3.0-LE-8-4.2/home/mattei/Dropbox/git/librar= y-FunctProg/SssDyna.scm.go
;;; note: auto-compilation is enabled, set GU= ILE_AUTO_COMPILE=3D0
;;; =C2=A0 =C2=A0 =C2=A0 or pass the --no-auto-comp= ile argument to disable.
;;; compiling /home/mattei/Dropbox/git/library-= FunctProg/SssDyna.scm
;;; SssDyna.scm:73:8: warning: possibly unbound va= riable `array-ref-set!'
;;; SssDyna.scm:192:28: warning: possibly un= bound variable `=C2=A7'
;;; SssDyna.scm:400:2: warning: possibly unb= ound variable `dyn'
;;; SssDyna.scm:408:10: warning: possibly unboun= d variable `dyn'
;;; SssDyna.scm:408:21: warning: possibly unbound v= ariable `dyn'
;;; SssDyna.scm:411:15: warning: possibly unbound vari= able `c'
;;; SssDyna.scm:413:10: warning: possibly unbound variable = `c'
;;; SssDyna.scm:415:15: warning: possibly unbound variable `R= 9;
;;; 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'
;;; SssDy= na.scm:417:18: warning: possibly unbound variable `s'
;;; SssDyna.sc= m:418:33: warning: possibly unbound variable `s'
;;; SssDyna.scm:408= :2: warning: possibly unbound variable `s'
;;; SssDyna.scm:423:22: w= arning: possibly unbound variable `R'
;;; SssDyna.scm:423:42: warnin= g: possibly unbound variable `c'
;;; SssDyna.scm:423:54: warning: po= ssibly unbound variable `R'
;;; SssDyna.scm:423:22: warning: possibl= y unbound variable `R'
;;; SssDyna.scm:423:42: warning: possibly unb= ound variable `c'
;;; SssDyna.scm:423:54: warning: possibly unbound = variable `R'
;;; SssDyna.scm:423:15: warning: possibly unbound varia= ble `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 compil= er because they are created dynamically by the macro=C2=A0 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 111= 1 1284 1344 1520 2027 2500 2734 3000 3267 3610 4285 5027))

(define t= -init 35267)

(define ls (length L-init))

(define dyna (make-a= rray 0 {ls + 1} {t-init + 1}))

(define (one-two b)
=C2=A0 (if b 1= 2))
it search if exist a solution to the subs= et 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 gl= obal variable! ,R must be local to function, it is worse than Python becaus= e <- create toplevel variables !!!, and then when i execute:
[else {s <- {(subset-su= m-guile R {t - c}) or (subset-sum-guile R t)}}
the first clause of or run well: (subset-su= m-guile R {t - c})
but modify R as it is not a local variable and then the second clause o= f or: (subset-sum-guile R t) return wrong result because it is called with = R containing a bad value:
(subset-sum-guile =C2=A0L-init t-init)
#f
scheme@(guile-user)> R
()
R exist now at top-level !!!

the solution to make the c= ode run well in this case was just to create a local variables,using anothe= r assignment operator <+ that add a local variable in local lexical scop= e the way define do it:
[exec {R <- (rest L)}] is equivalent to [exec (define R (rest L= ))]
and then th= e 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 w= ould 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-l= evel, i want ot be able to set! it)
I want to be able to control the scoping of variab= les 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 Matte= i wrote:
> hello,
> i'm developing an extension to Scheme
> and i need a procedure or macro that define a variable only if it is n= ot bind and if it is just set! it.
>
> I can not do it in Guile or any Scheme,and i'm desperately searchi= ng 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 b= ut 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?=C2=A0 Since Scheme is lexically sco= ped,
it's generally obvious whether a variable has already been defined or n= ot,
rendering such an operation useless.

If you're constructing code from outside input so that you don't kn= ow
whether a provided variable name represents a variable that's already b= een
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.=C2=A0 I= wonder what
exactly your use-case is though.=C2=A0 Chances are that your use-case is be= st
served with a simple data structure like a hash table...

--
Taylan
--00000000000089ce8c05cc918709--