Recently Written · git

common-lisp-utils

My utilities for Common Lisp programming.

git clone https://github.com/equwal/common-lisp-utils

Log | Files | Refs


commit aad040c208b8f02f7308d58cd5c832d5ac69a673
Spenser Truex <spensertruexonline@gmail.com>
2018-04-23 00:11:10 -0300

Fixed y-combinator to use f as a function.

 utils.lisp | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/utils.lisp b/utils.lisp
index 75f1e48..2bc031d 100644
--- a/utils.lisp
+++ b/utils.lisp
@@ -7,8 +7,10 @@
 	   :y
 	   :aif
 	   :it ;; A feature of some anaphoric macros
-	   :f ;; A feature of the y combinator anaphoric macro.
-	   ))
+	   :abbrev
+	   :abbrevs
+	   :enum
+	   :id))
 (in-package :utils)
 (defun y-comb (f)
   "The Y-combinator from the Lambda calculus of Alonzo Church."
@@ -22,16 +24,25 @@
 						      (progn (print n) (funcall FUNCTION (- n 1))))))) 10)|#
 ;;; Yes it is a bit complex and redundant, so there is an anaphoric macro.
 (defmacro y (lambda-list-args specific-args &rest code)
-  "Like Y-combinator, but is a recursive macro. The anaphor is 'f'. Don't forget
-to funcall f instead of trying to use it like an interned function."
-  ;; Funcall is the price we pay for being a Lisp-2. No way around this without language switch.
-  `(funcall (y-comb #'(lambda (f) #'(lambda ,lambda-list-args
-				      ,@code)))
-	    ,@specific-args))
+  "The anaphor is 'f'. Don't forget to funcall f instead of trying to use it 
+   like an interned function."
+  (with-gensyms (args f)
+    `(funcall (y-comb #'(lambda (,f) #'(lambda ,lambda-list-args
+					 (flet ((f (&rest ,args)
+						  (apply ,f ,args)))
+					  ,@code))))
+	      ,@specific-args)))
+ ;; (defmacro y (lambda-list-args specific-args &rest code)
+ ;;   "Like Y-combinator, but is a recursive macro. The anaphor is 'f'. Don't forget
+ ;; to funcall f instead of trying to use it like an interned function."
+ ;;   ;; Funcall is the price we pay for being a Lisp-2. Work around: symbol-macrolet.
+ ;;   `(funcall (y-comb #'(lambda (f) #'(lambda ,lambda-list-args
+ ;; 				      ,@code)))
+ ;; 	    ,@specific-args))
 ;;; Example code for the anaphoric y-combinator:
 #|(y (a b) (10 0) 
-(if (= 0 a) 				; ; ;
-b					; ; ;
+(if (= 0 a) 				; ; ; ;
+b					; ; ; ;
 (funcall f (- a 1) (progn (print b) (+ b 1)))))|#
 
 (defmacro with-gensyms (symbols &body body)
@@ -94,3 +105,14 @@ b					; ; ;
      ,@(mapcar #'(lambda (pair)
 		   `(abbrev ,@pair))
 	       (group names 2))))
+(defun enum (list)
+  (y (list acc count) (list nil 0)
+     (if (null list)
+	 (reverse acc)
+	 (funcall f (cdr list)
+		  (cons (cons (car list) count) acc)
+		  (1+ count)))))
+(defun id (thing)
+  thing)
+;; Reader macro:
+;; Convert something like #Fa.b.c to #'(lambda (x) (a (b (c x))))