unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Damien Mattei <damien.mattei@gmail.com>
To: Taylan Kammer <taylan.kammer@gmail.com>
Cc: Jean-Paul Roy <jean-paul.roy@unice.fr>, guile-devel@gnu.org
Subject: Re: new function
Date: Wed, 22 Sep 2021 10:44:48 +0200	[thread overview]
Message-ID: <CADEOaddrFV-yQdObQ5QPsKCiXnvzVp1gzLq10oCUGR3nG2zH1A@mail.gmail.com> (raw)
In-Reply-To: <147c2fb4-75d6-7cf6-4f4a-4edd996b0a4a@gmail.com>

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

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

  parent reply	other threads:[~2021-09-22  8:44 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 [this message]
2021-09-22  9:06     ` William ML Leslie
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=CADEOaddrFV-yQdObQ5QPsKCiXnvzVp1gzLq10oCUGR3nG2zH1A@mail.gmail.com \
    --to=damien.mattei@gmail.com \
    --cc=guile-devel@gnu.org \
    --cc=jean-paul.roy@unice.fr \
    --cc=taylan.kammer@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).