this could not works because the defined-symbol? used in the macro if-defined return false because at the expansion of the macro the symbol is not defined.
Instead at run-time, this works: #|kawa:21|# (define (foo2) (define x 7) (defined-symbol? x)) #|kawa:22|# (foo2) #t On Sun, Apr 14, 2024 at 9:24 AM Damien Mattei <damien.mat...@gmail.com> wrote: > i tried this, that works in some case: > > ;; 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 > > > ;; 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 fais with those examples: > > scheme@(guile-user)> (define (foo) (define x 1) (if-defined x 'def > 'not_def)) > defined-symbol? : undefined > if-defined : where=#f > id=#<syntax:unknown file:37:39 x> > scheme@(guile-user)> (define (bar) (let ((x 1)) (if-defined x 'def > 'not_def))) > defined-symbol? : undefined > if-defined : where=#f > id=#<syntax:unknown file:38:39 x> > > > On Fri, Apr 12, 2024 at 1:40 PM Damien Mattei <damien.mat...@gmail.com> > wrote: > >> 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.mat...@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 >>> >>>