unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Add internal definitions to derived forms
@ 2022-11-09 15:32 Linus Björnstam
  2022-11-09 15:46 ` Damien Mattei
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Linus Björnstam @ 2022-11-09 15:32 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

Hi there!

This commit adds internal definitions to derived conditional forms, with-fluids and and-let*. This means the bodies of when, unless and with-fluids, and the clause bodies of case and cond behave like a lambda body. 

There is no performance hit since guile optimizes a (let () ...) without internal definitions to a begin (i.e: no new lexical context is created).

best regards
  Linus Björnstam

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-internal-definitions-to-derived-forms.patch --]
[-- Type: text/x-patch; name="0001-Add-internal-definitions-to-derived-forms.patch", Size: 6347 bytes --]

From 7eeb91b822334b151c5b4a15ce9528a2a655d914 Mon Sep 17 00:00:00 2001
From: Linus <bjornstam.linus@fastmail.se>
Date: Wed, 9 Nov 2022 16:15:18 +0100
Subject: [PATCH] Add internal definitions to derived forms

This commit adds internal definitions to the following derived
forms: when, unless, cond, case, with-fluids, and and-let*.

 * doc/ref/api-control.texi (Conditionals): Update the syntax and docs
   of when, unless, cond, and case.
 * module/ice-9/and-let-star.scm (and-let*): Changed begins to let.
 * module/ice-9/boot-9.scm (cond, case, when, unless, with-fluids):
   Changed begins to let.
---
 doc/ref/api-control.texi      | 25 +++++++++++++------------
 module/ice-9/and-let-star.scm |  6 +++---
 module/ice-9/boot-9.scm       | 12 ++++++------
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi
index 087e795..ece6a60 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 test 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{body} @dots{})
 @end lisp
 
-where @var{test} and @var{expression} are arbitrary expressions, or like
-this
+where @var{test} is an arbitrary expression and @var{body} is a
+lambda-like body, or like this
 
 @lisp
 (@var{test} => @var{expression})
@@ -217,7 +217,7 @@ result of the @code{cond}-expression.
 @var{key} may be any expression, and the @var{clause}s must have the form
 
 @lisp
-((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
+((@var{datum1} @dots{}) @var{body} @dots{})
 @end lisp
 
 or
@@ -229,7 +229,7 @@ or
 and the last @var{clause} may have the form
 
 @lisp
-(else @var{expr1} @var{expr2} @dots{})
+(else @var{expr1} @var{body} @dots{})
 @end lisp
 
 or
@@ -239,13 +239,14 @@ or
 @end lisp
 
 All @var{datum}s must be distinct.  First, @var{key} is evaluated.  The
-result of this evaluation is compared against all @var{datum} values using
-@code{eqv?}.  When this comparison succeeds, the expression(s) following
-the @var{datum} are evaluated from left to right, returning the value of
-the last expression as the result of the @code{case} expression.
+result of this evaluation is compared against all @var{datum} values
+using @code{eqv?}.  When this comparison succeeds, the @var{body}
+following the @var{datum} is evaluated like the body of a lambda,
+returning the value of the last expression as the result of the
+@code{case} expression.
 
 If the @var{key} matches no @var{datum} and there is an
-@code{else}-clause, the expressions following the @code{else} are
+@code{else}-clause, the @var{body} following the @code{else} is
 evaluated.  If there is no such clause, the result of the expression is
 unspecified.
 
diff --git a/module/ice-9/and-let-star.scm b/module/ice-9/and-let-star.scm
index 2d53ff3..9427c17 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 a46145e..dc35370 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 ...)
@@ -674,7 +674,7 @@ If returning early, return the return value of F."
          #`(let ((fluid-tmp fluid) ...)
              (let ((val-tmp val) ...)
                #,(emit-with-fluids #'((fluid-tmp val-tmp) ...)
-                                   #'(begin exp exp* ...)))))))))
+                                   #'(let () exp exp* ...)))))))))
 
 (define-syntax current-source-location
   (lambda (x)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2023-02-02 11:17 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-09 15:32 Add internal definitions to derived forms Linus Björnstam
2022-11-09 15:46 ` Damien Mattei
2022-11-17  7:25 ` lloda
2022-11-18  9:04   ` Linus Björnstam
2022-11-18  9:27     ` Lassi Kortela
2022-11-18  9:50       ` Linus Björnstam
2022-11-18 10:22         ` Lassi Kortela
2022-11-18 12:53           ` Linus Björnstam
2022-11-18 13:18             ` Lassi Kortela
2023-01-19 17:54             ` lloda
2023-01-20 17:37               ` lloda
2023-01-23 22:13                 ` Ludovic Courtès
2023-01-23 23:28                   ` lloda
2023-01-24  7:33                     ` Linus Björnstam
2023-01-24  9:02                     ` Ludovic Courtès
2023-01-24 17:59                       ` lloda
2023-01-25 10:33                         ` Ludovic Courtès
2023-01-25 15:09 ` Ludovic Courtès
2023-01-25 15:38   ` Greg Troxel
2023-01-25 21:38     ` Linus Björnstam
2023-01-25 21:06   ` Linus Björnstam
2023-02-02 11:17   ` lloda

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