<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Common Lisp heresy: syntactic lambdas</title>
	<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas</link>
	<description>I hate self-referential taglines</description>
	<pubDate>Thu, 17 May 2012 05:21:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>

	<item>
		<title>By: John Watson</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-17841</link>
		<author>John Watson</author>
		<pubDate>Thu, 10 Sep 2009 16:36:43 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-17841</guid>
		<description>Suggestions:
* Let the lambda macro do its thing: let #'(lambda ...) just be (lambda ...).  This way you can use it standalone and as a function to pass to a higher-order function.  lambda is defined as a macro for this purpose.
* Why not do something closer to boost::lambda?  Let _1 be the 1st param, _2 the 2nd, etc.  Just requires some quick parsing of the tree.
e.g.
CL-USER&#62; ([+ _1 _2] 4 5)
9

Below is code to make this happen.  I left out the &#124;&#124; reading logic for making a separate argument list.

(defun underscore-num-sym-p (sym)
  (and (symbolp sym)
       (let ((str (symbol-name sym)))
         (string= "_" str)
         (parse-integer str :start 1 :junk-allowed t))))

;; Used to make two closures one that 
(defun make-symbol-finder ()
  (let ((max-sym 0))
    (values
     (lambda (sym)
       (let ((result (underscore-num-sym-p sym)))
         (and result (&#62; result max-sym) (setf max-sym result))
         result))
     (lambda () max-sym))))

;; (flatten '((1 2 3 nil 4 5 (nil 2 nil))))
;; Graham: (1 2 3 4 5 2)
;;   this: (1 2 3 NIL 4 5 NIL 2 NIL)
(defun flatten (x)
  (labels ((rec (x acc)
             (cond ((atom x) (cons x acc))
                   (t (rec (car x) (if (cdr x) (rec (cdr x) acc) acc))))))
    (rec x nil)))

(defun bracket-reader (stream char)
  (declare (ignore char))
  (multiple-value-bind (lsymbol-p num-lsyms) (make-symbol-finder)
    (let* ((body (read-delimited-list #\] stream t)))
      (remove-if-not lsymbol-p (flatten body))
      `(lambda ,(loop for i from 1 to (funcall num-lsyms) collect 
                     (intern (concatenate 'string "_" (write-to-string i))))
         ,body))))

(set-macro-character #\[ #'bracket-reader)
(set-macro-character #\] (get-macro-character #\#))</description>
		<content:encoded><![CDATA[<p>Suggestions:<br />
* Let the lambda macro do its thing: let #&#8217;(lambda &#8230;) just be (lambda &#8230;).  This way you can use it standalone and as a function to pass to a higher-order function.  lambda is defined as a macro for this purpose.<br />
* Why not do something closer to boost::lambda?  Let _1 be the 1st param, _2 the 2nd, etc.  Just requires some quick parsing of the tree.<br />
e.g.<br />
CL-USER&gt; ([+ _1 _2] 4 5)<br />
9</p>
<p>Below is code to make this happen.  I left out the || reading logic for making a separate argument list.</p>
<p>(defun underscore-num-sym-p (sym)<br />
  (and (symbolp sym)<br />
       (let ((str (symbol-name sym)))<br />
         (string= &#8220;_&#8221; str)<br />
         (parse-integer str :start 1 :junk-allowed t))))</p>
<p>;; Used to make two closures one that<br />
(defun make-symbol-finder ()<br />
  (let ((max-sym 0))<br />
    (values<br />
     (lambda (sym)<br />
       (let ((result (underscore-num-sym-p sym)))<br />
         (and result (&gt; result max-sym) (setf max-sym result))<br />
         result))<br />
     (lambda () max-sym))))</p>
<p>;; (flatten &#8216;((1 2 3 nil 4 5 (nil 2 nil))))<br />
;; Graham: (1 2 3 4 5 2)<br />
;;   this: (1 2 3 NIL 4 5 NIL 2 NIL)<br />
(defun flatten (x)<br />
  (labels ((rec (x acc)<br />
             (cond ((atom x) (cons x acc))<br />
                   (t (rec (car x) (if (cdr x) (rec (cdr x) acc) acc))))))<br />
    (rec x nil)))</p>
<p>(defun bracket-reader (stream char)<br />
  (declare (ignore char))<br />
  (multiple-value-bind (lsymbol-p num-lsyms) (make-symbol-finder)<br />
    (let* ((body (read-delimited-list #\] stream t)))<br />
      (remove-if-not lsymbol-p (flatten body))<br />
      `(lambda ,(loop for i from 1 to (funcall num-lsyms) collect<br />
                     (intern (concatenate &#8217;string &#8220;_&#8221; (write-to-string i))))<br />
         ,body))))</p>
<p>(set-macro-character #\[ #&#8217;bracket-reader)<br />
(set-macro-character #\] (get-macro-character #\#))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Travis</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-9497</link>
		<author>Travis</author>
		<pubDate>Mon, 10 Nov 2008 07:52:00 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-9497</guid>
		<description>On my version of Common Lisp (slime running sbcl): #[ #] and #) required a \ (ex: #\[, #\], #\)), or the reader would complain.  It's an interesting bit of code to use otherwise.</description>
		<content:encoded><![CDATA[<p>On my version of Common Lisp (slime running sbcl): #[ #] and #) required a \ (ex: #\[, #\], #\)), or the reader would complain.  It&#8217;s an interesting bit of code to use otherwise.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Luís</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-4362</link>
		<author>Luís</author>
		<pubDate>Sun, 22 Jun 2008 20:27:33 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-4362</guid>
		<description>People who complain about LAMBDA's verbosity often seem to be unaware that you can write (lambda (x) ...) instead of #'(lambda (x) ...). Not sure if that's your case, but since your LAMBDA examples have #' in there, I thought I should mention it.</description>
		<content:encoded><![CDATA[<p>People who complain about LAMBDA&#8217;s verbosity often seem to be unaware that you can write (lambda (x) &#8230;) instead of #&#8217;(lambda (x) &#8230;). Not sure if that&#8217;s your case, but since your LAMBDA examples have #&#8217; in there, I thought I should mention it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ...</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2972</link>
		<author>...</author>
		<pubDate>Wed, 07 May 2008 19:42:21 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2972</guid>
		<description>Are you aware of http://www.emacswiki.org/cgi-bin/wiki/PrettyLambda ?</description>
		<content:encoded><![CDATA[<p>Are you aware of <a href="http://www.emacswiki.org/cgi-bin/wiki/PrettyLambda" rel="nofollow">http://www.emacswiki.org/cgi-bin/wiki/PrettyLambda</a> ?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Patrick</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2524</link>
		<author>Patrick</author>
		<pubDate>Sat, 03 May 2008 23:26:12 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2524</guid>
		<description>One thing I should note -- &lt;tt&gt;intern&lt;/tt&gt; is mapcar'd over the named parameters so that one can use keywords -- as in, [:x :y &#124;&#124; (+ x y)]. I added this as a nod to the Smalltalk style, but it probably pushes things a bit too far...</description>
		<content:encoded><![CDATA[<p>One thing I should note &#8212; <tt>intern</tt> is mapcar&#8217;d over the named parameters so that one can use keywords &#8212; as in, [:x :y || (+ x y)]. I added this as a nod to the Smalltalk style, but it probably pushes things a bit too far&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Zach Beane</title>
		<link>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2518</link>
		<author>Zach Beane</author>
		<pubDate>Sat, 03 May 2008 21:50:44 +0000</pubDate>
		<guid>http://patrickcollison.com/blog/2008/05/common-lisp-heresy-syntactic-lambdas#comment-2518</guid>
		<description>I think this sort of thing is a great idea in an application. I've seen people who use short [] notation for data types that are used heavily in the problem domain, e.g. times, IP addresses, closures, etc.</description>
		<content:encoded><![CDATA[<p>I think this sort of thing is a great idea in an application. I&#8217;ve seen people who use short [] notation for data types that are used heavily in the problem domain, e.g. times, IP addresses, closures, etc.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

