Damien Mattei schreef op zo 19-09-2021 om 11:18 [+0200]: > ---------- Forwarded message --------- > From: Damien Mattei > Date: Sun, Sep 19, 2021 at 9:54 AM > Subject: new function > To: > > > hello, > i'm developing an extension to Scheme > and i need a procedure or macro that define a variable only if it is not > bind and if it is just set! it. Could you give an example in which the hypothetical define-or-set! is used? I wonder where such a thing would be useful. > I can not do it in Guile or any Scheme,and i'm desperately searching a way > to do that. I finally conclude that it can be done only by adding it in the > language. > > Can someone include a such function in Guile next release? > i know guile have a predicate defined? defined? only works on global variables, not on lexicals, and depends on the (current-module), which is not necessarily the module defined? is used in. > to test binfing of a vairable but > writing a macro with it is not possible because define can be used in an > expression context. You can use 'syntax-local-binding'. (use-modules (system syntax)) (define-syntax define-or-set! (lambda (s) (syntax-case s () ((_ var value) (case (syntax-local-binding #'var) ((lexical displaced-lexical) #'(set! var value)) ((global) #'(define var value)) (else ???)))))) ,expand (define-or-set! a 0) ; $_ = (define a 0) ,expand (let ((a 0)) (define-or-set! a 0) a) ; $_ = (let ((a 0)) (set! a 0) a) (define-or-set! a 0) ,expand (define-or-set! a 0) ; $_ = (define a 0) (might or might not be acceptable for your use case ,expand (let () (define-or-set! a 0) (define-or-set! a 1) a) ; $_ = (let () (define a 0) (set! a 1)) Greetings, Maxime.