tag:blogger.com,1999:blog-233268602024-03-06T03:35:24.154+00:00Kvardek DuLuíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.comBlogger49125tag:blogger.com,1999:blog-23326860.post-62771255415119314412024-01-30T14:56:00.002+00:002024-01-30T14:56:53.750+00:00Manuel Simoni on CL's control flow primitives<p>Manuel Simoni dusts his <em>Axis of Eval</em> blog off and writes about <a href="http://axisofeval.blogspot.com/2024/01/common-lisps-block-return-from-and.html">Common Lisp's BLOCK / RETURN-FROM and UNWIND-PROTECT</a>. A summary for non-Lispers.</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-14650825922335506152018-04-02T13:03:00.001+01:002018-04-02T13:05:32.577+01:00Reddit 1.0As many Lisp programmers may remember, <a href="https://reddit.com/">Reddit</a> was initially written in Common Lisp. Then, in late 2005, it was <a href="https://web.archive.org/web/20051230165203/http://reddit.com:80/blog/2005/12/night-of-living-python.html">rewritten in Python</a>. Much discussion ensued. Steve Huffman (aka spez, current CEO of Reddit) wrote about <a href="https://redditblog.com/2005/12/05/on-lisp/">why they switched to Python</a>. The late Aaron Swartz also wrote <a href="http://www.aaronsw.com/weblog/rewritingreddit">Rewriting Reddit</a>, focusing on the Python side of things.<br />
<br />
Last week, that original, Common Lisp version of Reddit was published on GitHub: <a href="https://github.com/reddit-archive/reddit1.0">reddit-archive/reddit1.0</a>. There's no documentation, but we know from the articles above that it ran on CMUCL. <a href="https://github.com/reddit-archive/reddit1.0/blob/master/reddit.asd">reddit.asd</a> is perhaps a good entry point, where we can see it used <a href="https://edicl.github.io/hunchentoot/">TBNL</a>, <a href="https://edicl.github.io/cl-who/">CL-WHO</a> and <a href="http://clsql.kpe.io/">CLSQL</a>, a common toolset at the time.<br />
<br />
It's missing various bits of static HTML, CSS and JS, so I don't think you can actually run this website without a fair bit of scrapping and stitching from the Wayback Machine. The code is quite readable and clean. It's not terribly interesting, since it's a fairly simple website. Still, it's a website that grew to become the 6th most visited worldwide (with 542 million monthly visitors) and now has 230 employees, says Wikipedia, so it's nice to see what it looked like at the very beginning.Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com1tag:blogger.com,1999:blog-23326860.post-7410457542994073862017-12-19T22:37:00.000+00:002017-12-19T22:40:20.456+00:00A Lisp REPL in your pocket<p>Thanks to Polos Ruetz, you can now play with Common Lisp directly on your Android phone. All you need to do is install <a href="https://play.google.com/store/apps/details?id=org.eql5.android.repl">CL REPL</a> from the Google Play Store. CL REPL is <a href="https://gitlab.com/eql/EQL5-Android/tree/master/examples/REPL">one of the examples</a> part of <a href="https://gitlab.com/eql/EQL5-Android">EQL5-Android</a> which is built on top of <a href="https://gitlab.com/eql/EQL5">EQL5</a>, a project that marries <a href="https://common-lisp.net/project/ecl/">ECL</a> with <a href="https://www.qt.io/">Qt</a>.</p><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://play.google.com/store/apps/details?id=org.eql5.android.repl" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5caJ9pZiz-UfFl9V_WBiKMYAU_LiCR9g-9VeeQyV5lMUMrsNLIDmf-jGIu37JFbMSQrKYkrK9zNEgj2nkQgyv3kRjJ9SC7s4cB59xWKS5SJ06zcFaBUNNZo96k62VQimFtb3SYQ/s200/cl-repl-logo.png" width="200" height="200" data-original-width="300" data-original-height="300" /></a></div><br />
<blockquote><strong>CL REPL</strong><br />
<br />
<em>A Common Lisp REPL with command line and history, plus a simple editor with syntax highlighting, simple visual paren-matching, a file dialog for opening/saving files, and a simple debug dialog. It uses the ECL implementation for the Lisp side, and Qt5/QML for the UI. This is an open source project (see EQL5-Android).</em></blockquote><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://play.google.com/store/apps/details?id=org.eql5.android.repl" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgekDqBD-AQ-r6frvnXYfXXbZ7kwLOfKntP9QYzulPiaUQnmuFS6J11HI7W_RsF98dXkb6__l7KLNF5P21qI1gfWsXLOpNnZp5XpN06i7I1-LkcMLFJIwZe82FOzvCA3ZA8qTrVJw/s1600/cl-repl.png" data-original-width="506" data-original-height="900" /></a></div><br />
<p>(via <a href="https://twitter.com/dk_jackdaniel/status/942857838644400129">@dk_jackdaniel</a>)</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com7tag:blogger.com,1999:blog-23326860.post-60172976874154168552016-07-10T23:39:00.001+01:002016-07-14T13:46:09.348+01:00Re: Querying plistsZach's <a href="http://lispblog.xach.com/post/147048601608">Querying plists</a> blog post showcases a neat little querying DSL for plists. I couldn't shake the feeling that it looked an awful lot like pattern matching. I've often been impressed by <a href="https://github.com/m2ym/optima">optima</a>, but I barely get to use it, so I thought I should try and see what querying plists looked like using pattern matching.<br />
<br />
Here's what I came up with. Zach's example<br />
<blockquote><pre><code>(query-plists '(:and (:= :first-name "Zach") (:= :state "ME")
(:not (:= :last-name "Beane")))
*people*)
</code></pre></blockquote>becomes:<br />
<blockquote><pre><code>(remove-if-not (lambda-match ((plist :first-name "Zach" :state "ME"
:last-name (not "Beane")) t))
*people*)
</code></pre></blockquote><br />
It turned out more succinct than I initially expected! Also, it's trivially adaptable to other kinds of objects. E.g., given the following class:<br />
<blockquote><pre><code>(defclass person ()
((first-name :initarg :first-name)
(last-name :initarg :last-name)
(state :initarg :state)))
</code></pre></blockquote>all we have to do is swap <code>plist</code> with the class name <code>person</code> and we're all set:<br />
<blockquote><pre><code>(remove-if-not (lambda-match ((<strong>person</strong> :first-name "Zach" :state "ME"
:last-name (not "Beane")) t))
*people*)
</code></pre></blockquote><br />
We can't quite define something exactly like Zach's <code>query-plists</code> because, AFAICT, optima's patterns are not first-class objects but perhaps we can cheat a little bit.<br />
<blockquote><pre><code>;; naming things is hard. :-/
(defmacro matchp (pattern) `(lambda-match (,pattern t)))
(defun filter (predicate list) (remove-if-not predicate list))
(filter (matchp (plist :first-name "Zach" :state "ME"
:last-name (not "Beane")))
*people*)
</code></pre></blockquote><br />
Making this equally succinct when the query criteria are not constant is a challenge for another day and makes it clear that <code>matchp</code> is a lousy abstraction. ;-)Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com1tag:blogger.com,1999:blog-23326860.post-83126941621282437862016-02-03T00:51:00.001+00:002016-02-03T00:56:41.000+00:00slime-macrostepSLIME's just got a new contrib called <code>slime-macrostep</code>, courtesy of <a href="https://github.com/joddie">Jon Oddie</a> who also wrote the underlying <a href="https://github.com/joddie/macrostep">macrostep</a> package.<br />
<br />
And what is <code>slime-macrostep</code>? It's an interactive inline macro-expander. Have a look:<br />
<br />
<div style="text-align: center"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhApTjRNs214Q-YxiV75AOAhgjID_gH9EtxZme7m60IgR5TAMtR_PWNcRCWTmXlFcutT_e25Vdhsr2KEoGnHzf2BWeRTSM9Z_6oUsmPl-NnyxFpoZoaPUwFEuSmdoX4dgOrLxKn9A/s1600/macrostep-demo.gif" /></div><br />
In this quick demo, using a <a href="http://common-lisp.net/project/cffi">CFFI</a> example, I start by expanding the top-level <code>WITH-FOREIGN-OBJECT</code> form, then I expand the <code>WITH-ALIEN</code> form, but regret it and collapse it back. Then I proceed to expand everything else, including compiler macros!<br />
<br />
A nice feature of <code>slime-macrostep</code> is that the expansions are annotated to show which forms are further expandable and <code>macrostep-expand</code> will jump automatically to the next expandable form. That's what makes it a stepper: pressing <kbd>e</kbd> repeadly will step through the macroexpansion. Plus, it expands macrolets!<br />
<br />
If you'd like to try it out, please grab SLIME's bleeding edge (<a href="https://github.com/slime/slime#quick-setup-instructions">via MELPA or Git</a>). It's enabled by default if you use the <code>slime-fancy</code> meta contrib. Feedback is most welcome.Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-44591292058438666702016-01-04T11:18:00.001+00:002016-01-04T11:23:24.869+00:00Common Lisp Recipes: A Problem-Solution ApproachEdi Weitz, author of things like <a href="http://weitz.de/cl-ppcre/">CL-PPCRE</a> and <a href="http://weitz.de/hunchentoot/">Hunchentoot</a> (amongst many other pieces of <a href="http://weitz.de/lisp.html"><em>ediware</em></a>), has just published a new book, <a href="http://weitz.de/cl-recipes/">“Common Lisp Recipes: A Problem-Solution Approach”</a>. I've ordered mine. Get yours from <a href="http://www.apress.com/9781484211779">Apress</a> or a <a href="https://www.curiua.com/dp/1484211774">European Amazon store</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlkIvRm1Yo3DjXUSkoJ_KG-NkxE7quAzpdZAzjxFfdzYeAKS4dNvCW-s4wBv7c2p5iL1Sh_hsoHKgaz9qOFR8213ZNX_bmKf6Bt462YIkEnZVOaF471IaRte9AHoebqocmT64cEw/s1600/7177Nn51w5L.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlkIvRm1Yo3DjXUSkoJ_KG-NkxE7quAzpdZAzjxFfdzYeAKS4dNvCW-s4wBv7c2p5iL1Sh_hsoHKgaz9qOFR8213ZNX_bmKf6Bt462YIkEnZVOaF471IaRte9AHoebqocmT64cEw/s320/7177Nn51w5L.jpg" /></a></div><br />
<blockquote><p><em>Common Lisp Recipes is a collection of solutions to problems and answers to questions you are likely to encounter when writing real-world applications in Common Lisp. Written by an author who has used Common Lisp in many successful commercial projects over more than a decade, this book is the first Common Lisp book which covers areas as diverse as web programming, databases, graphical user interfaces, communication with other programming languages, multi-processing, and mobile devices as well as debugging techniques and optimization, to name just a few. It is organized around specific problems or questions each followed by ready-to-use example solutions and clear explanations of the concepts involved, plus pointers to alternatives and more information. Each recipe can be read independently of the others and thus the book will hopefully earn a special place on your bookshelf as a reference work you always want to have within reach.</em></p><p><em>Common Lisp Recipes is aimed at programmers who are already familiar with Common Lisp to a certain extent but do not yet have the experience you typically only get from years of hacking in a specific computer language. It is written in a style that mixes hands-on no-frills pragmatism with precise information and prudent mentorship.</em></p><p><em>If you feel attracted to Common Lisp's mix of breathtaking features and down-to-earth utilitarianism, you'll also like this book.</em></p></blockquote>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2tag:blogger.com,1999:blog-23326860.post-40541017906177486972015-05-30T17:06:00.000+01:002016-02-03T17:14:42.733+00:00My answer to the Pretty Printer PuzzleAs promised, I'll describe my solution to the <a href="http://kvardek-du.kerno.org/2015/05/pretty-printer-puzzle.html">Pretty Printer Puzzle</a> I proposed last week. To recap, we wish to pretty print a Lisp form to a string and identify the textual positions of arbitrary subforms therein. <br />
<br />
<h3>First attempt</h3>A couple of folks proposed a clever solution that goes like this: (1) replace the <code>CAR</code> of each subform with some unique token (a gensym should be close enough), (2) pretty-print that, (3) find the token positions and replace them with the original <code>CAR</code>s.<br />
<br />
Problem with this solution: changing the form affects pretty-printing. In particular, it will no longer be able to properly indent macros and special forms.<br />
<br />
<h3>Second attempt</h3>Another approach is to pretty-print then read the form back and track positions by either using a custom reader that keeps track of form positions (such as <a href="http://hub.darcs.net/hu.dwim/hu.dwim.reader">hu.dwim.reader</a>) or instrumenting the standard readtable by <a href="https://github.com/sbcl/sbcl/blob/master/contrib/sb-cover/cover.lisp#L459" title="like this, for example">wrapping the <code>#\(</code> reader-macro</a> and doing the reading from a so-called <a href="https://github.com/sbcl/sbcl/blob/399c6f8dee7b07c8c0a17510ed78411672cba2f9/src/code/fd-stream.lisp#L197">form-tracking-stream</a>.<br />
<br />
Problem with this solution: it breaks down if the form contains unreadable objects.<br />
<br />
<h3>Third attempt, getting closer</h3>The pretty printer is customisable through a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/22_bad.htm">pprint-disptach-table</a>. It is analogous to the reader's <code><a href="http://www.lispworks.com/documentation/lw51/CLHS/Body/t_rdtabl.htm">readtable</a></code>. So, we try and <a href="https://gist.github.com/luismbo/edbff74733812f57c5d9#file-tracking-string-output-stream-lisp">instrument it</a> like in the previous approach. Each time a list is about to be pretty-printed, we store the current position in the output stream.<br />
<br />
Problem: we have been defeated by the pretty printer's intermediate buffer. Turns out the pretty printer only writes to the output stream at the very end of the process. Back to the drawing board.<br />
<br />
<h3>Fourth and final attempt</h3>But these attempts have not been in vain, and my final solution involves elements from all three. It goes like this:<br />
<ol><li>Pretty print the form normally.</li>
<li>Pretty print the form again, this time instrumenting the <code>pprint-dispatch-table</code> to wrap lists with some token identifying the subform being printed. (I decided to use the unicode range <code>U+E000..U+F8FF</code> which is reserved for private-use, which seemed neat.) This messes up the pretty-printing a little bit, but not too much, it turns out.</li>
<li>Cross-reference the token positions in #2 with #1 by taking advantage of the fact these outputs differ by whitespace (and tokens) only!</li>
</ol><br />
And that's it!<br />
<br />
With this tool in hand, there are some interesting utilities that can be built in SLIME, but that's <a href="http://kvardek-du.kerno.org/2016/02/slime-macrostep.html">another blog post</a>. :-)Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-3632590206819515872015-05-24T15:20:00.001+01:002015-05-26T01:04:17.163+01:00Pretty printer puzzleThis past week, I came across a Lisp challenge that turned out to be trickier than one might expect at first. I needed to pretty-print a Lisp form to a string and identify the positions of certain subforms. Here's an example:<br />
<blockquote><pre><code>CL-USER> (with-output-to-string (*standard-output*)
(pprint '(defun factorial (x) (if (zerop x) 1 (* x (factorial (1- x)))))))
"
(DEFUN FACTORIAL (X)
(IF (ZEROP X)
1
(* X (FACTORIAL (1- X)))))"
</code></pre></blockquote>In this, output the <a href="http://www.lispworks.com/documentation/lw50/CLHS/Body/26_glo_b.htm#bounding_index">bounding indices</a> of the <code>IF</code> form are 24 and 77. In other words:<br />
<blockquote><pre><code>CL-USER> (subseq * 24 77)
"(IF (ZEROP X)
1
(* X (FACTORIAL (1- X))))"
</code></pre></blockquote>The challenge, then, is to write a function that, given a form and list of subforms, returns a string with the pretty-printed output and a list of bounding indices for each subform. E.g.<br />
<blockquote><pre><code>CL-USER> (pprinted-bounds '(defun factorial (x) #1=(if (zerop x) 1 (* x #2=(factorial (1- x)))))
(list '#1# '#2#))
"
(DEFUN FACTORIAL (X)
(IF (ZEROP X)
1
(* X (FACTORIAL (1- X)))))"
((24 77) (57 75))
</code></pre></blockquote>I'll post my solution later. Have fun. :-)Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2tag:blogger.com,1999:blog-23326860.post-17727337715741786582014-12-19T18:27:00.000+00:002014-12-20T00:08:06.032+00:00LOOP quiz<ol><li>Does <code>(loop for i below 10 finally (return i))</code> return 9 or 10?<br />
</li>
<li>Does <code>(loop for i upto 10 finally (return i))</code> return 10 or 11?<br />
</li>
<li>What does <code>(loop for i below 10 for j upto 10 finally (return (list i j)))</code> return?<br />
</li>
<li>What about <code>(loop for i below 10 <strong>and</strong> j upto 10 finally (return (list i j)))</code>?</li>
</ol><br />
I stumbled upon the semantics of this last example <a href="https://github.com/cl-babel/babel/commit/c53ee13b19e5a3184c106aff88b38871204e88ad?diff=split">in a recent bugfix</a> and thought it was worth sharing. (Reminded me of <a href="http://martinfowler.com/bliki/TwoHardThings.html">the joke about what's hard in CS</a>, too.)<br />
<br />
Turns out <code>LOOP</code>'s <code>FOR ... AND</code> not only mimics <code>LET</code> (rather than <code>LET*</code>) in terms of binding visibility, it also influences when the loop termination checks take place. That was new to me. I initially expected examples 3 and 4 to return the same values. What about you? Which ones, if any, did you get wrong? :-)<br />
<br />
P.S.: <a href="http://www.gigamonkeys.com/book/loop-for-black-belts.html">LOOP for Black Belts</a> is my favorite LOOP tutorial.Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com5tag:blogger.com,1999:blog-23326860.post-38369142463924256332014-12-11T21:20:00.000+00:002015-05-31T16:21:10.408+01:00pareditTaylor Campbell's <a href="http://emacswiki.org/ParEdit">paredit</a> is one of those Emacs extensions that I can't live without. In a nutshell, it forces you to deal with Lisp code exclusively via operations that don't introduce unbalanced parenthesis (or other similar violations of structure). The genius about this approach is that it completely eliminates the step of making sure parentheses are properly balanced after you write or edit a piece of code. After you get used to paredit, performing — or even watching — manual parenthesis balancing becomes painful.<br />
<br />
Recently, I've come across these two introductions to paredit:<br />
<ol><li><a href="http://emacsrocks.com/e14.html">Emacs Rocks! Episode 14: Paredit</a></li>
<li><a href="http://danmidwood.com/content/2014/11/21/animated-paredit.html">The Animated Guide to Paredit</a></li>
</ol>So, if you're still not using paredit, have a look at those and give it a try. At first you might feel like the karate kid doing frustrating chores — you can always take a break with <kbd>M-x paredit-mode</kbd> — but I promise it'll soon pay off!<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7Uut8pPI67KAvM3schGsTR5ght8DEtgqNQ0AmSuFXznERIhOVMn16cyLw__Ue27N_GxP49R6BntnWRO_G9zmVHGv6rDcHZRJzp-lEasV4j-IBdUqVwIzfSZyIkoPJm1vT2IfZRA/s1600/tumblr_m7k3xbemnG1qg4blro1_500.gif"/></div>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-63660714111835635932014-12-01T12:04:00.000+00:002014-12-01T18:15:56.731+00:00SLIME officially available via MELPASLIME has been <a href="http://melpa.org/#/slime">available from MELPA</a> for a while, but only recently did we iron out some annoying bugs. Notably, upgrading the SLIME package no longer results in confusion about where SWANK is.<br />
<br />
So, as of SLIME 2.11, once you have the <a href="http://melpa.org">melpa</a> (or <a href="http://stable.melpa.org">melpa stable</a>) repository set up, installing and updating SLIME from within Emacs is pretty easy:<br />
<pre> M-x package-install RET slime RET</pre>Enjoy!<br />
<br />
<strong>Update:</strong> Oh, if you want to switch to MELPA, make sure you remove your old SLIME location from Emacs's <code>load-path</code>, otherwise the old version will take precedence.<br />
<br />
<div style="text-align:center"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1YcUvwAdGQKuW4-O4km1ToBRKHgDLcXIo6HjsV4VxN7BpU6pRKsoFQRK4UnDVrEQG2B5NhJi4Z1QmXe2bNwuv32LM0zeNHE3cAXxeESim2m9hC6iJpDMenb0IIpMN4j9Eeki9Qg/s1600/package-install-slime.gif" /></div>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2tag:blogger.com,1999:blog-23326860.post-27335999972531651802014-11-28T22:04:00.000+00:002014-11-28T22:09:03.842+00:00(cons cat (cons cat nil))<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwFGsoF-WX9Y7PKFF97e__EaQvf-ahMdaUbCN8C1grKF3LG9B86S_wR-ahzVnEmcENawDvpOJSXEmCC-jwdMx90rdO4id06vrv5pUJKif7OlkrDgqTTc5iSP8bNjgcaBw0MZG20Q/s1600/unnamed.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwFGsoF-WX9Y7PKFF97e__EaQvf-ahMdaUbCN8C1grKF3LG9B86S_wR-ahzVnEmcENawDvpOJSXEmCC-jwdMx90rdO4id06vrv5pUJKif7OlkrDgqTTc5iSP8bNjgcaBw0MZG20Q/s400/unnamed.jpg" /></a><br />
<br />
I thought <a href="https://twitter.com/lvsn/status/533685461957349376">this tweet</a> was pretty funny, despite the diagrammatic inaccuracy that twitterers were quick to point out. :-) Reminds me of <a href="http://catrapum.kerno.org/image/9848612617">my second cat</a>, whom I named CADR, of course.Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com4tag:blogger.com,1999:blog-23326860.post-77073837534009249762014-03-02T14:40:00.003+00:002014-03-02T18:13:22.653+00:00SLIME 2.4<a href="https://github.com/slime/slime/releases/tag/v2.4">SLIME 2.4 has been released</a> without any <a href="http://christophe.rhodes.io/notes/blog/posts/2014/sbcl_release_management_in_the_air/">exciting release management</a>, but with <a href="https://raw.github.com/slime/slime/v2.4/NEWS">extensive release notes</a>! :-)<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiIclVT1PFJXJNWyIfF_25kB2W6I6DSKcuI_G2uvNwD8mrfhTks5Tpsd27mzDTVnoevuKa_ol7Q9uA_I8K8LlfFLeH43YNAsTNtdrYWlaIzniM7DrX9jotTqQnCbxYFM0ugrAJiA/s1600/slime-connected.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiIclVT1PFJXJNWyIfF_25kB2W6I6DSKcuI_G2uvNwD8mrfhTks5Tpsd27mzDTVnoevuKa_ol7Q9uA_I8K8LlfFLeH43YNAsTNtdrYWlaIzniM7DrX9jotTqQnCbxYFM0ugrAJiA/s1600/slime-connected.png" /></a></div>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-85209749475782259972014-02-23T16:40:00.000+00:002014-02-23T17:56:06.888+00:00Call for SLIME testersAs you may have heard, SLIME's recently moved to GitHub where, for the last 3 months or so, code has been refactored, bugs have been fixed and some new features have been introduced.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/slime/slime/graphs/commit-activity" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" alt="SLIME's commit activity over the last 12 months" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6JrN6HHA9fJQ4fKs01DRrUPuHv2T-KhEMbnFhBye5pZXVMAj2P6cqDXZl_4Nzp4yYIBUtrNN3xfRgEqy593HAwSnnRx4ayr0E8eihL0nZSWi7NVLK4u3GPpj0Cj4oLel-_VN8tw/s1600/slime-activity.png" /></a></div><br />
The last SLIME release has a very long beard, so we'd like to make a new one next weekend. To make it a good release, it'd be very really helpful if fellow SLIME users grabbed <a href="https://github.com/slime/slime">the latest code from github</a> (via either git or the ZIP download link), took it for a spin and, if need be, used the <a href="https://github.com/slime/slime/issues">issue tracker</a> to report issues that may pop up.<br />
<br />
Thanks!Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-6068178479065573392013-11-21T12:13:00.000+00:002013-11-22T16:20:32.680+00:00SISCOG's ECLM 2013 slides (finally) up<div class="separator" style="float: right; clear: both; text-align: center;"><a href="http://www.siscog.eu/upload/GESTAO-DE-LISTAS/News/PDF/eclm-2013-siscog-a-story-written-in-lisp-20130602.pdf" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img style="border-style:solid;
border-width:1px;" border="1" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOmNN2f5LwAFuurFyFGZcfk2vzNYDvYNgDkk5S8WfIz6wfNyUjs7qus2dbKrMzCVWe84a3QfweR_g8Bw1eEwjKvV50joueYKbkbP49ZK2neyUCcHClBKZRT875rdO2yL4pkeTtEw/s400/presentation.png" /></a></div><br />
It took a while, but our <a href="http://weitz.de/eclm2013">ECLM 2013</a> slides “<a href="http://www.siscog.eu/upload/GESTAO-DE-LISTAS/News/PDF/eclm-2013-siscog-a-story-written-in-lisp-20130602.pdf">SISCOG: a story written in Lisp</a>” have been published. Incidentally, they are also featured in Franz's <a href="http://www.franz.com/success/customer_apps/scheduling/siscog.lhtml">ACL Success Stories</a>, yay.<br />
<br />
On a related note, Vsevolod Dyomkin published his <a href="http://www.youtube.com/playlist?list=PLyKekftcIioT995qDMGO8TtSLIz25lhGd">video recordings</a> of the meeting. Sadly, we didn't get permission to publish our video.<br />
<br />
Finally, <a href="http://www.siscog.eu/list_detail.asp?idArea=3&idList=7&idListDetail=506">SISCOG is hiring</a> and has open positions for Software Engineers and Operations Research Analysts that require C++ programming, which is rather ironic and anti-climatic for this blog post. :-)<br />
Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-56517391088105780602013-06-06T11:46:00.001+01:002013-06-06T19:27:28.000+01:00ECLM 2013Another odd year, another <a href="http://weitz.de/eclm2013/">ECLM</a>. This time around in sunny Madrid at the posh <a href="https://plus.google.com/114180786369307770957/photos?hl=en">TRYP Ambassador</a> within walking distance from Teatro Real and Plaza Mayor. 63 people from 20 countries turned up.<br />
<br />
On <strong>Saturday</strong> I failed to meet some other lispers for lunch. Apparently, there's two or three Museos del Jamón around Plaza Mayor and I stood for 20 minutes in front of the wrong one. Took the afternoon to tweak my slides. Dinner was nice for catching up with familiar faces from past meetings. Met some new lispers as well. Some of us went for a quick drink at <a href="http://www.mercadodesanmiguel.es/">Mercado de San Miguel</a> afterwards.<br />
<br />
<strong>Sunday</strong> started off with a visibly jet lagged <strong>Wes Henderson</strong> talking about <a href="http://wukix.com/mocl">mocl</a>, a Lisp-to-C compiler with two backends tailored for the iPhone and Android environments. Despite the jet lag, he was quite eloquent! mocl makes it trivial to call Lisp from Java/ObjC:<br />
<br />
<pre> (declaim (call-in foo)) ; declares FOO can be called from foreign land
(defun foo (x)
(format t "~a~%" x))
</pre><br />
After compiling this function, it will be available from the ObjC or Java environments. I didn't quite figure out how mocl deals with the mismatch between static and dynamic typing, but apparently that's taken care of. Note that the goal is for mocl to be embedded in Android/Java or iOS/ObjC applications. I.e., you'll be writing your GUIs in Java/ObjC and call out to Lisp for the remaining bits. I don't recall anything being mentioned about calling Java/ObjC from the Lisp side.<br />
<br />
I enjoyed his thought out justification of why Common Lisp is a good match for mobile applications. First off, CL has a stable specification and a rich ecosystem with many alternative implementations. That means that, if he follows the spec, our existing code (namely libraries) will work as is. Secondly, CL is fast and that's important for resource-constrained mobile devices. (What does it mean for a language to be fast? I guess it means that there are plenty of implementations around that show how its semantics can be implemented efficiently.) Thirdly, the CL ecosystem has a relatively reduced dependency on foreign libraries which may or may not work on mobile environments. I was convinced. :-)<br />
<br />
Wes took the opportunity to announce that mocl will be released at 3581000000 lisp universal time. (That's from memory, I hope I got it right.)<br />
<br />
<strong>Michael Eisfeld</strong> presented <a href="http://www.coned.de/">ConED</a>, an application to help engineers design the first stages of building structures.<br />
<br />
<p style="text-align: center"><img src="http://www.coned.de/uploads/tx_e3pslideshow/step5.png" /></p><br />
There weren't many lispy details, but the application seemed quite useful and interesting. I'm told this is a hard market to get into, so best of luck to Michael and his team!<br />
<br />
<strong>Michael Compton</strong> talked about Accenture's digital optimisation software, <a href="http://marketingsoftware.accenture.com/en-US/Products/Marketing-Software/Software-Products/Accenture-Digital-Optimization.aspx">ADO</a>. In a nutshell, ADO will feed various versions of a webpage to users and cleverly measure which ones work best. I didn't understand most of what was discussed, but apparently they're market leaders.<br />
<br />
Then, <strong>Tiago Maduro Dias</strong> and I talked about the company where we work, <a href="http://www.siscog.pt">SISCOG</a>. Tiago presented SISCOG's history, problem domain and products and I tried to illustrate some interesting ways how we use Lisp. Thanks to Murphy's law, projector woes took up a fair chunk of our allotted time and I had to compress 25 minutes of talk into 15 or so. In the end, I think it went OK and the feedback was pretty positive. SISCOG is a 27 year old company with a rich Lisp history (going back to the Lisp Machines!) and it's quite successful in its market: resource planning, management and optimisation for railway companies. Oh, and we have about 70 full-time lispers.<br />
<br />
<em>Tapas</em> for lunch.<br />
<br />
After lunch, <strong>R. Matthew Emerson</strong> (rme) talked about Clozure CL's Objective-C bridge. I enjoyed his presentation style, and there were plenty of demos, which is nice. I had heard about CCL's IDE before, but this was the first time I got to see it.<br />
<br />
<strong>Janusz Podrazik</strong> then demoed <a href="http://opusmodus.com/">Opusmodus</a>, written using CCL and the aforementioned ObjC bridge, which looked quite slick! It felt a bit like an Emacs-inspired IDE for writing music with lots of pretty graphs and visualizations. Plus, it lets you write music using Lisp! IIUC, the coding was done by rme who did a very fine job! Looking forward to its release this coming September.<br />
<br />
<p style="text-align: center"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicO1RAV4xPOx9Fm-9xBhLK_MWt4i5zVURSEYTDiO4noXCa7x6q9XcKcCLf7Ihk3xtlJDjx9PtymZkNEJ5EGkmTALKqiEohAi-xb0UUi3JXbi9iCB-LFXSoewYN2Kmx8bIWuHP7oQ/s1600/omn10.png" /></p><br />
<strong>Erik Huelsmann</strong> (ehu) talked about <a href="http://abcl.org/">ABCL</a>, whose version <a href="http://article.gmane.org/gmane.editors.j.devel/5515">1.2.0 RC</a> had been released that morning from the venue. He basically talked about the latest developments and how ABCL is being used out there (including an application of his). I liked how the ABCL developers are using cl-test-grid to assess ABCL's compatibility with major libraries and how Quicklisp's download statistics helps them prioritise bug fixing.<br />
<br />
<strong>Sven Emtell</strong> demoed <a href="http://scorecleaner.com/">ScoreCleaner</a>. (I don't recall exactly which bits were written in Common Lisp. It was a very polyglot product, IIRC.) He showed nicely done marketing videos, such as <a href="http://www.youtube.com/watch?&v=nl9uxZefWdY">this one</a>.<br />
<br />
At dinner, Faré tried to explain to me what Interface Passing Style was all about and how he used it in his <a href="http://common-lisp.net/~frideau/lil-ilc2012/lil-ilc2012.html">Lisp Interface Library</a>. He almost succeeded!<br />
<br />
There were lightning talks throughout the day. Here are the ones I remember. <strong>Mark Evenson</strong> presented a very clear explanation of what went wrong with the latest <a href="http://common-lisp.net">common-lisp.net</a> migration and how he and other folks plan to fix outstanding issues and generally improve how the logistics of this service are managed. <strong>Nick Levine</strong> talked about <a href="http://www.ravenbrook.com/">Ravenbrook</a>. <strong>Christophe Rhodes</strong> released <a href="http://www.sbcl.org/news.html#1.1.8">SBCL 1.1.8</a> live.<br />
<br />
All in all, I think this was the best ECLM yet. Lots of cool applications and a vibrant community. Looking forward to the next one!Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com4tag:blogger.com,1999:blog-23326860.post-73226253527340187382013-03-18T00:46:00.000+00:002013-03-18T00:48:28.095+00:00Kálmán Réti on Lisp Machines<p>An interesting video popped up on the <a href="http://www.reddit.com/r/lisp/comments/1a24aj/kalman_reti_the_last_symbolics_developer_speaks/">Lisp Reddit</a> last week: <a href="http://www.loper-os.org/?p=932">Kálmán Réti, the Last Symbolics Developer, Speaks of Lisp Machines</a>. The first half goes into satisfyingly low-level detail about the Lisp Machine's history and architecture, and the second half contains the most in-depth demo I recall watching. Enjoy.</p><iframe src="https://docs.google.com/file/d/0Bw4Wz8Ir0pl1cmNRaHYwdU1wdXM/preview" width="640" height="385"></iframe>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-80345437451218365042013-03-09T18:55:00.000+00:002013-03-09T21:23:13.630+00:00CFFI 0.11.0 releasedCFFI 0.11.0 has been released on Feb 25th, 2013, but I only finished writing the release notes today:<br />
<ul><li><em>new feature:</em> <a href="http://repo.or.cz/w/fsbv.git">fsbv</a> has been integrated into CFFI, courtesy of Liam Healy. This means we now support passing structs by value via [libffi](http://sourceware.org/libffi/)! <strong>NB:</strong> in order to differentiate between structure passing by value from structure by reference, <code>(:struct foo)</code> and <code>:pointer</code> should be used. The old way of referring to struct types by bare name is now deprecated.</li>
<li><em>new feature:</em> a new MKCL backend has been added courtesy of Jean-Claude Beaudoin.</li>
<li><em>enhancement:</em> the ABCL backend has improved considerably thanks to Mark Evenson and Stas Boukarev.</li>
<li><em>enhancement:</em> the ECL backend now supports multiple linking strategies thanks to Juanjo Garcia-Ripoll.</li>
<li><em>optimization:</em> <code>foreign-free</code> is non-consing on SBCL. (Thanks to Stas Boukarev.)</li>
<li><em>bugfix:</em> in some situations we were not signalling a warning upon defining a foreign type using a symbol from the <code>:cl</code> or <code>:keyword</code> packages. Because of this, some projects will see new compilation warnings that will require fixing.</li>
<li>and various other bugfixes.</li>
</ul>This version will be included in the next Quicklisp dist.Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-50658684331536570352012-06-06T02:59:00.000+01:002012-06-10T01:47:20.075+01:00Augmenting bordeaux-threads with atomic operations<p><a href="http://common-lisp.net/project/bordeaux-threads/">Bordeaux-threads</a> is a portability layer that defines a low-level API for programming shared-state concurrency: basic thread management, locks, timeouts, and condition variables. It has been ported to plenty of CL implementations: ABCL, Allegro CL, CLISP, Clozure CL, CMUCL, Corman Lisp, ECL, Lispworks, MCL, SBCL, and SCL. As such, it's an ubiquitous building block for useful higher-level libraries such as <a href="http://lparallel.org/">lparallel</a>, <a href="http://marijnhaverbeke.nl/pcall/">PCall</a>, <a href="http://common-lisp.net/project/cl-stm/">CL-STM</a>, and <a href="http://www.cliki.net/concurrency">many others</a>.</p><p>One important piece missing from bordeaux-threads is the support for atomic operations such as <a href="http://en.wikipedia.org/wiki/Compare-and-swap">compare-and-swap</a>, <a href="http://en.wikipedia.org/wiki/Fetch-and-add">fetch-and-add</a>, atomic-swap, <a href="http://en.wikipedia.org/wiki/Atomic_(computer_science)">etc</a>. Among other things, these operations are useful for implementing scalable, efficient lock-free or wait-free algorithms and data-structures. The availability of such data-structures in a portable fashion would benefit many of the higher-level libraries that use bordeaux-threads. (E.g.: lparallel, when running on SBCL, takes advantage of the lock-free queues provided by that implementation.)</p><p>Back when bordeaux-threads was created, virtually no CL implementation supported these operations.<sup><a name="ref-20120607-1" href="#footnote-20120607-1">1</a></sup> Nowadays, though, more and more implementations support at least a subset thereof. What follows is a survey of that support in modern CL implementations, a necessary first step to add an atomic operation API to bordeaux-threads.</p><br />
<h3>compare-and-swap</h3><p>I'll start with compare-and-swap (CAS), which is the most powerful of the atomic operators we'll be looking into, and consequently the most widely supported in CL implementations. Typically, this operation is syntactically similar to <code>SETF</code> but is restricted to a handful of CL <em>places</em>:</p><ul><li><code>SLOT-VALUE</code>.</li>
<li><code>SYMBOL-VALUE</code>, i.e. the value of a dynamic variable.</li>
<li>The global value of a dynamic variable, a common extension to standard CL.</li>
<li>Structure accessors.</li>
<li><code>CAR</code> and <code>CDR</code>.</li>
<li><code>SYMBOL-PLIST</code>.</li>
<li><code>SVREF</code>.</li>
<li>MOP's <code>STANDARD-INSTANCE-ACCESS</code> and <code>FUNCALLABLE-STANDARD-INSTANCE-ACCESS</code>.</li>
</ul><br />
<table border=1 cellpadding=5 align="center"><caption>Table 1. CAS support per place.</caption><tbody> <!-- Results table headers -->
<tr> <th></th> <th><abbr title="slot-value">slotval</abbr></th> <th><abbr title="symbol-value">symval</abbr></th> <th><abbr title="global-symbol-value">gsymval</abbr></th> <th><abbr title="defstruct-defined accessor">structslot</abbr></th> <th>car/cdr</th> <th><abbr title="symbol-plist">symplist</abbr></th> <th>svref</th> <th>mop</th></tr>
<tr> <td>ACL 9.0b</td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td></tr>
<tr> <td>CCL 1.7</td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td></tr>
<tr> <td>LW 6.0</td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td></tr>
<tr> <td>SBCL 1.0.54</td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td></tr>
<tr> <td>SCL 1.3</td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: green">✔</span></td> <td align="center"><span style="color: red">✖</span></td></tr>
</tbody> </table><br />
<p><em>(2012-06-07 update: fixed table to correctly reflect the fact that SCL does support <code>SYMBOL-GLOBAL-VALUE</code> as a CAS place.)</em></p><p><em>(2012-06-10 update: Nikodemus wrote in to point out that <code>(cas (symbol-value '*foo*) ...)</code> on SBCL modifies the special variable's global value rather than its dynamic binding. Fixed table accordingly.)</em><br />
<p>As far as I can tell, ABCL, CMUCL and ECL don't yet have any support for atomic operations. I didn't check MCL or Corman Lisp. Also, note that CCL's CAS — <code>ccl::conditional-store</code> — is in fact an unexported interface. All in all, the feature overlap amongst the Lisps that better support CAS (ACL, LW, SBCL, SCL) is not too bad.</p><p><strong>Conclusion:</strong> bordeaux-threads should support CAS for <code>SLOT-VALUE</code>, <code>CAR/CDR</code>, structure accessors, and <code>SVREF</code> on ACL, LW, SBCL, and SCL. The other partially supported places could perhaps be supported where possible but with a compile-time style warning about their unportability; haven't decided yet whether this would be worth the trouble.</p><br />
<h3>fetch-and-add</h3><p>A concrete implementation of fetch-and-add is the x86 <code>LOCK</code>-prefixed <code>XADD</code> instruction. It atomically increments an integer using word-sized modular arithmetic, i.e. the addition can overflow and the result wraps.</p><p>SBCL has <code>ATOMIC-INCF</code> whose name is slightly misleading because it is pretty much a direct interface to the aforementioned <code>XADD</code> instruction (on x86, of course), and thus only works on word-sized places: structure slots with type <code>SB-EXT:WORD</code> or simple arrays with element-type <code>SB-EXT:WORD</code>.</p><p>Lispworks on the other hand, provides <code>ATOMIC-FIXNUM-INCF</code>. Although it also boils down to <code>XADD</code> and the addition will overflow, it works on all the same places as CAS since it handles plain fixnums.</p><p><strong>Conclusion:</strong> bordeaux-threads can define <code>ATOMIC-WORD-INCF</code> and <code>ATOMIC-FIXNUM-INCF</code>, support those operations efficiently on SBCL and LW respectively, and emulate them on other Lisps using CAS.</p><br />
<h3>atomic-swap</h3><p>Only Lispworks provides this functionality (via <code>ATOMIC-EXCHANGE</code>). Not yet sure whether it's sensible to emulate this using CAS on other Lisps.</p><br />
<h3>Coming next</h3><p>Having surveyed the support for atomic operations, we'll proceed to define a useful interface and some slightly higher-level utilities around CAS. There's plenty of inspiration to be found in the various implementations and we should be able to draw various ideas from each.</p><p>(P.S.: hopefully this doesn't overlap too much with Nikodemus's <a href="http://random-state.net/log/3522216438.html">MADEIRA</a> efforts.)</p><br />
<p style="font-size: smaller"><sup><a href="#ref-20120607-1" name="footnote-20120607-1">1</a></sup> (2012-06-07 update) I hadn't realized this until Douglas Crosher wrote in to set some facts straight: turns out SCL has supported SMP (including compare-and-swap) for nearly a decade!</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com8tag:blogger.com,1999:blog-23326860.post-9188495205576933112011-12-09T09:39:00.001+00:002011-12-09T15:07:10.923+00:00Setting up CommonQt on OSX<p><a href="http://common-lisp.net/project/commonqt/">CommonQt</a> can be tricky to setup due to its dependencies from C++ land. Tricky enough to warrant writing down the steps I went through to get it running on Mac OS 10.7:</p>
<ol>
<li><p>If you don't already have <a href="http://developer.apple.com/xcode/">Xcode</a>, install it because you'll need <code>g++</code>.</p></li>
<li><p>Grab and install the <a href="http://qt.nokia.com/downloads/downloads#qt-lib">Qt Libraries</a> (<em><strong>not</strong></em> the Qt SDK). I used version 4.7.4.</p></li>
<li><p>Install <code>CMake</code>. (I used <code><a href="http://mxcl.github.com/homebrew/">brew</a> install cmake</code>.)
<li><p>Download, compile and install the <a href="https://projects.kde.org/projects/kde/kdebindings/smoke">SMOKE</a> library:</p>
<pre>
$ git clone git://anongit.kde.org/smokegen
$ cd smokegen
$ cmake .
$ make install
$ cd ..
$ git clone git://anongit.kde.org/smokeqt
$ cd smokeqt
$ cmake -DSmoke_DIR="$PWD/../smokegen/cmake" .
$ make install
</pre>
<p>At this point, <code>smokephonon</code> failed to build so I had to manually install the two modules I actually needed:</p>
<pre>
$ make -C qtcore install
$ make -C qtgui install
</pre>
</li>
<li><p>Get an <a href="http://www.sbcl.org">SBCL</a> with threads enabled and <a href="http://www.quicklisp.org">Quicklisp</a>.</p></li>
<li><p>CommonQt needed a couple of tweaks for OSX and recent changes in SMOKE. While said changes aren't reviewed and integrated into the main repository, you can fetch them as follows:</p>
<pre>
$ cd ~/quicklisp/local-projects
$ git clone git://gitorious.org/~luismbo/commonqt/commonqt-luis.git
$ cd commonqt-luis
$ git checkout modular-smoke-and-osx-fixes
</pre>
</li>
<li>Start SBCL and <code>(ql:quickload :qt)</code>.</li>
</ol>
<p>Hopefully that went well. Next we'll try and run an application.
<ol>
<li>Enable the <code>swank-listener-hooks</code> contrib by adding <code>(slime-require 'swank-listener-hooks)</code> to your SLIME configuration.</li>
<li><code>(asdf:load-system :qt-tutorial)</code></li>
<li><code>(asdf:load-system :qt-repl)</code></li>
<li><code>(qt-repl:start-gui-thread)</code></li>
<li>And <em>finally</em>, <code>(qt-tutorial-14::test)</code>!</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwiz016g6JPJzxfLdabUXIakjHbClb_Blikq-97vyys7T-_sv1DSylpg77Qm-lMclcdL6jZDo_XumbISXluvKH8U1s65qIpsNaYfoU-ieSstfJHQQGTzZ6DXoHKS1ByCOA0nJBkQ/s1600/qt-tutorial.png" />
</div>
<p>If not running under SLIME, <code>(asdf:load-system :qt-tutorial)</code> followed by <code>(qt-tutorial-14:main)</code> would be sufficient.</p>
<p>If you want to try and skip the C++ compilation steps, grab <a href="http://common-lisp.net/~loliveira/tmp/commonqt-libs-20111209.tar.gz">this tarball</a> with <code>libcommonqt.dylib</code> and <code>libsmoke*.dylib</code>. You should place <code>libcommonqt.dylib</code> in CommonQt's source directory. The SMOKE libs go into <code>/usr/local/lib</code> or similar.</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com1tag:blogger.com,1999:blog-23326860.post-28763653937514648632011-11-16T23:20:00.004+00:002012-01-07T00:09:25.991+00:00TIME on steroids<p>
Nikodemus's <a href="http://random-state.net/log/3530433886.html">recent post</a> about a yet-to-be-released micro-benchmarking tool prompted me to talk about <a href="https://github.com/luismbo/perfpiece">Perfpiece</a>. I describe it as a tool for measuring the performance of Lisp code, not unlike the standard <code>CL:TIME</code> and I wrote over two years ago to measure the performance of SBCL's garbage collector.</p>
<h3>
Features</h3>
<p>
Here are its main features:</p>
<ul>
<li><p>
Lispy interface to <a href="http://icl.cs.utk.edu/papi/">PAPI</a> (Performance Application Programming Interface). PAPI is a library that enables access modern CPU’s hardware counters. This allows us to measure several events such as processor cycles, cache misses, number of floating-point instructions, and almost two hundred other events. Perfpiece dynamically inspects the current platform’s supported events at runtime and enables the user to inspect this list and measure these events. We also use this library to measure real (wall-clock) time and user (virtual) time.</p>
</li>
<li><p>
Support for other non-PAPI events such as the number of GC runs, CPU usage, and operating system resource usage (via the <code>getrusage()</code> system call).</p>
</li>
<li><p>
Transparent support for multi-threaded programs. It includes a helper C library that when loaded through the POSIX <code>LD_PRELOAD</code> mechanism will preempt pthread creation/termination calls and allow for the individual measurement of events across threads created during a measurement session. This includes both Lisp threads as well as threads created by C code. This is rather limited at the moment; only real/user/cpu time is measured for new threads.</p>
</li>
<li><p>
Segregation of measurements between mutator and GC.</p>
</li>
<li><p>
Support for sampling. Perfpiece can repeat a given a measurement a number of times then calculate and report basic statistic analysis: minimums, maximums, geometric means, and standard deviations for each measured event.</p>
</li>
</ul>
<h3>
Usage</h3>
<p>
The simplest way to interact with this library is through the <strong><code>ascertain</code></strong> macro, which works very much like <code>cl:time</code>. The following example shows the default events measured for a very simple arithmetic form:</p>
<blockquote><pre>PERFPIECE> (ascertain (+ 1 1))
non-GC GC Total
────────────────────────────────────────────────────────────────────────────
Total cycles: 8,343 0 8,343
Instructions completed: 481 0 481
Level 2 data cache misses: 78 0 78
Level 2 instruction cache misses: 24 0 24
GC count: - - 0
Involuntary context-switches: 0 0 0
Voluntary context-switches: 1 0 1
Page faults: 0 0 0
Page reclaims: 6 0 6
System time: 0 0 0
CPU usage: 100.00% - 100.00%
User time: 6.00 µs 0 6.00 µs
Real time: 613 ns 0 613 ns
0 new threads were spawned
2 ; printed result of (+ 1 1)
</pre></blockquote>
<p>
Having loaded the helper library using <code>LD_PRELOAD</code>, we can measure multi-threaded code:</p>
<blockquote><pre>PERFPIECE> (ascertain (loop repeat 2 do
(sb-thread:join-thread
(sb-thread:make-thread (lambda () (sleep 0.5)))))
:events '(:real-time :user-time :cpu-usage))
non-GC GC Total
────────────────────────────────────────────────────────────────────────────
CPU usage: 0.02% - 0.02%
User time: 206.00 µs 0 206.00 µs
Real time: 1.335 s 0 1.335 s
2 new threads were spawned
#0 real: 667.54 ms, user: 101.00 µs, cpu: 0.02%
#1 real: 667.60 ms, user: 144.00 µs, cpu: 0.02%
</pre></blockquote>
<p>
The other main function is <strong><code>sample</code></strong>. In the following example, we're measuring FP instructions, invoking some code 10 times, and aggregating measurements in several ways:</p>
<blockquote><pre>PERFPIECE> (sample (lambda () (* 2 pi)) :events '(:papi-fp-ins) :samples 10)
[Floating point instructions] Min Max Mean Stddev
──────────────────────────────────────────────────────────────────────────────
total: 35 36 35.60 ± 1.376%
non-gc: 35 36 35.60 ± 1.376%
gc-only: 0 0 0 ± 0.000%
</pre></blockquote>
<p>
<code>sample</code>'s got a <code>:report</code> keyword argument that you can use to get machine-readable results:</p>
<blockquote><pre>PERFPIECE> (sample (lambda () (* 2 pi)) :events '(:papi-fp-ins) :samples 10
:report nil)
((:PAPI-FP-INS :MIN (35 35 0)
:MAX (38 38 0)
:MEAN (184/5 184/5 0)
:STDDEV (1.0770329 1.0770329 0.0)))
</pre></blockquote>
<h3>Fork it!</h3>
<p>That's pretty much it. There is some SBCL-specific code, but it shouldn't be too hard to port to other implementations. Its use of PAPI could be made optional since that makes this library pretty much Linux-only otherwise. <a href="https://github.com/luismbo/perfpiece">Patches are most welcome!</a></p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2tag:blogger.com,1999:blog-23326860.post-61256346699451676982011-11-16T19:07:00.001+00:002011-11-16T19:09:31.528+00:00ECLM videos<p>Just a quick note: Vsevolod Dyomkin has posted a couple of <a href="http://blip.tv/eclm">ECLM 2011 videos</a> with more to come.</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-45177285811603463162011-10-25T09:18:00.007+01:002011-10-25T23:14:56.007+01:00ECLM 2011<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajpuKwE36JLRlz__iDiHdN1a0UtTCKKvpso7UHbTx6UUQCTia9RpdPuIklPMMMa1KV5TUJLNoDh78rVTx8t1FXV8dHvOp1fU5UYp1a2919xe-qagP2bzUnrTDa4N2aCz3zWwiKA/s1600/IMG_1142.JPG" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="300" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjajpuKwE36JLRlz__iDiHdN1a0UtTCKKvpso7UHbTx6UUQCTia9RpdPuIklPMMMa1KV5TUJLNoDh78rVTx8t1FXV8dHvOp1fU5UYp1a2919xe-qagP2bzUnrTDa4N2aCz3zWwiKA/s400/IMG_1142.JPG" /></a></div>
<p>Contrary to <a href="http://kvardek-du.kerno.org/2011/02/another-zslug-meeting-report.html">my expectations</a> earlier this year, <a href="http://weitz.de/eclm2011">ECLM 2011</a> happened and ~90 people turned up. Yay!</p>
<p>Saturday, a bunch of us went on a guided tour across Amsterdam. We had a great guide with an awesome sense of humor and this was a nice way to meet new Lispers and catching up with folks I'd met in past meetings.</p>
<p>Dinner was fun. One very prominent Lisper who shall remain anonymous didn't know what <a href="http://quicklisp.org/">Quicklisp</a> was. Everyone sitting at that particular table was shocked. :-)</p>
<p>Sunday started off with Nick Levine talking about learnt lessons from his failed attempt at writing a <a href="http://lisp-book.org/">Lisp book</a>. Midway through, he took the opportunity to rant a little bit about how there were at least 3 overlapping, incomplete websites (<a href="http://cliki.net">cliki</a>, <a href="http://common-lisp.net/">c-l.net</a>, <a href="http://cl-user.net">cl-user.net</a>) and how the solution would be to, huh, create yet another one. The consensus seems to be that cliki is the one that's best suited for a starting point, but Nick complains that its focus on Free Software Lisps is too narrow. Anyway, cliki could indeed use a revamp.</p>
<p>Jack Harper talked about using Lisp on <a href="http://www.secureoutcomes.net/">portable fingerprint scanners</a>. He had great things to say about <a href="http://www.lispworks.com/">Lispworks</a> which, by the way, had 3 people at this year's meeting.</p>
<p>Luke Gorrie did an extended version of the presentation on Teclo I had seen <a href="http://kvardek-du.kerno.org/2011/02/another-zslug-meeting-report.html">earlier this year in Zürich</a>. This one included even more interesting diagrams, in particular some illustrating the contrast between 3G network performance before and after enabling their product.</p>
<p>After lunch, Dave Cooper talked about his <a href="http://genworks.com/downloads/customer-documentation/index.xml">GDL</a> product, which includes <a href="http://www.cliki.net/KR">yet</a> <a href="http://www.cliki.net/Cells">another</a> <a href="http://www.cliki.net/Clon">object</a> <a href="http://www.cliki.net/computed-class">constraint</a>-ish system framework thingie.</p>
<p>Hans Hübner picked a controversial topic: code style and conventions. (A bit reminiscent of <a href="norvig.com/luv-slides.ps">Norvig and Pitman</a>'s slides.) He picked on the veritable 80-column rule (<em>blasphemy!</em>) and pushed for project/company style guides. The discussion was entertaining. The general conclusion I drew from that is that while it might be useful to write the more important points down, it's even better to programmatically enforce the more important ones like tabs vs. spaces and trailing whitespace. In my experience, good programmers pick up and follow (or challenge) code style fairly quickly without needing to go through an explicit style guide.</p>
<p>Paul Miller demoed his company's <a href="http://www.xanalys.com/solutions/linkexplorer.html">data analysis tool</a> written in Lispworks and talked a little bit about how it interacted and integrated with things like Excel via COM.</p>
<p>Lisp hero extraordinaire Xach Beane did an awesome presentation on <a href="http://quicklisp.org">Quicklisp</a> detailing some of his implementation strategies, what problems Quicklisp purports to solve, its social impact on the Lisp community, and what his vision for the future is. I was particularly excited about his plan to enable hacking on random project à la <a href="http://common-lisp.net/project/clbuild">clbuild</a>. Definitely the juiciest talk in the meeting in my opinion.</p>
<p>Finally, there were lots of lightning talks this year:</p>
<ul><li>Marco Antoniotti announced <a href="http://www.european-lisp-symposium.org/">ELS</a> 2012.</li>
<li>Christophe Rhodes's talked about R's lispiness and demoed his <a href="http://common-lisp.net/~crhodes/swankr/">swankr</a> project that brings R to SLIME and has nifty features like <a href="http://common-lisp.net/~crhodes/swankr/lattice-presentations.png">graphical presentations</a>.</li>
<li>Erik Huelsmann announced <a href="http://abcl-dev.blogspot.com/2011/10/abcl-100-released.html">ABCL 1.0</a>! (There were three quite enthusiastic ABCL developers at the meeting.)</li>
<li>Pierre-Yves Baccou shared some thoughts on <a href="https://github.com/pyb/zen">Zen</a>, his X-server in ~5K lines of CL code.</li>
<li>... and many others including a valiant attempt at subverting the 5+2 minute rule.</li>
</ul>
<p>Drinks, dinner, then drinks again. Hanging out with Lispers is the best part of ECLM and there was plenty of that. Looking forward to the next one already!</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com0tag:blogger.com,1999:blog-23326860.post-46238951337220572582011-06-02T11:00:00.000+01:002011-06-02T11:15:38.955+01:00Joey Comeau learns CL<p>Noticed via Twitter that <a href="http://untoward.livejournal.com/">Joey Comeau</a> of "<a href="http://www.asofterworld.com">A Softer World</a>"-fame has been doing some <a href="http://untoward.livejournal.com/472028.html">programming in Lisp</a>. I liked the way <a href="http://ryannorth.tumblr.com/post/5896696632/iming-with-joey">he put it</a>:</p>
<blockquote><pre><strong>Joey: (4:01:05 PM)</strong> maybe i should take up a self abusive hobby
<strong>Joey: (4:01:08 PM)</strong> like lisp programming
<strong>Ryan: (4:01:20 PM)</strong> haha
<strong>Ryan: (4:01:23 PM)</strong> sec phone
after the phone call i leave the computer and don't come back
the next day
<strong>Joey: (9:20:29 AM)</strong> I am learning common lisp</pre></blockquote>
<p>With apologies to Joey and Emily:</p>
<p style="text-align: center"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQLAADW9FAPzOyG_zMmqNpPthmMVx2YDHezbe6UTKTvJAMq5MIEpvEPexQOjGxWGyGzcwTVbtOyYcF_chmZMhbS3P4xg7PPl0o-cp9Ptb_CYim-aAK1VP1izqR8Ilq8Q562tAO8Q/s1600/lisp.png" /><p>
(And here's <a href="http://www.asofterworld.com/index.php?id=556
">one of my favourite strips</a>.)Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2tag:blogger.com,1999:blog-23326860.post-28420115467302221972011-02-10T12:20:00.004+00:002011-02-10T21:16:03.811+00:00Another ZSLUG meeting report<p style="clear:right; float:right; margin-left:1em; margin-bottom:1em">
<img border="0" height="300" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzR3pxm1uoZsaDbf9F-qYCZ1haHSuCZI0Wnk_y9jqMZ54HGwaphI4AUiH8kfKW5OTW3minKyHHOKT5WYR5StAc1Lmyb5ip2R_WEKhECbSowJfwQScyUGi3D8xIpqD_44Cd2F-WOw/s400/IMG_0873.jpg" /></p>
<p>I seem to have picked up the habit of doing at least one Lisp conference per year. This year I was hoping for an <a href="http://www.international-lisp-conference.org">ILC</a> (or <a href="http://www.weitz.de/eclm2009/">ECLM</a>?), but I'll have no such luck, it seems. So, the <a href="http://zslug.wordpress.com/2011/02/09/meeting-1-report-audio-und-slideware-of-hans-talk/">first ZSLUG-ng meeting</a> was it and here's a summary of my trip to Zürich.</p>
<p><strong>Sunday</strong>. Met the <a href="http://www.teclo.net/">Teclo</a> folks for dinner. The stuff they're working on is exciting in a low-level-ish kind of way — more on that later — and their team is composed by some of the best Lispers I know. (Also, as it turns out, they must have the very best intersection between Lisp and cooking skills!) Their startup vibe is intoxicating; if you're into systems programming, low-level networking stuff, <a href="http://common-lisp.net/pipermail/pro/2010-December/000198.html">et cetera</a>, you should definitely get in touch with them.</p>
<p><strong>Monday</strong>. Could see the snowy Alps thanks to the lovely clear sky. Zürich is posh, expensive, clean, and it's got great a public transportation system, mostly trams, which I much prefer to subways. Met <a href="http://jorgetavares.com/">Jorge Tavares</a> who was in town for the meeting. Jorge was a TA of mine who pointed me at Paul Graham's <em>ANSI Common Lisp</em> back in my first year of college. (Note: this was before the <a href="http://www.gigamonkeys.com/book/" title="Practical Common Lisp">best Lisp book</a> had been released.) Among many things, we talked about his rather interesting research around <a href="http://en.wikipedia.org/wiki/Genetic_programming">genetic programming</a> and evolutionary design of algorithms using Lisp.</p>
<p style="clear:left; float:left; margin-right:1em; margin-bottom:1em">
<a href="http://twitter.com/#!/lukego/status/34903428484308992">
<img border="0" height="299" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS57ND0sKgX57lOTOd7J5n9I50h8Up9dyEhue2lVBOwnuWKxXbUczL8-CmSASPAbwgcVlZw3w0RUyl6oRYneAiQL3rLiT2Fsaeezad0YVrbUNhRy2cEkLGkS-Pyr1lzW4QeDFCUg/s400/237911134.jpg" /></a></p>
<p>Hans Hübner talked about his thwarted plans to replicate the Lisp Machine using FPGAs, and how he ended up implementing a Forth system instead. I was expecting some sort of tutorial or more technical details, perhaps a demo, but, alas, no such luck. Great talk, though.</p>
<p>Luke Gorrie then talked about Teclo. After introducing the team, he proceeded to show us how TCP badly misbehaves in today's mobile networks using insightful time-sequenced diagrams produced by their <a href="http://teclo.net/products/sage/">analysis tools</a>. Some of the TCP sessions exhibited pathological behaviour, with TCP senders getting awfully confused by the odd packet lost in the ether. It was a bit reminiscent of <a href="http://www.bufferbloat.net/
">buffer bloat</a> to the untrained eye; perhaps because part of the problem is that radio networks go out of their way to not drop packets.
There was some explanation about how <a href="http://teclo.net/products/sambal/">Sambal</a> sits as a proxy between radio and wired networks and massages TCP connections to make them more amenable to the lossy radio networks. They have their own TCP/IP stack written in Lisp that bypasses the OS and handles packets in under 100 ns each. Neat stuff.</p>
<p>The evening carried on, to a local pub, as usual. It was a good meeting, if a bit short. I think it could have included lightning talks; those have worked quite well in past conferences.</p>
<p><strong>Tuesday</strong>. Had time for some light hiking around <a href="http://en.wikipedia.org/wiki/%C3%9Cetliberg">Üetliberg</a>, then back to Lisbon.</p>Luíshttp://www.blogger.com/profile/04787580931645750027noreply@blogger.com2