On Fri, Oct 17, 2014 at 07:44:27PM +0200, Michele La Monaca wrote:
> Hi,
> 
> curiously:
> 
> 
> (cond (1 => odd?))
> 
> Error: unbound variable: =>
> 
> while
> 
> 
> (cond (+ => procedure?))
> #t
> 
> The only difference I can spot is that 1 is self-evaluating while + is
> not. Anyhow, it doesn't look good to me.

Well-spotted!  This was due to an optimisation which rewrote
(cond (CONSTANT <whatever> ...) ...) to <whatever>, which is correct,
but it forgot to rewrite (cond (CONSTANT => <whatever>) ...) to
(<whatever> CONSTANT).

The attached patch fixes it.

Thanks for reporting this issue!

Cheers,
Peter
-- 
http://www.more-magic.net
>From f66efec38cb6b7ebf34d70cfabafe9552807c9bd Mon Sep 17 00:00:00 2001
From: Peter Bex <peter....@xs4all.nl>
Date: Fri, 17 Oct 2014 20:46:15 +0200
Subject: [PATCH] Fix incorrect optimization in cond expansion.

When a constant is used as the condition, the consequence would be
simply taken as-is (or wrapped in a "begin" if it's multiple
statements).  However, if there's a => following the constant, it should
expand to a call of the procedure with the constant as argument.

Reported by Michele La Monaca
---
 NEWS                   |    2 ++
 expand.scm             |    9 ++++++---
 tests/syntax-tests.scm |    5 +++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 70b68fa..00b1475 100644
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,8 @@
 - Syntax expander
   - define-values, set!-values and letrec-values now support full lambda
     lists as binding forms
+  - cond expands correctly when a constant is used in combination with =>
+     (thanks to Michele La Monaca)
 
 - C API
   - Removed deprecated C_get_argument[_2] and
diff --git a/expand.scm b/expand.scm
index 16a1370..966d4ba 100644
--- a/expand.scm
+++ b/expand.scm
@@ -1174,9 +1174,12 @@
                          (and (pair? (car clause))
                               (c (r 'quote) (caar clause))))
                     (expand rclauses (strip-syntax (car clause)))
-                    (if (null? (cdr clause))
-                        (car clause)
-                        `(##core#begin ,@(cdr clause))))
+                    (cond ((and (fx= (length clause) 3)
+                                (c %=> (cadr clause)))
+                           `(,(caddr clause) ,(car clause)))
+                          ((null? (cdr clause))
+                           (car clause))
+                          (else `(##core#begin ,@(cdr clause)))))
                    ((null? (cdr clause)) 
                     `(,%or ,(car clause) ,(expand rclauses #f)))
                    ((and (fx= (length clause) 3)
diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm
index df0f607..ba9b3fc 100644
--- a/tests/syntax-tests.scm
+++ b/tests/syntax-tests.scm
@@ -196,6 +196,11 @@
 (let ((baz 100))
   (t "no baz" (kw baz)))
 
+;; Optimisation to rewrite constants with =>, reported by Michele La Monaca
+(t 2 (cond (1 2)))
+(f (cond (1 => string-length)))
+(t #t (cond (1 => odd?)))
+
 (t 'ok
 (let ((=> #f))
   (cond (#t => 'ok)))
-- 
1.7.10.4

_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to