hello, i ported my code from guile that use ,as you say it 'exceptions': ;; #|kawa:57|# ;; #|kawa:58|# (define r 2) ;; #|kawa:59|# (if-defined r 'defined (define r 7)) ;;if-defined : where=#t ;; id=r ;; (if-defined r 'defined (define r 7)) ;; defined ;; #|kawa:60|# r ;; 2 ;; #|kawa:61|# (defined-symbol? r) ;; #t ;; #|kawa:62|# (defined-symbol? t) ;; /dev/tty:62:18: warning - no declaration seen for t ;; defined-symbol? : undefined ;; #f ;; #|kawa:63|# (let ((k 7)) (defined-symbol? k)) ;; #t ;; (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 ;; #|kawa:86|# (define k 0) ;; #|kawa:87|# (let loop () (if (< k 4) (let () (display k) (newline) (<- k (+ k 1)) (loop)))) ;; if-defined : where=#t ;; id=k ;; 0 ;; 1 ;; 2 ;; 3 ;; #|kawa:88|# (let () (define k 0) (let loop () (if (< k 4) (let () (display k) (newline) (<- k (+ k 1)) (loop))))) ;; if-defined : where=#t ;; id=k ;; 0 ;; 1 ;; 2 ;; 3 ;; #|kawa:89|# (let () (define s 0) (let loop () (if (< s 4) (let () (display s) (newline) (<- s (+ s 1)) (loop))))) ;; if-defined : where=#t ;; id=s ;; 0 ;; 1 ;; 2 ;; 3 ;; #|kawa:90|# (let ((s 0)) (let loop () (if (< s 4) (let () (display s) (newline) (<- s (+ s 1)) (loop))))) ;; if-defined : where=#t ;; id=s ;; 0 ;; 1 ;; 2 ;; 3 (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)))))) i use the code in conjunction with this macro: (define-syntax <- (lambda (stx) (syntax-case stx () #`(if-defined var (set! var expr) (define var expr)))))) it works better than guile (guile fails on the let () tests...: scheme@(guile-user)> (let ((k 0)) (let loop () (if (< k 4) (let () (display k) (newline) (<- k (+ k 1)) (loop))))) defined-symbol? : undefined if-defined : where=#f id=# # ice-9/boot-9.scm:1685:16: In procedure raise-exception: In procedure +: Wrong type argument in position 1: # Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. ), as you can see the examples , but in some place of my code kawa fails too, i made a simplified example from the whole code: for example if i put all the stuff in a module test-defined.scm: (module-name test-defined) (export foo) (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 (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)))))) (define-syntax <- (lambda (stx) (syntax-case stx () ((_ var expr) #`(if-defined var (set! var expr) (define var expr)))))) (define (foo) (define expr2 '()) (<- expr2 7)) then it fails: #|kawa:1|# (require test-defined)defined-symbol? : undefined if-defined : where=#f id=expr2 (require test-defined) /Users/mattei/Scheme-PLUS-for-Kawa/test-defined.scm:95:7: duplicate declaration of 'expr2' /Users/mattei/Scheme-PLUS-for-Kawa/test-defined.scm:93:11: (this is the previous declaration of 'expr2') it finds that expr2 is not defined,then expand a (define expr2 ...) but then cause an error of duplicate declaration of expr2 On Thu, Apr 11, 2024 at 3:01 AM Per Bothner wrote: > > > On 4/10/24 14:49, Damien Mattei via Kawa wrote: > > hello, > > > > is there a way to know if a variable is defined in Kawa? > > > > (like 'identifier-binding' in Racket) > > If you need to know if a variable is bound in the dynamic environment, > you could perhaps use eval wrapped in an exception handler. > > There are probably better ways, but I don't remember off-hand. > > Can't think of anything to use if you need information about lexical > bindings. > I supposed you could implemented identifier-binding or something similar. > > -- > --Per Bothner > per@bothner.com http://per.bothner.com/ >