guile-user
[Top][All Lists]
Advanced

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

conditional based on binding of a variable


From: Damien Mattei
Subject: conditional based on binding of a variable
Date: Fri, 12 Apr 2024 00:34:54 +0200

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]