guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: conditional based on binding of a variable


From: Damien Mattei
Subject: Re: conditional based on binding of a variable
Date: Fri, 12 Apr 2024 13:40:51 +0200

indeed ,seems not a thing feasible ,unless in Racket where it works great:

https://stackoverflow.com/questions/3267351/how-do-i-test-whether-a-variable-is-defined-before-referencing-it?noredirect=1&lq=1

On Fri, Apr 12, 2024 at 12:34 AM Damien Mattei <damien.mattei@gmail.com>
wrote:

>
> hello,
>
> i'm searching the equivalent in scheme , guile or r6rs of this code for
> Racket:
>
> ; Tests
> ;; (if-defined z (list z) 'not-defined) ; -> not-defined
>
> ;; (if-defined t (void) (define t 5))
> ;; t ; -> 5
>
> ;; (define x 3)
> ;; (if-defined x (void) (define x 6))
> ;; x ; -> 3
> (define-syntax (if-defined stx)
>   (syntax-case stx ()
>     [(_ id iftrue iffalse)
>      (let ([where (identifier-binding #'id)])
>        (display "if-defined : where=") (display where) (newline)
>        (display "id=") (display #'id) (newline)(newline)
>        (if where #'iftrue #'iffalse))]))
>
> it is based on identifier-binding
>
> i tried defined? in guile but it is not reliable other than toplevel, then
> i wrote this code based on exception and test the evaluation of the
> variable in environment:
>
> ;; scheme@(guile-user)> (defined-symbol? d)
> ;; ;;; <stdin>:20:17: warning: possibly unbound variable `d'
> ;; $3 = #f
> (define-syntax defined-symbol?
>   (syntax-rules ()
>     ((_ x) (call-with-current-continuation
>    (lambda (exit)
>      (with-exception-handler
>       (lambda (e)
> (display "defined-symbol? : undefined") (newline)
> (exit #f)) ; eval failed => not defined
>       (lambda ()
> (eval x (interaction-environment))
> #t))))))) ; eval suceeded => defined
>
> used in conjunction with:
>
> ;; scheme@(guile-user)> (define r 2)
> ;; scheme@(guile-user)> (if-defined r 'defined (define r 7))
> ;; if-defined : where=#t
> ;; $16 = defined
> ;; scheme@(guile-user)> (if-defined t3 'defined (define t3 7))
> ;; if-defined : where=#f
> ;; scheme@(guile-user)> t3
> ;; $17 = 7
> ;; scheme@(guile-user)> (if-defined z (list z) 'not-defined)
> ;; if-defined : where=#f
> ;; $18 = not-defined
> (define-syntax if-defined
>   (lambda (stx)
>     (syntax-case stx ()
>       ((_ id iftrue iffalse)
>        (let ((where (defined-symbol? #'id))) ;;(quote id))))
> (display "if-defined : where=") (display where) (newline)
> (display "id=") (display #'id) (newline)
> (if where #'iftrue #'iffalse))))))
>
> but in some case it fails again
>
> the goal is to be able to use this macro:
>
> (define-syntax <-
>
>   (lambda (stx)
>
>     (syntax-case stx ()
>
>       ((_ var expr)
>
>        #`(if-defined var
>     (set! var expr)
>     (define var expr))))))
>
> that define a variable when not defined or just set! it
>
> it then fails in some case:
>
> (let () (define k 0) (let loop () (if (< k 4) (let () (display k)
> (newline) (<- k (+ k 1)) (loop)))))
> defined-symbol? : undefined
> if-defined : where=#f
> id=#<syntax:unknown file:22:80 k>
> #<unspecified>
> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
> In procedure +: Wrong type argument in position 1: #<unspecified>
>
> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
>
> but works in this case:
>
> scheme@(guile-user)> (define k 0)
> scheme@(guile-user)> (let loop () (if (< k 4) (let () (display k)
> (newline) (<- k (+ k 1)) (loop))))
> if-defined : where=#t
> id=#<syntax:unknown file:25:59 k>
> 0
> 1
> 2
> 3
>
> i know it is hard and perheaps not possible but if someone has any idea?
>
> Damien
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]