Re: cond clause does not allow definitions

Damien Mattei <[email protected]>
Newsgroups gmane.lisp.guile.user
Message-ID <CADEOadftk4Ms=T2GGE-fLziU8kEwY_Y5rCs1DXRfKfT6oH3DCA@mail.gmail.com>
hello Maxime,

On Thu, May 23, 2024 at 12:12 AM Maxime Devos <[email protected]>
wrote:

> >but it is allowed in else clause:
>
> >scheme@(guile-user)> (cond (else (define x 7) x))
>
> >$4 = 7
>
> >
>
> >not really logic
>
>
>
> Probably in the implementation of ‘cond’, (cond (else X)) reduces to ‘X’.
>
>
>
> It’s tricky to ensure the same behaviour here as is the case when there is
> more than only the ‘else’ clause – without tail-calling, you could use
> ‘call-with-values’ in the macro to artificially make an expression context
> etc., but ‘cond’ needs to tail-call for X.
>
>
>
> If someone wishes to implement this, I would propose defining some new
> syntax ‘begin-expression’ (like ‘begin’, but instead of splicing, it
> interprets things as a bunch of expressions to evaluate in-order, and with
> the last expression in tail-position). Would probably be needed to be
> implemented as a primitive.
>
>
>
> Then, ‘(cond (else X))’ could be implemented as (begin-expression X).
>
>
>
> The documentation complains a bit about how ‘begin’ does both splicing and
> this ‘begin-expression’, but 'begin’ can be split! (At least, I think so,
> it has been a while since I read that part.)
>
>
>
> >It is allowed in Kawa and Racket but they are not scheme references
>
> the R5RS and R7RS talk about 'clause' without more information
>
>
>
> I don’t know what the standard says about this.
>
>
>
> >is it normal for Guile to consider clause for cond to be an expression
>
> context and not a definition context?
>
>
>
> Personally, I don’t care whether something is ‘normal’, whatever that’s
> supposed to mean. What I would care about, is whether the implementation
> matches the documentation, whether the documentation is complete (even
> saying “It is unspecified whether [this] or [that].” would suffice) and
> whether the (documented) semantics is desired, useful, convenient and
> consistent with relevant standards and conventions.
>
>
>
> In this case, not all of these are satisfied.
>
>
>
> >should not be better to consider definition context? that would allow more
>
> possibilities.
>
>
>
> That would be possible – (cond (a x) ...) could be interpreted as (cond (a
> (let () x)) ...) instead.
>
>
>
> However, I don’t think it has the semantics you desire. Some time ago, you
> asked questions  along the lines of making a macro ‘define-block’ that
> allows doings things like
>
yes...

i had written a special form condx that allow both inner definition and
inter-definition between conditionals LOL (do not scream please... :-) :

(define-syntax condx
  (syntax-rules (exec else)
    ((_) '()) ;; allow no else clause
    ((_ (else e ...))
     (let () e ...))
    ((_ (exec s ...) d1 ...)
     (let () s ... (condx d1 ...)))
    ((_ (t e ...) tail ...)
     (cond (t (let () e ...))
  (else (condx tail ...))))))


>
> (define (f)
>
>   (if blah
>
>       (define-block foo 1)
>
>       (define-block foo 2))
>
>   [do things with foo here])
>
>
>
but that’s not how scoping, macros and in particular ‘let’ works in Scheme,
> as mentioned there.
>
>
>
> Personally, I think implementing ‘cond’ as the cond+let stuff mentioned
> above is a bit risky w.r.t. misunderstanding scoping, consider for example:
>
>
>
> (define (f x)
>
>   (define y x)
>
>   (cond ((square? x) (define y (sqrt x)) (pk “took a square root”))
>
>              [more branches here])
>
> y)
>
>
>

if i understand , one could misuse y , but it is clear for me that the y in
cond is different than the one more global in f and the last y and result
of f should be x , it is to the programmer to take care of that.

consider Python , it is incredible :
if True:
    x=7

x
7

and now x is defined out of the branch of  x

not a problem for me with that.

Regards,
Damien



> which would silently do the wrong thing (unless you enable warnings for
> shadowing, but you can do neat things with shadowing – you can write pure
> code in a somewhat imperative style (*)).
>
>
>
> Best regards,
> Maxime Devos
>
>
>
> (*)  See, e.g.,
> https://git.gnunet.org/gnunet-scheme.git/tree/gnu/gnunet/config/parser.scm,
> where ‘let^’ can do (if X (return Y)) and ‘continue’ without let/ec (not an
> use of shadowing but sounds like something you may be interested in). On
> line
> https://git.gnunet.org/gnunet-scheme.git/tree/gnu/gnunet/config/parser.scm#n481
> and 485, you can see how shadowing is used as a replacement of mutation.
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.