unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Maxime Devos <maximedevos@telenet.be>
To: Damien Mattei <damien.mattei@gmail.com>, guile-user <guile-user@gnu.org>
Subject: RE: cond clause does not allow definitions
Date: Thu, 23 May 2024 00:12:02 +0200	[thread overview]
Message-ID: <20240523001202.SNC02C00D1JCEDt06NC2dB@albert.telenet-ops.be> (raw)
In-Reply-To: <CADEOaddz=+Teyh2U98TOMjH4_N7K7UjBiNYj5=Jr0=KPbOrsVw@mail.gmail.com>

>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

(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)

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.


  parent reply	other threads:[~2024-05-22 22:12 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-22 19:26 cond clause does not allow definitions Damien Mattei
2024-05-22 20:07 ` Jeronimo Pellegrini
2024-05-22 20:33   ` Damien Mattei
2024-05-22 20:34     ` Damien Mattei
2024-05-22 20:37     ` lloda
2024-05-22 20:40       ` lloda
2024-05-22 21:07   ` Pierpaolo Bernardi
2024-05-22 22:09     ` Damien Mattei
2024-05-22 22:37     ` Jeronimo Pellegrini
2024-05-23 14:25       ` Damien Mattei
2024-05-23 14:59         ` Pierpaolo Bernardi
2024-05-22 22:12 ` Maxime Devos [this message]
2024-05-22 22:34   ` Damien Mattei
2024-05-24 14:27 ` Linus Björnstam

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=20240523001202.SNC02C00D1JCEDt06NC2dB@albert.telenet-ops.be \
    --to=maximedevos@telenet.be \
    --cc=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).