>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.