unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Damien Mattei <damien.mattei@gmail.com>
To: guile-user <guile-user@gnu.org>
Subject: Re: conditional based on binding of a variable
Date: Tue, 16 Apr 2024 08:41:29 +0200	[thread overview]
Message-ID: <CADEOadd-=FPfiPmVTCkryJAD41hDpwCzr7HPPjC56AR=fNOnBQ@mail.gmail.com> (raw)
In-Reply-To: <CADEOaddknrHwDVLhzMcwTV+54dd+MpcZc9G_U2KT7KsF4TNtwg@mail.gmail.com>

scheme@(guile-user)> (define (foo2) (define x 7) (defined-symbol? x))
scheme@(guile-user)> (foo2)
$2 = #t

On Tue, Apr 16, 2024 at 8:36 AM Damien Mattei <damien.mattei@gmail.com>
wrote:

> 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.mattei@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.mattei@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.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	other threads:[~2024-04-16  6:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-11 22:34 conditional based on binding of a variable Damien Mattei
2024-04-12 11:40 ` Damien Mattei
2024-04-14  7:24   ` Damien Mattei
2024-04-16  6:36     ` Damien Mattei
2024-04-16  6:41       ` Damien Mattei [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADEOadd-=FPfiPmVTCkryJAD41hDpwCzr7HPPjC56AR=fNOnBQ@mail.gmail.com' \
    --to=damien.mattei@gmail.com \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).