Hi there!

This patch updates some derived conditional forms (and do and and-let*) to 
support definitions in expression context. Meaning it makes this valid code:

(cond 
  ((pred? arg) 
    (define a (something arg))
    (when (error-case a)
      (error "a is broken"))
    (define b (something2 a))
    (when  (= 3 *log-level*)
      (display "logging something1 and 2 as successful"))
    (define c (something3 b a))
    (when (odd? c)
       (error "something went wrong in something3"))
    c)
  (else 
    ;;chosen by fair dice roll. Guaranteed to be random
    4)))

While awful, is sometimes what the world makes us do. 

The change means cond, case, when and unless behaves like it does in racket. Do 
was below case, so I changed that as well, and will actually become yet another 
way guile is superior to racket. 

I did also change the documentation, but I learned english by watching Beverly 
Hills cop, so that might need some fine touches by a capable english speaker.
            

Best regards
  Linus Björnstam
From 7af96162bf531b70e66170864cd536032b1c89c7 Mon Sep 17 00:00:00 2001
From: Linus <bjornstam.li...@fastmail.se>
Date: Wed, 16 Jun 2021 20:47:41 +0200
Subject: [PATCH] Allow definitions in derived conditional forms

This allows definitions in the bodies of when, unless, do, and
 and-let*. It also adds support for definitions in cond- and
case-clauses.

 * doc/ref/api-control.texi (when, unless, cond, case): update
   documentation to reflect changes.
 * module/ice-9/and-let-star.scm: Changed (begin ...) to (let () ...)
 * module/ice-9/boot-9.scm (when, unless, cond, case, do): changed
   (begin ...) to (let () ...)
---
 doc/ref/api-control.texi      | 10 +++++-----
 module/ice-9/and-let-star.scm |  6 +++---
 module/ice-9/boot-9.scm       | 12 ++++++------
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi
index 5df5344c5..eaa2b4dbf 100644
--- a/doc/ref/api-control.texi
+++ b/doc/ref/api-control.texi
@@ -152,10 +152,10 @@ documentation:
 
 @example
 (define-syntax-rule (when test stmt stmt* ...)
-  (if test (begin stmt stmt* ...)))
+  (if test (let () stmt stmt* ...)))
 
 (define-syntax-rule (unless condition stmt stmt* ...)
-  (if (not test) (begin stmt stmt* ...)))
+  (if (not test) (let () stmt stmt* ...)))
 @end example
 
 That is to say, @code{when} evaluates its consequent statements in order
@@ -167,11 +167,11 @@ statements if @var{test} is false.
 Each @code{cond}-clause must look like this:
 
 @lisp
-(@var{test} @var{expression} @dots{})
+(@var{test} @var{expression-or-definition} @dots{})
 @end lisp
 
-where @var{test} and @var{expression} are arbitrary expressions, or like
-this
+where @var{test} is an arbitrary expression, and @var{expression-or-definition}
+is an arbitrary expression or a definition, like @code{define}.
 
 @lisp
 (@var{test} => @var{expression})
diff --git a/module/ice-9/and-let-star.scm b/module/ice-9/and-let-star.scm
index 2d53ff384..9427c1733 100644
--- a/module/ice-9/and-let-star.scm
+++ b/module/ice-9/and-let-star.scm
@@ -53,12 +53,12 @@
       ((_ orig-form ((var expr)) . body)
        (identifier? #'var)
        #'(let ((var expr))
-           (and var (begin . body))))
+           (and var (let () . body))))
       ((_ orig-form ((expr)) . body)
-       #'(and expr (begin . body)))
+       #'(and expr (let () . body)))
       ((_ orig-form (var) . body)
        (identifier? #'var)
-       #'(and var (begin . body)))
+       #'(and var (let () . body)))
 
       ;; Handle bad clauses.
       ((_ orig-form (bad-clause . rest) . body)
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index 2323b1ec5..675f38633 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -417,10 +417,10 @@ If returning early, return the return value of F."
 (include-from-path "ice-9/quasisyntax")
 
 (define-syntax-rule (when test stmt stmt* ...)
-  (if test (begin stmt stmt* ...)))
+  (if test (let () stmt stmt* ...)))
 
 (define-syntax-rule (unless test stmt stmt* ...)
-  (if (not test) (begin stmt stmt* ...)))
+  (if (not test) (let () stmt stmt* ...)))
 
 (define-syntax else
   (lambda (x)
@@ -461,7 +461,7 @@ If returning early, return the return value of F."
                          ((else e e* ...)
                           (lambda (tail)
                             (if (null? tail)
-                                #'((begin e e* ...))
+                                #'((let () e e* ...))
                                 (bad-clause "else must be the last clause"))))
                          ((else . _) (bad-clause))
                          ((test => receiver)
@@ -488,7 +488,7 @@ If returning early, return the return value of F."
                          ((test e e* ...)
                           (lambda (tail)
                             #`((if test
-                                   (begin e e* ...)
+                                   (let () e e* ...)
                                    #,@tail))))
                          (_ (bad-clause))))
                      #'(clause clauses ...))))))))
@@ -534,7 +534,7 @@ If returning early, return the return value of F."
                                ((=> receiver ...)
                                 (bad-clause
                                  "wrong number of receiver expressions"))
-                               ((e e* ...) #'(begin e e* ...))
+                               ((e e* ...) #'(let () e e* ...))
                                (_ (bad-clause)))))
                          (syntax-case #'test (else)
                            ((datums ...)
@@ -585,7 +585,7 @@ If returning early, return the return value of F."
                (begin
                  (if #f #f)
                  expr ...)
-               (begin
+               (let ()
                  command
                  ...
                  (loop (do "step" var step ...)
-- 
2.25.1

Reply via email to