Re: Fwd: new function

2021-09-22 Thread Damien Mattei
i do not understand well what you want to mean with those example.
For me  define-once does not seems to be a solution, it act as define too
much ,does not set! variable if already exist and can not use to set it
again because, as define it is forbidden twice in the same block for the
same variable:

scheme@(guile-user)> (define (foo3)
  (define-once  x 1)
  (if #t
  (let ()
(define-once x 2)
;;(set! x 2)
(display "x=")
(display x)
(newline)
(define-once x 3)
;;(set! x 2)
(display "x=")
(display x)
(newline)

)
  'never)
  (display x)
  (newline))
While compiling expression:
Syntax error:
unknown file:51:6: invalid or duplicate identifier in definition in form
(let () (define-once x 2) (display "x=") (display x) (newline) (define-once
x 3) (display "x=") (display x) (newline))

i will try (use-modules (system syntax)) that yesterday seems to give
better results

On Tue, Sep 21, 2021 at 9:03 PM Maxime Devos  wrote:

> Damien Mattei schreef op di 21-09-2021 om 15:04 [+0200]:
> > i have tested define-once
> > http://www.gnu.org/software/guile/docs/master/guile.html/Top-Level.html
> > (the defvar of Lisp)and idea are:
> > -unfortunately it is considered by scheme as a define,so there is some
> > context where it is not allowed in my code
> > -seems to work fine at toplevel (as mentioned in doc) but strange
> behavior
> > in a function, i did not understand really what happened but i got some
> > #unspecified value.
> >
> > here are my test code:
> > cheme@(guile-user)> (define (foo2)
> >   (define-once  x 1)
> >   (if #t
> >   (let ()
> > (define-once x 2)
> > ;;(set! x 2)
> > (display "x=")
> > (display x)
> > (newline))
> >   'never)
> >   (display x)
> >   (newline))
>
> Possibly you want (added a set? argument for demonstration):
>
> (define (foo2 set?)
>   (define x) ; define an (undefined or unbound, not sure about
> terminology) variable
>   (if set?
>   (let ()
> (set! x 2) ; change the value of x
> (display "x=")
> (display x)
> (newline))
>   'never)
>   (display x)
>   (newline))
>
> That should be portable and avoids global state.
>
> scheme@(guile-user)> x
> ;;; :20:0: warning: possibly unbound variable `x'
> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
> Unbound variable: x
> scheme@(guile-user) [1]> ,q
>
> scheme@(guile-user) [1]> (foo2 #f)
> # ; I expected an error as would result from ...
>
> ;; ... this ...
> scheme@(guile-user)> (variable-ref (make-undefined-variable))
> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
> In procedure variable-ref: Unbound variable: # value: #>
>
> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> scheme@(guile-user) [2]>
>
> ;; instead  of # but whatever ...
>
> scheme@(guile-user) [1]> (foo2 #t)
> x=2
> 2
> scheme@(guile-user) [1]> (foo2 #t)
> x=2
> 2
>
>
> scheme@(guile-user) [1]> (define x 3)
> scheme@(guile-user) [1]> (foo2 #t)
> x=2 ; foo2 doesn't use the global variable 'x'
> 2
>
> scheme@(guile-user) [1]> x
> $1 = 3
>
> Does this seem reasonable to you?
>


Re: Fwd: new function

2021-09-22 Thread Maxime Devos
Damien Mattei schreef op wo 22-09-2021 om 09:52 [+0200]:
> i do not understand well what you want to mean with those example.
> For me  define-once does not seems to be a solution, it act as define too 
> much 
> ,does not set! variable if already exist and can not use to set it again 
> because,
> as define it is forbidden twice in the same block for the same variable:
> [...]

I was not suggesting using define-once.
Rather, I was demonstrating how to get Python-style scoping of variables local 
to
a function (procedure) in Scheme without defining new syntax, by using set! 
instead
of define, and adding a define in the beginning of the procedure for every 
variable.

Python:

def hello(language):
  if language == "english":
 message = "Hello world!"
  if language == "dutch":
 message = "Hallo wereld!"
  print(message)

hello("english") # output: Hello world!
hello("dutch") # output: Hallo wereld!

Equivalent (non-idomatic but portable) Scheme:

(define (hello language)
  (define message)
  (cond ((equal? language "english")
 (set! message "Hello world!"))
((equal? language "dutch")
 (set! message "Hallo wereld!")))
 
(display message)
  (newline))

(hello "english") ; "Hello world!"
(hello "dutch") ; "Hallo wereld!"

Greetings,
Maxime.


signature.asc
Description: This is a digitally signed message part


Re: Fwd: new function

2021-09-22 Thread Taylan Kammer
On 21.09.2021 21:03, Maxime Devos wrote:
> 
> (define (foo2 set?)
>   (define x) ; define an (undefined or unbound, not sure about terminology) 
> variable
>   (if set?
>   (let ()
> (set! x 2) ; change the value of x
> (display "x=")
> (display x)
> (newline))
>   'never)
>   (display x)
>   (newline))
> 

I didn't know (define x) without a value was possible in Guile.  I guess
it's just a shorthand for (define x *unspecified*), judging by your result.

If I'm not mistaken, the only way in Scheme to get a "defined but not yet
bound" kind of situation is to use 'letrec'.  If you use the 'letrec*'
variant, it guarantees a straight order of evaluation, so the following is
supposed to definitely NOT work, due to y and z being defined-not-bound:

  (letrec* ((x (+ y z))
(y (random 10))
(z (random 10)))
(display x)
(newline))

However, in Guile, it seems to bind all the variables to #
anyway, resulting in a "wrong type argument" error (since we end up
passing # to '+') instead of saying that y and z are not
yet bound.

Long story short, there doesn't seem to be *any* way in Guile to have a
lexical variable that's defined but not bound.

-- 
Taylan