tag:blogger.com,1999:blog-200691142024-03-08T04:14:20.419+01:00p-cos blogPascal Costanza's Highly Opinionated Blog.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.comBlogger80125tag:blogger.com,1999:blog-20069114.post-10627024037157838602022-11-03T12:47:00.001+01:002022-11-03T12:47:57.998+01:00New blog address<p>I am moving my blog away from blogspot / blogger. I am going to host my <a href="https://blog.p-cos.net">new blog</a> at <a href="https://micro.blog">micro.blog</a>. You can subscribe to an <a href="https://blog.p-cos.net/categories/lisp/feed.xml">RSS feed on Lisp-related posts</a> if you care only for that. micro.blog also acts as a social network and, although it is its own platform, is compatible with Mastodon. My Mastodon handle is @costanza@micro.blog.</p><style>cnx.cnx-float, cnx.cnx-float cnx { visibility: hidden !important; } div.jwplayer div.jw-wrapper, div[id^='primis_playerSekindoSPlayer'], div.min-tv-is-sticky, iframe.min-tv-is-sticky, div.vjs-pip-container video-js.video-js.vjs-pip-active { position: absolute !important; }</style><style>cnx.cnx-float, cnx.cnx-float cnx { visibility: hidden !important; } div.jwplayer div.jw-wrapper, div[id^='primis_playerSekindoSPlayer'], div.min-tv-is-sticky, iframe.min-tv-is-sticky, div.vjs-pip-container video-js.video-js.vjs-pip-active { position: absolute !important; }</style>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-4005767247008129282021-01-29T14:43:00.000+01:002021-01-29T14:47:20.334+01:00The Slick programming language<p>I’m happy to announce the release of the Slick programming language, an s-expression surface syntax for Go, with some extensions inspired by Common Lisp and Scheme. See the <a href="https://github.com/ExaScience/slick">Slick programming language repository</a> for more details.</p>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-7536256985972900672016-02-28T19:40:00.002+01:002016-02-28T19:40:11.610+01:00Closer project repositories moved to github<div style="font-family: Helvetica; font-size: 12px; line-height: normal;">
I have moved the Closer project repositories to github. All details around this move are listed at the <a href="https://common-lisp.net/project/closer/">Closer project website</a>, especially see the <a href="https://common-lisp.net/project/closer/downloads.html">list of repositories</a>. Since github provides dedicated means for reporting issues, I’m shutting down the mailing lists for the Closer project as well.</div>
Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-11420051238480006722014-09-07T16:21:00.000+02:002014-09-07T23:30:49.626+02:00"Why I like Common Lisp"In a recent email exchange discussion, Charlotte Herzeel gave a summary of Common Lisp that I believe is worth repeating publicly. With her permission, I repeat her statements here.<br />
<br />
“An important reason why I like Common Lisp a lot is that the language has a layered design that supports incremental development. The language provides very high-level programming abstractions, such as object-oriented programming, dynamic multiple dispatch, garbage collection, a meta-object protocol, and so on. These abstractions are typically open implementations, built on top of more efficient low-level abstractions the user can also choose to access directly.<br />
<br />
Common Lisp is typically implemented as a compiled language, compiling directly to machine code. The runtime components are sparse, the garbage collector being an important one. Common Lisp provides the means to steer the compiler and runtime components to do low-level optimizations. Examples of this include: type declarations to remove type-checking at runtime; inline declarations to avoid dispatch; dynamic extent declarations to perform stack allocation instead of heap allocation; disassembly of code snippets; tuning of the garbage collector to switch between collection strategies; and so on. Optimizations such as these are optional and localized. Hence it is very easy in Common Lisp to rapidly prototype and then incrementally optimize the code by identifying the hotspots through profiling. This way you can often be as efficient as with C code, without being forced to program in a low-level style from the start throughout your whole program.<br />
<br />
Hence in contrast to C/C++, Common Lisp allows you to optimize code incrementally and locally for a particular snippet of code. In contrast to Java - or any other language with an implementation that performs optimization at runtime through tracing or JIT compiling or so - Common Lisp implementations employ in a sense a more classic compilation approach. In this sense, Common Lisp makes it easier to ‘control’ what you are measuring when profiling programs.<br />
<br />
The Common Lisp Object System (CLOS) is a library in Common Lisp for object-oriented programming. Common Lisp is a multi-paradigm language, so it depends on your problem whether it is a good idea to use object-oriented programming or not. That said, CLOS is very different from mainstream object-oriented programming. It allows multiple inheritance, multiple dispatch, and is based on generic functions, i.e. classes define types, and methods are defined separately as part of generic functions. The CLOS implementation performs a lot of clever optimizations at runtime, for example for method lookup. What is of course special about CLOS, is that it has a meta-object protocol, which allows you to extend/modify CLOS in an organized way. For example, you have hooks into the method dispatch protocol, the slot (= field) access protocol, etc. If you want to know more about the CLOS implementation and the meta-object protocol, read ‘The Art of the Meta-Object Protocol’ by Kiczales, des Rivieres, Bobrow.<br />
<br />
Common Lisp just has a lot of advanced language features that you just don’t find in other languages.<br />
<br />
From a practical point of view, I can recommend LispWorks as a Common Lisp implementation. LispWorks is very user-friendly because it comes with an integrated development environment. This means you get Smalltalk-like features such as code browsers and inspector tools. Another user-friendly implementation that is free is Clozure Common Lisp. The most widely used open-source implementation is SBCL, which is very stable and very efficient. There are lots of other Common Lisp implementations out there, but I recommend one of these three.<br />
<br />
If you want to learn about Common Lisp, I can recommend “Ansi Common Lisp” by Graham. Maybe also interesting: ‘<a href="http://www.p-cos.net/lisp/guide.html">Pascal Costanza’s highly opinionated guide to Common Lisp</a>’ ;-). If you want a funny introduction to Common Lisp, check out the <a href="http://lisperati.com/">Lisperati</a>. A good place to snoop for Common Lisp war stories is <a href="http://planet.lisp.org/">Planet Lisp</a>. If you want to get an idea about libraries, see <a href="http://www.quicklisp.org/">quicklisp</a>.”<br />
<br />Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com1tag:blogger.com,1999:blog-20069114.post-47852302917509153712014-07-20T15:49:00.000+02:002014-07-20T15:49:24.560+02:00A Lisper's first impression of JuliaI have recently looked at <a href="http://julialang.org/">Julia</a>, a new programming language developed at MIT that promises to be a dynamic programming language that is suitable for scientific computing with a high-performance implementation. It is an interesting project that heavily borrows from <a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">Common Lisp</a>, <a href="http://opendylan.org/books/drm/">Dylan</a>, and <a href="http://www.schemers.org/Documents/Standards/R5RS/">Scheme</a>, and you can rightfully argue that Julia itself is actually a Lisp dialect. While I wasn’t very impressed with some other recent Lisp dialects (<a href="http://arclanguage.org/">Arc</a>, <a href="http://clojure.org/">Clojure</a>), Julia puts a couple of very interesting features on the table. Below is a discussion of the more salient aspects of Julia, as seen from a Common Lispers perspective. It is based on the <a href="http://julia.readthedocs.org/en/latest/manual/">documentation of the prerelease version 0.3 of Julia</a>.<br />
<br />
Julia is closest to Dylan in many regards. It uses a somewhat mainstream syntax rather than s-expressions. Unlike Dylan, you can nevertheless write ‘full’ macros, since macro definitions are implemented in Julia, not some template language, and <a href="http://repository.readscheme.org/ftp/papers/pepm99/bawden.pdf">backquote/quasiquote</a> is integrated with the Julia syntax. Julia is a <a href="http://www.dreamsongs.com/Separation.html">Lisp-1</a> (like Scheme or Dylan) rather than a <a href="http://www.dreamsongs.com/Separation.html">Lisp-2</a> (like Common Lisp or ISLISP), which makes it necessary to add <a href="http://dx.doi.org/10.3217/jucs-016-02-0271">macro hygiene</a> features. Fortunately, this does not mean you have to deal with the rather painful <a href="http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-13.html">syntax-case</a> construct of some Scheme dialects, but you can still use far simpler backquote/quasiquote constructions, just with macro hygiene taken care of by default. Julia also allows you to selectively break hygiene. Although I usually strongly prefer the simplicity of Common Lisp’s non-hygienic macro system, the fact that Julia is a Lisp-1 turns macro hygiene into a real problem, so I guess this is a reasonable design.<br />
<br />
Julia provides object-oriented programming from the ground up, similar to Dylan. It centers on generic functions rather than classes, where methods are defined outside classes and allow for multiple dispatch, just like in Dylan and Common Lisp. Like Dylan, and unlike Common Lisp, it does not distinguish between functions and generic functions: All functions can have methods, you do not have to make up your mind whether you want methods or plain functions. Unlike in Common Lisp, there are no method combinations, no before/after/around methods, and call-next-method is not directly supported, but has to be done manually. This is probably to simplify method dispatch, maybe to have some performance advantages, though I find it hard to imagine that adding method combinations would make things substantially worse.<br />
<br />
You still need a class hierarchy to drive method dispatch. Unlike in Common Lisp, there is no multiple inheritance, only single inheritance. In fact, there is actually no real inheritance, because in Julia, only leaf classes of the class hierarchy are allowed to define slots/fields. All superclasses are required to be “abstract,” without any slot definitions. Also, Julia classes cannot be redefined at runtime, so in fact Julia classes are much closer to Common Lisp’s structured types rather than classes.<br />
<br />
Julia’s execution model is based on dynamic compilation. As a user, you don’t have to compile your code at all, source code is just compiled on the fly (similar as in <a href="http://ccl.clozure.com/">Clozure Common Lisp</a>). Julia inlines functions on the fly, including generic functions, and can de-optimize when function definitions change at runtime. This is more flexible than in Common Lisp, where inlined functions can get out of sync with their potentially changed definitions. Also, while the Common Lisp specification does not say anything with regard to being able to inline generic functions or not, there are <a href="http://alu.org/mop/concepts.html#generic-function-invocation-protocol">aspects in the CLOS MOP specification that prevent generic functions from being inlined</a>, at least for user-defined extensions of generic functions. Julia definitely seems more “modern” here.<br />
<br />
In Julia, there is no distinction between variable binding and variable assignment. If you assign to a variable that has not been used before in the same lexical environment, it is silently introduced. In Common Lisp/Scheme/Dylan, there is a distinction between ‘let forms that introduce variable bindings, and assignments (setq/setf/set!) that perform assignments. I’m highly skeptical of Julia’s design here, because this potentially leads to bugs that are hard to find: A simple typo in your source code just may go unnoticed.<br />
<br />
In Julia, all variables are lexically scoped (except for some seemingly quirky scoping semantics for global variables, see below). There are no special / dynamically scoped variables in Julia, which is a major omission in my book. Some academics don’t like special scoping, but their presence in Common Lisp is incredibly useful in practice, especially but not only for multi-threading!<br />
<br />
Julia’s default representation for integers is either 32-bit or 64-bit integers, depending on the target architecture, which silently wrap around. Julia also supports “BigInts” that can be arbitrarily large, but you have to ask for them explicitly. In Common Lisp, integers are by default arbitrarily large, which I think is an advantage. Due to type tagging in Common Lisp implementations, even “big” integers are typically allocated as immediate values rather than on the heap when they fall into the “fixnum” range. I didn’t find anything in the Julia documentation that discusses this aspect of “BigInt.”<br />
<br />
In Julia, all mathematical operations are generic functions and can be extended by user-defined methods. This is a strong advantage for Julia. In Common Lisp, mathematical operations are “plain” functions which cannot be extended. Due to some aspects in the design of Common Lisp’s generic functions, it’s hard to inline (or open-code) them, which is why for performance reasons, it’s better to express mathematical (and other such performance-critical functions) as “plain” functions.
Apart from that, the support for number types seems to be on par between Julia and Common Lisp (complex types, rational numbers, floating point numbers, etc.)<br />
<br />
In Julia, strings are unicode strings by default. My knowledge about unicode support in Common Lisp implementations is limited, so I cannot really make any comparisons here. One interesting aspect in Julia’s string support is that there can be user-defined macros to parse them and construct other syntactic entities out of them. This feels somewhat similar to read macros in Common Lisp, although with a slightly different scope.<br />
<br />
Julia’s support for functions is similar to Common Lisp: They can be first class and anonymous (lambda expressions). There are varargs (&rest), optional and keyword arguments. In Common Lisp, optional and keyword arguments cannot be dispatched on in methods. In Julia, optional arguments can be dispatched on, but not keywords. (This is a pity, dispatch on keyword arguments would be very interesting, and is something I wanted to add as part of <a href="http://common-lisp.net/project/closer/">Closer to MOP</a> for a long time!)<br />
<br />
Julia’s support for control flow is much more limited than in Common Lisp. There are equivalents for progn, cond/if, for and while loops. Unlike Common Lisp, there is no support for a <a href="http://gigamonkeys.com/book/loop-for-black-belts.html">full loop facility</a>, or even for a simple goto construct. Common Lisp clearly wins here. Julia’s support for exception handling is also limited: No handler-bind, no restarts, unlike in Common Lisp, which are also really useful features.<br />
<br />
Julia’s type system has some interesting differences to Common Lisp: There is a distinction between mutable and immutable classes. Immutable classes disallow any side effects on their fields. This seems to be primarily directed at enabling stack allocation as an optimization. In Common Lisp, you would use dynamic extent declarations when allocating structs (or other data types) to achieve similar performance improvements. I’m not sure why it would matter that the fields need to be read-only for such an optimization, but if this covers most cases, maybe this is good enough.<br />
<br />
Julia allows for returning and receiving multiple values from function calls, similar to Common Lisp. This is a feature I like a lot in Common Lisp, so I’m happy it’s also in Julia. In Julia, this is achieved by an explicit tuple type representation which doesn’t exist in this form in Common Lisp. In Lisp, you could also return/receive lists instead of multiple values, which would correspond to this kind of tuple type, but lists add an additional performance overhead, which multiple values and, presumably, tuples in Julia don’t have.<br />
<br />
Julia supports parametric types. I don’t see at the moment why this is relevant. You could achieve similar functionality also with some macrology. Maybe I’m missing something here.<br />
<br />
There is a whole section on constructors (make-instance / make-struct) in the Julia manual. This makes me suspicious, this should be an easier topic.<br />
<br />
Julia has a module system. It supports export and automatic import of explicitly exported identifiers. You can also still access non-exported identifiers with additional syntax. This is good, because module designers may not always perfectly anticipate what users actually need to access. Common Lisp’s package system supports a similar distinction between external and internal definitions that can be accessed in different ways. I slightly prefer Common Lisp’s ability to use the package name as a prefix even for explicitly exported definitions. There is no feature in Julia to rename imported identifiers, which is something where Common Lisp’s support for explicit package name prefixes can come in very handy. I would like to see something like <a href="http://www.inf.ethz.ch/personal/wirth/Oberon/Oberon.Report.pdf">Oberon</a>’s support for renaming identifiers on import in some Lisp dialect someday, because I believe that is the most complete solution for dealing with potential name conflicts.<br />
<br />
In terms of meta-programming, apart from macros, Julia also supports (top-level) eval, like Common Lisp. Julia’s support for “reflection” is much weaker than Common Lisp’s <a href="http://alu.org/mop/">CLOS MOP</a>: You can only inspect types at runtime, but you cannot modify them (and language designers should stop calling something “reflection” that is clearly just “introspection”).<br />
<br />
Both Julia and Common Lisp support multi-dimensional arrays. Common Lisp’s arrays are in row-major order, starting at index 0 in every dimension. Julia’s arrays are column-major order, starting at index 1 in every dimension. Julia’s support for multi-dimensional arrays is a library feature, whereas Common Lisp’s support is built into the language. Julia supports both dense and sparse matrices, where Common Lisp supports only dense matrices out of the box.<br />
<br />
There are a lot of libraries that ship with Julia targeted at scientific computing.<br />
<br />
Julia supports parallel programming with a model built on top of message passing: If you want to run parallel algorithms, you essentially start several instances of Julia that communicate with each other. The model does not support shared memory, and there is no multi-threading within a Julia instance (although there seem to be discussions among the Julia designers to add this in the future). The model is built on top of <a href="https://en.wikipedia.org/wiki/Message_Passing_Interface">MPI</a> as an implementation backend. However, the actual programming model supports single-sided communication: You can ask a function to be executed in some other Julia worker process, and can later synchronize with it to fetch results. On top of that, there are some high-level constructs provided as library features, such parallel maps and loops. Julia’s message passing model ensures that within a Julia instance, only one task is executed at a time, so there is yet no need to provide low-level synchronization mechanisms, such as locks or atomic operations. The lack of shared-memory parallelism is problematic because many parallel algorithms that are very easy to express with shared memory become quite complicated in a distributed memory setting. On the other hand, Julia’s model easily supports true distributed programming: You can configure Julia to run several instances across a cluster, and use them in a quite straightforward way: substantially easier than what you have to do with, say, MPI, and much closer with regard to ease of use to modern <a href="https://en.wikipedia.org/wiki/Partitioned_global_address_space">PGAS languages</a> like <a href="http://chapel.cray.com/">Chapel</a> or <a href="http://x10-lang.org/">X10</a>.<br />
<br />
The ANSI specification for Common Lisp does not mention anything about multi-threading or parallel programming at all, but many Common Lisp implementations add support for shared-memory parallelism. I will not go into details here, but let me just briefly state that, for example, the <a href="http://www.lispworks.com/">LispWorks</a> implementation of Common Lisp provides <a href="http://www.lispworks.com/documentation/lw61/LW/html/lw-244.htm">excellent support for symmetric multiprocessing</a> that is at least on par with what you can find in most other language implementations in terms of parallel programming support. However, unfortunately, support for true distributed memory models seems almost non-existent in Common Lisp, apart for some basic support for MPI in a library that was maintained only for a very short period of time a couple of years ago. Julia looks like a good source of inspiration for adding such features to Common Lisp.<br />
<br />
However, one aspect of Julia’s message passing approach seems problematic, as far as I can tell: You can pass closures between different instances of Julia, but it’s not clear how free variables in a lambda expression are bound. It seems that lexical variables are bound and serialized to another process, but global variables are not serialized and need to be present in any presence that may execute the closure. Experiments with adding side effects to free variables in lambda expressions that are passed to other processes seem to suggest that the semantics of this combination of features are unpredictable. At least, I have not been able to figure out what happens when — sometimes variables seem to be updated at the sender’s side, sometimes not — and I didn’t find a discussion of this topic in the Julia manual.<br />
<br />
Anyway, as you can tell, there are a lot of interesting features in Julia, and it’s definitely worth a try.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com19tag:blogger.com,1999:blog-20069114.post-32165734318602903342013-09-06T09:04:00.002+02:002013-09-06T09:04:52.305+02:00Parenthesis can be tricky...You probably didn't see <a href="http://www.trickysite.com/parenthesis-video-2/">this</a> coming.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-62538931322995945522013-08-18T19:11:00.000+02:002013-08-18T19:18:55.109+02:00The Human Consequences of Dynamic Typing<p>I agree with Jay McCarthy that <a href="http://jeapostrophe.github.io/2013-08-12-types-post.html">static typing is anti-human</a>. I think I can give a slightly more elaborate example of a program that every static type checker must reject, but that is nevertheless correct. Everything below is valid Common Lisp:</p>
<pre>
(defclass person ()
((name :initarg :name
:accessor person-name)))
</pre>
<pre>
(defmethod display ((p person))
(format t "Person: Name ~S, address ~S."
(person-name p)
(person-address p)))
</pre>
<p>A static type checker must reject this program because there is no <span style="font-family: Courier New, Courier, monospace;">address</span> field defined in the class <span style="font-family: Courier New, Courier, monospace;">person</span> that <span style="font-family: Courier New, Courier, monospace;">person-address</span> presumably refers to. However, below is a run of the program in a Lisp listener that runs to a correct completion without fatal (!) errors:</p>
<pre>
CL-USER 1 > (defvar *p* (make-instance 'person :name "Pascal"))
*P*
</pre>
<pre>
CL-USER 2 > (display *p*)
</pre>
<pre>
Error: Undefined function PERSON-ADDRESS called with arguments
(#<PERSON 4020059AB3>).
1 (continue) Try invoking PERSON-ADDRESS again.
2 Return some values from the call to PERSON-ADDRESS.
3 Try invoking something other than PERSON-ADDRESS with the
same arguments.
4 Set the symbol-function of PERSON-ADDRESS to another
function.
5 (abort) Return to level 0.
6 Return to top loop level 0.
</pre>
<pre>
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for
other options.
</pre>
<pre>
CL-USER 3 : 1 > (defclass person ()
((name :initarg :name
:accessor person-name)
(address :initarg :address
:accessor person-address)))
#<STANDARD-CLASS PERSON 4130371F6B>
</pre>
<pre>
CL-USER 4 : 1 > :c 1
</pre>
<pre>
Error: The slot ADDRESS is unbound in the object
#<PERSON 41303DD973> (an instance of class
#<STANDARD-CLASS PERSON 4130371F6B>).
1 (continue) Try reading slot ADDRESS again.
2 Specify a value to use this time for slot ADDRESS.
3 Specify a value to set slot ADDRESS to.
4 (abort) Return to level 0.
5 Return to top loop level 0.
</pre>
<pre>
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for
other options.
</pre>
<pre>
CL-USER 5 : 1 > :c 3
</pre>
<pre>
Enter a form to be evaluated: "Belgium"
Person: Name "Pascal", address "Belgium".
NIL
</pre>
<pre>
CL-USER 6 > (display *p*)
Person: Name "Pascal", address "Belgium".
NIL
</pre>
<p>The "trick" is that the Lisp listener allows for interactive modification of a program <b>while it is running</b>. No static type checker can anticipate what modifications will be performed at runtime.</p>
<p>This is not a toy feature of Common Lisp, but something that many Lisp developers rely on. For example, <a href="http://common-lisp.net/project/closer/">my own ContextL library</a> crucially relies on the very <a href="http://www.lispworks.com/documentation/lw50/CLHS/Body/04_cf.htm">class redefinition feature</a> I demonstrate above. Joe Marshall provides <a href="http://funcall.blogspot.be/2013/07/clos.html">another account how such features can solve real-world problems</a>.</p>
Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com13tag:blogger.com,1999:blog-20069114.post-7888887534034220502013-02-17T18:43:00.001+01:002013-02-17T18:43:14.920+01:00Closer to MOP supports ABCL 1.1.1The darcs repositories of Closer to MOP now also support ABCL 1.1.1. I plan to make a more official release soon. The Common Lisp implementations currently covered are now as follows: Allegro 9.0, ABCL 1.1.1, CLisp 2.49, Clozure Common Lisp 1.8, CMU CL 20d, ECL 12.12.1, LispWorks 6.0.x and 6.1.x, SBCL 1.1.4, and SCL 1.3.9.<br />
<br />Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com2tag:blogger.com,1999:blog-20069114.post-80668897118308488452012-09-25T21:32:00.000+02:002012-09-25T21:34:11.442+02:00Closer to MOP on ABCL and ECLJust to report on work in progress: I am currently working in my spare time on making sure that Closer to MOP works (again) with ABCL and ECL. ABCL is in relatively good shape, but still needs a couple of bugs fixed here and there. Rudi Schlatte is doing a fantastic job at responding to bug reports. I'm pretty sure the next release will have excellent Closer to MOP support. ECL's recent version came with several changes in its CLOS MOP implementation which broke a lot of things in Closer to MOP, so the current version of Closer to MOP doesn't work with ECL. I'm doing what I can to make sure Closer to MOP is back to speed again with ECL. However, I can only do this in my spare time, and will be busy moving in the next couple of weeks, so some delays are to be expected...<br />
<br />Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com2tag:blogger.com,1999:blog-20069114.post-39334201760152487652012-08-09T19:55:00.001+02:002012-08-09T19:56:48.296+02:00Arguments against call/ccAn excellent collection of good arguments against having call/cc in a programming language (such as Scheme), by the ever-inspiring Oleg Kiselyow: <a href="http://okmij.org/ftp/continuations/against-callcc.html">An argument against call/cc</a>.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com2tag:blogger.com,1999:blog-20069114.post-72420322995576195862012-05-02T15:48:00.002+02:002012-05-02T15:48:48.672+02:00Common Lisp, the Untold StoryNice article by Kent Pitman, mostly about his experiences with the Common Lisp standardization process: <a href="http://www.nhplace.com/kent/Papers/cl-untold-story.html">Common Lisp, the Untold Story</a>.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-15919281869146229012012-05-02T15:46:00.000+02:002012-05-02T15:46:01.403+02:00100% programmed in Common Lisp, the artificial intelligence applications development languageA short article about an apparently successful <a href="http://www.marketwatch.com/story/secure-outcomes-announces-50th-order-for-ls1100-digital-livescan-fingerprinting-system-2012-05-01">digital livescan fingerprinting system</a>.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-30997089428522739152011-11-08T18:29:00.002+01:002011-11-08T18:29:56.028+01:00Bertrand Meyer about John McCarthy...Nice essay about <a href=http://bertrandmeyer.com/2011/11/07/john-mccarthy/>John McCarthy</a>.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-14788495128391205872011-10-01T17:38:00.003+02:002011-10-01T17:40:04.886+02:00Beware the Purists...See <a href="http://joshuablankenship.com/blog/2011/09/24/beware-the-purists/">Beware the Purists, Lest They Kill Your Innovation</a>. Much of what is stated there also strongly applies to programming and programming languages...Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-50083002655516003552011-08-30T22:58:00.001+02:002011-08-30T22:59:45.048+02:00The Perils of Partially Powered LanguagesHere is a worthwhile read: <a href="http://www.yesodweb.com/blog/2011/08/perils-partially-powered-languages">The Perils of Partially Powered Languages</a>. It's from a Haskell perspective, but should apply to other non-underpowered languages as well. ;)Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-55928297051893727992011-08-12T17:53:00.002+02:002011-08-12T17:56:25.958+02:00Complexity metrics other than code size don't mean that much...See <a href=http://www.neverworkintheory.org/?p=58>here</a>. To cite:
<br />
<br />"El Emam and his colleagues repeated some of those experiments using bivariate analysis so that they could allocate a share of the blame to code size (measured by number of lines) and the metric in question. It turned out that code size accounted for all of the significant variation: in other words, the object-oriented metrics they looked at didn’t have any actual predictive power once they normalized for the number of lines of code. Herraiz and Hassan’s chapter in Making Software, which reports on an even larger study using open source software, reached the same conclusion:
<br />
<br />'…for non-header files written in C language, all the complexity metrics are highly correlated with lines of code, and therefore the more complex metrics provide no further information that could not be measured simply with lines of code… In our opinion, there is a clear lesson from this study: syntactic complexity metrics cannot capture the whole picture of software complexity. Complexity metrics that are exclusively based on the structure of the program or the properties of the text…do not provide information on the amount of effort that is needed to comprehend a piece of code—or, at least, no more information than lines of code do.'"Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com2tag:blogger.com,1999:blog-20069114.post-17066382253878327542011-02-01T10:24:00.003+01:002011-02-01T12:06:16.249+01:00Special variables in JavaWow. This is how complicated it gets to have he functionality of special variables in a language that really doesn't want them (and it's brought to you by Google): <a href="http://code.google.com/p/google-guice/">Google Guice</a>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com8tag:blogger.com,1999:blog-20069114.post-23780312926365692452010-12-30T20:20:00.002+01:002010-12-30T20:59:51.860+01:00A non-hierarchical approach to object-oriented programmingThe <a href="http://www.mcjones.org/dustydecks/archives/2010/12/30/279/">Lisp historical archive web site just got reorganized</a>. I have made a quick check of the contents, and found out that Howard I. Cannon's original technical report about <a href="http://www.softwarepreservation.org/projects/LISP/MIT/nnnfla1-20040122.pdf">Flavors - A non-hierarchical approach to object-oriented programming</a> was finally made available as part of that archive. The report was originally written in 1979, was circulated around Lispers, but was never ever published as an actual technical report, although it is cited as such in several later papers by other authors. It describes the original object-oriented extension to the MIT Lisp Machine, heavily influenced by Smalltalk, but with multiple inheritance and method combinations added (but no multiple dispatch yet, which got only introduced in <a href="http://www2.parc.com/istl/members/stefik/loops.html">CommonLoops</a>, a direct predecessor of <a href="http://dreamsongs.com/CLOS.html">CLOS</a>). Although unpublished and clearly in an unfinished state, this report itself influenced a lot of other subsequent experiments with object-oriented extensions to Lisp dialects. Among other things, it already mentions the idea of exploring "meta-protocols" for making parts of the implementation of the object-oriented extension itself customizable, which was later investigated in much more detail as part of the work on the <a href="http://www.lisp.org/mop">CLOS MOP</a> (see also <a href="http://books.google.be/books?id=3X5Gnudn3k0C&lpg=PP1&ots=ZqatlHu75S&dq=the%20art%20of%20the%20metaobject%20protocol&hl=en&pg=PP1#v=onepage&q&f=false">The Art of the Metaobject Protocol</a>). And, of course, method combinations were already a very early predecessor of aspect-oriented programming.<div><br /></div><div>It's good that this very important historical document is finally available!</div><div><br /><div><br /></div></div>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-39013718403162849472010-11-08T12:44:00.004+01:002010-11-08T12:45:23.035+01:00Now is the time...Now is the time to switch programming languages: <a href="http://blog.herlein.com/2010/11/oracle-is-the-borg-enterprise-software-development-will-be-assimilated/">Oracle is the borg</a>.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com1tag:blogger.com,1999:blog-20069114.post-37052321727130720662010-06-14T14:37:00.002+02:002010-06-14T14:51:40.954+02:00AOSD'11 conferenceAnother interesting conference is coming up: The <a href="http://www.aosd.net/2011/">International Conference on Aspect-Oriented Software Development</a> will be held in Porto de Galinhas, Brazil in March 2011. The conference chair is Shigeru Chiba, who is a long-term contributor to reflection and metaprogramming techniques himself, and who has assembled a diverse <a href="http://www.aosd.net/2011/organization.html">program committee</a> covering not only core aspect technologies (like AspectJ-influenced approaches), but also explicitly Feature-oriented Programming, Context-oriented Programming, and also metaprogramming and reflection (which have been somewhat neglected in the aspect community for a long time, although they are clearly very relevant), among others. Dynamic languages are also mentioned in the <a href="http://www.aosd.net/2011/call_research.html">call for research papers</a>, so good papers based on languages like Lisp, Scheme, Smalltalk, and so on, are definitely welcome.<div><br /></div><div>Another interesting element of this conference that I haven't seen before is that there will be two opportunities to submit papers: The first deadline is July 1, 2010, and the second deadline is October 1, 2010. The idea is that papers that fail to get accepted in the first round can be improved by their authors for a second round of reviews. It will be interesting to see if this works out.</div>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-61733923367273981012010-06-07T17:15:00.002+02:002010-06-07T17:22:22.609+02:00International Lisp Conference '10The <a href="http://www.international-lisp-conference.org/2010/">International Lisp Conference</a> (ILC'10) is being held again, sooner than expected: It will be held in October 2010 in Reno, Nevada. This year, the conference will be co-located with <a href="http://splashcon.org/">OOPSLA/SPLASH</a>, which also hosts the <a href="http://www.dynamic-languages-symposium.org/dls-10/">Dynamic Language Symposium</a>. So this event is bound to be a very interesting combination. Paper submission for ILC'10 is open, submission deadline is August 1, so there is enough time to submit something. See the <a href="http://www.international-lisp-conference.org/2010/call-for-papers.txt">call for papers</a> for more information.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com1tag:blogger.com,1999:blog-20069114.post-4151203596774458492010-04-25T15:04:00.003+02:002010-04-25T15:11:55.814+02:00Lisp Machine demonstration...I only now realized that besides the interesting talks and presentations to be given at this year's European Lisp Symposium, there will also be a demonstration of a <a href="http://en.wikipedia.org/wiki/TI_Explorer">TI Explorer Lisp Machine</a>. That's pretty cool - I have never seen a Lisp Machine in action, but always wanted to see one, so this will be my first time. Looking forward to that. :)<div><br /></div><div>Ah, yes, here is the link again: <a href="http://www.european-lisp-symposium.org/">European Lisp Symposium, Lisbon, Portugal, May 6-7, 2010</a>.</div><div><br /></div><div>There will also be presentations by Kent Pitman and Matthias Felleisen whose abstracts sound pretty interesting, and I will try to give an overview of parallel programming in Common Lisp at the symposium as well. Still have to work on the slides for that one...</div>Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com3tag:blogger.com,1999:blog-20069114.post-9311560671178834452010-04-13T15:16:00.003+02:002010-04-13T15:33:30.505+02:003rd European Lisp Symposium is very soon!The third European Lisp Symposium is less than a month away. I have received the following call for participation to redistribute, which I post here for everyone to read.<br /><br /><h2>3rd European Lisp Symposium</h2><br />May 6-7, 2010, Fundacao Calouste Gulbenkian, Lisbon, Portugal<br /><br /><span style="font-weight:bold;">Call for Participation</span><br /><br />Registration for the 3rd European Lisp Symposium (ELS 2010) is now <a href="http://www.european-lisp-symposium.org/">open</a>.<br /><br /><span style="font-weight:bold;">Scope and Programme Highlights</span><br /><br />The purpose of the European Lisp Symposium is to provide a forum for the discussion of all aspects of the design, implementation and application of any of the Lisp dialects. We encourage everyone interested in Lisp to participate.<br /><br />As well as presentations of the accepted technical papers and tutorials, the programme features the following highlights:<br /><ul><li>Kent Pitman of HyperMeta Inc. will offer reflections on Lisp Past, Present and Future;<br /></li><li>Pascal Costanza will lead a tutorial session on Parallel Programming in Common Lisp;<br /></li><li>Matthias Felleisen of PLT will talk about languages for creating;<br /></li><li>programming languages;<br /></li><li>there will be opportunities for attendees to give lightning talks and demos of late-breaking work.<br /></li></ul><br /><span style="font-weight:bold;">Social events</span><br /><ul><li>Symposium banquet (included with registration)<br /></li><li>Excursion to Sintra (optional), for six centuries the favourite<br /></li><li>Summer residence of the Kings of Portugal, who were attracted by cool climates and the beauty of the town's setting.<br /></li></ul><br /><span style="font-weight:bold;">Programme Chair</span><br /><br />Christophe Rhodes, Goldsmiths, University of London, UK<br /><br /><span style="font-weight:bold;">Local Chair</span><br /><br />Antonio Leitao, Technical University of Lisbon, Portugal<br /><br /><span style="font-weight:bold;">Programme Committee</span><br /><ul><li>Marco Antoniotti, Universita Milano Bicocca, Italy<br /></li><li>Giuseppe Attardi, Universita di Pisa, Italy<br /></li><li>Pascal Costanza, Vrije Universiteit Brussel, Belgium<br /></li><li>Irene Anne Durand, Universite Bordeaux I, France<br /></li><li>Marc Feeley, Universite de Montreal, Canada<br /></li><li>Ron Garret, Amalgamated Widgets Unlimited, USA<br /></li><li>Gregor Kiczales, University of British Columbia, Canada<br /></li><li>Antonio Leitao, Technical University of Lisbon, Portugal<br /></li><li>Nick Levine, Ravenbrook Ltd, UK<br /></li><li>Scott McKay, ITA Software, Inc., USA<br /></li><li>Peter Norvig, Google Inc., USA<br /></li><li>Kent Pitman, PTC, USA<br /></li><li>Christian Queinnec, Universite Pierre et Marie Curie, France<br /></li><li>Robert Strandh, Universite Bordeaux I, France<br /></li><li>Didier Verna, EPITA Research and Development Laboratory, France<br /></li><li>Barry Wilkes, Citi, UK<br /></li><li>Taiichi Yuasa, Kyoto University, Japan<br /></li></ul><br /><span style="font-weight:bold;">Registration</span><br /><br />Registration is <a href="http://www.european-lisp-symposium.org/">open</a> and costs EUR120 (EUR60 for students) until 22nd April, and EUR200 (EUR120 for students) afterwards.<br /><br />Registration includes a copy of the proceedings, coffee breaks, and the symposium banquet. Accommodation is not included.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com0tag:blogger.com,1999:blog-20069114.post-68752236124034328742009-12-04T23:00:00.002+01:002009-12-04T23:07:30.203+01:00Filtered functionsI am very excited that I can finally annouce a public release of <span style="font-style:italic;">filtered functions</span>, an extension of generic functions that Charlotte Herzeel, Jorge Vallejos, and myself have developed some time ago and that we are very excited about because it seems to be quite powerful in a number of very different scenarios. It took a while to release filtered functions, because it is a quite non-trivial extension of generic functions and requires a CLOS MOP implementation that is compliant with the AMOP specification to quite a deep level. Therefore, this required some serious preparation in the form of a much improved Closer to MOP library, that I released today as well.<br /><br />You can find filtered functions and Closer to MOP at the <a href="http://common-lisp.net/project/closer/">Closer project website</a>. Below you will find a general overview of the concept.<br /><br />Filtered functions are an extension of generic functions, extended with a filtering step where the arguments received by a generic function are mapped to other values based on user-defined mapping functions. Those filtered values are then used to perform the actual selection and execution of applicable methods. Nevertheless, the methods that are eventually executed see the original objects as received by the generic function, and not the filtered ones.<br /><br />Here are some examples to illustrate the expressive power of filtered functions.<br /><br /><span style="font-weight:bold;">Factorial</span><br /><br />In order to be able to use filtered functions, we need to have filter functions that map received arguments to values that we actually want to base our dispatch on. For the factorial function, we want to distinguish between negative and positive numbers, and the number zero. For that we can just use the Common Lisp function SIGNUM that returns +1 for positive numbers, -1 for negative numbers, and just 0 for the number 0. The filtered function FAC can thus be defined as follows.<br /><pre><br />(define-filtered-function fac (n)<br /> (:filters (:sign #'signum)))<br /></pre><br />DEFINE-FILTERED-FUNCTION is exactly like DEFGENERIC, except that it can also define one or more filters. Here, it defines a filter with the name :SIGN wich specifices that the function SIGNUM is to be used for filtering.<br /><br />We can now define methods for FAC:<br /><pre><br />(defmethod fac :filter :sign ((n (eql +1)))<br /> (* n (fac (- n 1))))<br /><br />(defmethod fac :filter :sign ((n (eql 0)))<br /> 1)<br /><br />(defmethod fac :filter :sign ((n (eql -1)))<br /> (error "Fac not defined for negative numbers."))<br /></pre><br />Here, we use the qualifiers :FILTER :SIGN in the method definitions to indicate that we indeed want to use the :SIGN filter for method selection. We then use EQL specializers to ensure that the method definitions are applicable for the three different cases that SIGNUM yields. Remember that the method bodies always see the original arguments, not the filtered ones, and this is why the FAC methods can do the correct computations.<br /><br /><span style="font-weight:bold;">State pattern</span><br /><br />Filtered functions can be used to dispatch methods based on the state of an argument passed to a filtered function, which enables expressing State-like idioms. Assume the following simple CLOS class is defined for implementing a stack.<br /><pre><br />(defconstant +stack-size+ 10)<br /><br />(defclass stack ()<br /> ((contents :initform (make-array +stack-size+)<br /> :reader stack-contents))<br /> (index :initform 0<br /> :accessor stack-index)))<br /></pre><br />Instances of this class have three different states: Such a stack can either be empty, or full, or anywhere in between (in 'normal' state). We can express this as a function that recognizes the state of a stack.<br /><pre><br />(defun stack-state (stack)<br /> (cond ((<= (stack-index stack) 0) 'empty)<br /> ((>= (stack-index stack) +stack-size+) 'full)<br /> (t 'normal)))<br /></pre><br />It is now straightforward to use stack-state in a filter named :state for the typical stack operations.<br /><pre><br />(define-filtered-function stack-push (stack value)<br /> (:filters (:state #'stack-state)))<br /><br />(define-filtered-function stack-pop (stack)<br /> (:filters (:state #'stack-state)))<br /><br />(define-filtered-function stack-emptyp (stack)<br /> (:filters (:state #'stack-state)))<br /></pre><br />We can now group the behavior of a stack according to its different states. Note that for 'normal' state, we do not need to mention the use of any filter here, because the methods are not specialized on anything specific anyway. (Filtered functions always allow for 'regular' methods alongside the filtered methods.)<br /><pre><br />;;; Normal state<br /><br />(defmethod stack-push (stack value)<br /> (setf (aref (stack-contents stack)<br /> (stack-index stack))<br /> value)<br /> (incf (stack-index stack)))<br /><br />(defmethod stack-pop (stack)<br /> (decf (stack-index stack))<br /> (aref (stack-contents stack)<br /> (stack-index stack)))<br /><br />(defmethod stack-emptyp (stack)<br /> nil)<br /><br />;;; Empty state<br /><br />(defmethod stack-pop :filter :state ((stack (eql 'empty)))<br /> (error "Stack is empty."))<br /><br />(defmethod stack-emptyp :filter :state ((stack (eql 'empty)))<br /> t)<br /><br />;;; Full state<br /><br />(defmethod stack-push :filter :state ((stack (eql 'full)) value)<br /> (error "Stack is full."))<br /></pre><br />Note that we used a derived state function here, that determines the state of the stack based on some of its other properties. Since filter functions can be any functions, we could also use the reader of a slot as a filter function, and thus have the behavior of a filtered function depend on the explicit state of an object.<br /><br />Filtered functions can do a lot more: As already mentioned, they can use more than one filter; filter functions can see all the arguments a generic function receives; and filters can be guarded, which means that methods that use a particular filter may be completely ignored if the arguments don't fulfil a certain predicate. You can read the paper <a href="http://p-cos.net/documents/filtered-dispatch.pdf">Filtered Dispatch</a> that I co-authored with Charlotte Herzeel, Jorge Vallejos and Theo D'Hondt for a more thorough introduction, background information and semantics, and which also includes an extensible metacircular Lisp interpreter as an example, based on implementing EVAL as a filtered function.Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com4tag:blogger.com,1999:blog-20069114.post-32674466136217713962009-04-25T14:32:00.002+02:002009-04-25T14:57:31.198+02:00European Lisp Symposium 2009 - programme details!On May 27-29, there will be the <a href="http://www.european-lisp-symposium.org/">2nd European Lisp Symposium</a> taking place in Milan, Italy. The program looks very exciting, and I will definitely be there (well, due to obvious reasons, see below ;).<br /><br />For example, there are two keynote talks. One is by <a href="http://www.nhplace.com/kent/">Kent Pitman</a> who is an <a href="http://www.nhplace.com/kent/Papers/index.html">award-winning author of technical papers about Lisp</a>, editor of the ANSI Common Lisp specification, and designer of the <a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">HyperSpec</a>, the de-facto standard manual for Common Lisp. He will discuss how the Lisp community should move forward from his perspective. Kent's ideas are always well thought-out, although at times controversial, so this is certainly going to be a provocative talk.<br /><br />The other is by João Pavão Martins and Ernesto Morgado, the two owners of <a href="http://www.siscog.pt/">SISCOG</a> - a Portuguese company that develops <a href="http://www.siscog.eu/area.asp?idArea=1">large-scale industrial planning and scheduling software</a> which is in use for over twenty years. It's always good to hear what practitioners have to tell about their experiences with Lisp, so this should turn out quite interesting.<br /><br />There will be a couple of presentations in the main track of the symposium about papers that have been reviewed by a program committee chaired by António Leitão.<br /><br />Jim Newton is going to present a type inferencing approach for the Skill dialect of Lisp that is actually being used in his group at Cadence Design Systems, one of the world-wide largest providers of <a href="http://en.wikipedia.org/wiki/Electronic_design_automation">Eletronic Design Automation</a>. (If you use an eletronic device, it's very likely that the chips inside were designed using one of their tools!)<br /><br />Thomas Burdick is going to present an approach for compiling FEXPRs (think: first-class macros that you can pass around like regular functions). I'm a bit skeptical here that this will work, because it is actually known that <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.44.9264">FEXPRs cannot be compiled</a>, but maybe he has found an interesting twist to the problem.<br /><br />Some colleagues of mine from the <a href="http://arti.vub.ac.be/">Artificial Intelligence Lab of the Vrije Universiteit Brussel</a> in Belgium are going to present a debugging technique they have devolped for their own large-scale agent system that they use to investigate the possible <a href="http://www.emergent-languages.org/">development of natural languages</a> by reconstructing how they could have evolved from simple, first-class principles. The debugging approach consists of monitoring the activities of the agents and presenting the process as an interactive webpage that can present arbitrary detailed (or abstract) views on what is happening. Very cool stuff here, and since they use web technology here, it is actually portable...<br /><br />Charlotte Herzeel is going to present an architecture for Software Transactional Memory (STM). STM has become quite a hot topic in the last few years because it seems a very promising approach for dealing with concurrency, and since multicore processors are the buzz of the moment, there is a lot of interesting in such approaches. However, little attention has been payed to the design of STM frameworks where you can selectively plug in different STM algorithms. Charlotte has developed a reflective approach (think: metaobject protocol) for STM, which seems very promising (but I'm one of the co-authors of the paper, so I'm naturally biased, of course ;).<br /><br />Another presentation will be about <a href="http://en.wikipedia.org/wiki/Linda_(coordination_language)">Linda-style distribution layer</a> on top of Kenzo, an apparently very powerful system for symbolic computation developed in Common Lisp. The Linda Model (also used in JavaSpaces and TSpaces, for example) has a number of very interesting properties for distributed computing, and the paper presents an implementation based on <a href="http://www.franz.com/products/allegrocache/">AllegroCache</a>, a robust and high-performance object-oriented database for Allegro Common Lisp. I'm wondering what the concrete benefits for a symbolic algebra system are, so this is another presentation to look forward to.<br /><br />Finally, I am going to present a paper myself - that's the main reason why I will definitely be there ;). My presentation will be about a macro system on top of Common Lisp's macros that allows writing hygienic macros. The system provides facilities similar to <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.5184">Clinger's renaming construct</a>. The interesting part is that my system is implemented in fully portable Common Lisp and integrated in such a way that 'regular' Common Lisp macros and the macros developed with this new macro system can be used together. The reason why this works is because of the use of symbol macros in the implementation of the new constructs.<br /><br />Other items on the programme for the symposium are:<br /><br />A debate on expanding and updating the Common Lisp standard. I am known to be quite conservative when it comes to this topic, in that I don't think ANSI Common Lisp needs a serious revision, but can be developed in a piecemeal fashion (and this actually already happens due to the efforts of the currently very vibrant Common Lisp community). I believe (obviously) that something like <a href="http://cdr.eurolisp.org/">CDR</a> is much more promising than a "big bang" revision of the core language. The recent developments in the Scheme community, where the highly controversial <a href="http://www.r6rs.org/">R6RS specification</a> was <a href="http://www.r6rs.org/ratification/results.html">almost not ratified</a>, seems to indicate that the danger is too high that a lot of time and resources could be wasted that can otherwise be used in a much more productive way. Well, maybe there will be some new ideas and visions coming out of the debate...<br /><br />On the Saturday after the symposium, there will be a visit to the <a href="http://www.futurismo.milano.it/">Futurism exhibit in Milan</a>. Futurism was an art movement in Italy in the early 20th century, whose founders announced that everything "old" (so artistic and political tradition) should be replaced by the new ideas of a then young generation. This is probably one of the strangest choices for the social programme of a Lisp-related event: Lisp is second oldest programming language still in use today, and has always been in competition with whatever other programming language came along that was considered to be 'newer' (as if that automically meant 'better'). However, judging for example from <a href="http://newsblog.aboutitaly.net/2009/02/02/one-hundred-years-of-futurism-milan-celebrates-with-an-exhibition/en/">this blog posting</a>, this could actually be a very inspiring exhibition.<br /><br />So all in all, a highly interesting programme, with some more items being added in the coming days. (There are rumours that Christophe Rhodes is going to give a tutorial about non-portable features of <a href="http://www.sbcl.org/">SBCL</a>, for example!) Although the early registration deadline is ending very soon now, there is no reason to despair: With €80 for students and €160 for regular participants, the registration fees will remain very low.<br /><br />So, hope to see you in Milan!Pascal Costanzahttp://www.blogger.com/profile/04512975624438301971noreply@blogger.com4