Didier Verna's Sci-Blog

Lisp, XEmacs, LaTeX and random stuff...

Tuesday, May 22 2012

Clon 1.0b22 is out

A new version of Clon, the Command-Line Options Nuker is out.

The most important change in this release is the support for LispWorks, which brings the number of supported implementations to 8. One left to go, and I may eventually switch to RC status. Thanks to Martin Simmons for providing a fully functionnal version of LW 6.1. As for CLISP and Allegro, there is an optional dependency on CFFI for LispWorks.

Two backward incompatible changes that may affect you:

  • Variables renamings: *current-context* has been renamed *context*, and *default-synopsis* has been renamed *synopsis*. This should remain transparent unless you're using Clon in a somewhat advanced way.
  • clon:exit has been upgraded to SBCL's new quitting protocol. If you use this function (or if you want to compile the demo programs), please upgrade to SBCL 1.0.57.

Finally, support for terminal autodetection and stream handling in general has been improved for all implementations.

Grab it at the usual place.

Call for Papers: ACM SAC'13 PL: ACM Symposium on Applied Computing, Programming Languages track

CALL FOR PAPERS

SAC'13 - ACM 2013 SYMPOSIUM ON APPLIED COMPUTING
Technical Track on "Programming Languages"
March 18-22, 2013
Coimbra, Portugal


SAC '13
Over the past 27 years, the ACM Symposium on Applied Computing has become a
primary forum for applied computer scientists,
computer engineers, software engineers, and application developers from around
the world to interact and present their work.
SAC 2013 is sponsored by the ACM Special Interest Group on Applied Computing
(SIGAPP). For additional information, please
check the SAC web page: http://www.acm.org/conferences/sac/sac2013/. This
document is also available at:
http://www.cse.unt.edu/~bryant/sac2013/PL-SAC13-CFP.pdf

PROGRAMMING LANGUAGES (PL) TRACK

A technical track on Programming Languages will be held at SAC'13. It will be
a forum for engineers, researchers and practitioners throughout the world to
share technical ideas and experiences relating to implementation and
application of programming languages. Original papers and experience reports
are invited in all areas of programming languages. Major topics of interest
include but are not limited to the following:
− Compiling Techniques,
− Domain-Specific Languages,
− Formal Semantics and Syntax,
− Garbage Collection,
− Language Design and Implementation,
− Languages for Modeling,
− Model-Driven Development and Model Transformation,
− New Programming Language Ideas and Concepts,
− New Programming Paradigms,
− Practical Experiences with Programming Languages,
− Program Analysis and Verification,
− Program Generation and Transformation,
− Programming Languages from All Paradigms (Agent-Oriented, Aspect-Oriented,
Functional, Logic, Object-Oriented, etc.),
− Visual Programming Languages.

GUIDELINES FOR SUBMISSION

Paper submissions must be original, unpublished work. Submissions should be in
electronic format, via the START site:
https://www.softconf.com/c/sac2013/.
Author(s) name(s) and address(es) must not appear in the body of the paper,
and self-reference should be avoided and made
in the third person. Submitted papers will undergo a blind review process. 
Authors of accepted papers should submit an
editorial revision of their papers that fits within six two-column pages (an
extra two pages, to a total of eight pages,
may be available at a charge). Please comply with this page limitation already
at submission time. For accepted papers,
registration for the conference is required and allows accepted papers to be
printed in the conference proceedings.
For each accepted paper, an author or a proxy attending SAC MUST present the
paper. This is a requirement for the paper
to be included in the ACM/IEEE digital library. A set of selected papers,
which did not get accepted as full papers,
will be accepted as poster papers and will be published as extended 2-page
abstracts in the symposium proceedings.
After the conference, selected accepted papers will be invited to a special
issue of the Computer Languages, Systems and
Structures journal
(http://www.journals.elsevier.com/computer-languages-systems-and-structures/).

IMPORTANT DATES
September 21, 2012: Full Paper Submissions
November 10, 2012: Author Notification
November 30, 2012: Camera-Ready Copy

The SAC 2013 Programming Language Track Program Committee Members
Vasco Amaral, Universidade Nova de Lisboa, Portugal
Roberto da Silva Bigonha, Universidade Federal de Minas Gerais, Brasil
Haiming Chen, Chinese Academy of Sciences, China
Johan Fabry, University of Chile, Chile
Sebastian Guenter, Vrije Universiteit Brussel, Belgium
Gopal Gupta, University of Texas at Dallas, USA
Christian Haack, University of Nijmegen, The Netherlands
Christian Hammer, Saarland University, Germany
Matthias Hauswirth, University of Lugano, Switzerland
Pedro Henriques, University of Minho, Portugal
Michael Hind, IBM, USA
Nigel Horspool, University of Victoria, Canada
Zoltan Horvath, Eotvos Lorand University, Hungary
Bo Huang, Intel, China
Geylani Kardas, Ege University, Turkey
Shih Hsi "Alex" Liu, California State University, Fresno, USA
Hanspeter Moessenboeck, Johannes Kepler Universitat Linz, Austria
Jesús García Molina, University of Murcia, Spain
Nikolaos Papaspyrou, National Technical University of Athens, Greece
Corneliu Popeea, Technical University of Munich, Germany
Andre Santos, Universidade Federal de Pernambuco, Brazil
Bostjan Slivnik, University of Ljubljana, Slovenia
Didier Verna, EPITA, France
Wuu Yang, National Chiao-Tung University, Taiwan
Youtao Zhang, University of Pittsburgh, USA

Track Chairs
Marjan Mernik, University of Maribor, Slovenia, marjan.mernik@uni-mb.si
Barrett Bryant, University of North Texas, USA, Barrett.Bryant@unt.edu

Monday, May 14 2012

Monday Troll: the syntax extension myth

Here's a little Monday Troll.

To my greatest disappointment, I discovered today that it is not possible to replace Lisp parenthesis by, say, ... curly braces. What a shame. Hell, it's not even possible to freely mix the two. Very naively, I had expected that:

(set-macro-character #\{ (get-macro-character #\())
(set-macro-character #\} (get-macro-character #\)))

would suffice, but no. All implementations that I have tested seem to agree on this, although the error messages may differ. For instance, trying to evaluate {and} gives you an "unmatched close parenthesis error" except for CMU-CL which chooses to ignore it, but then report an end-of-file error. The unmatched close parenthesis, of course, is the closing curly brace! So what is going on here?

When an opening curly brace is read, the original left paren macro function is called. In SBCL for instance, this is SB-IMPL::READ-LIST, which looks for a hardwired right paren on the stream. Yuck. It doesn't find one, but it finds my closing brace which triggers the "standalone" right paren behavior (spurious paren alert). In passing, it also surprised me that SB-IMPL::READ-LIST is not implemented in terms of READ-DELIMITED-LIST.

EDIT: as mentioned in several comments, we could use read-delimited-list to look for a closing curly brace, but even this won't work completely. The problem is with dotted lists (see Pascal's comment). SBCL hard-wires #\) in its dotted lists parsing procedures.

So it appears that dispatching macro characters are only shaky. What we miss is a true concept of syntactic categories (Common Lisp character syntax types are close, but not quite there yet). In fact, TeX, with its notion of catcodes (category codes), seems to be the only language that gets this right. Ideally, any character with associated status LIST TERMINATOR should do as good as a right paren (the problem is only with closing, not opening).

Instead of hard-wiring the right paren in the Lisp parser, a quick workaround would be to check whether the next character on the stream is a dispatching one, and in such a case, whether its macro function is the one originally associated with the right paren. If so, it should then simply stand as a list terminator. This is actually an interesting idea I think: could the built-in macro functions become equivalent to actual category codes, and could we completely remove hard-wired characters in Lisp parsers?

Anyway, this whole story is a true scandal because it ruined an otherwise cool live demo of mine. So much for syntax extensibility. I will immediately complain to the concerned authorities.

Looking for the concerned authorities to complain to... please wait.

Wednesday, March 21 2012

Star TeX, the Next Generation

I'm happy to announce that my contribution to TUG 2012, the next TeX Users Group International conference, has been accepted. Please find the title and abstract below.



Star TeX, the Next Generation

In 2010, I asked Donald Knuth why he chose to design and implement TeX as a macro-expansion system (as opposed to more traditional procedure calls). His answer was that:

  1. he wanted something relatively simple for his secretary who was not a computer scientist,
  2. the very limited computing resources at that time practically mandated the use of something much lighter than a true programming language.

The first part of the answer left me with a slight feeling of skepticism. It remains to be seen that TeX is simple to use, and when or where it is, its underlying implementation has hardly anything to do with it.

The second part of the answer, on the other hand, was both very convincing and arguably now obsolete as well. Time has passed and the situation today is very different from what it was 50 years ago. The available computing power has grown exponentially, and so has our overall skills in language design and implementation.

Several ideas on how to modernize TeX already exist. Some have been actually implemented. In this talk, I will present mine. Interestingly enough, it seems to me that modernizing TeX can start with grounding it in an old yet very modern programming language: Common Lisp. I will present the key features that make this language particularly well suited to the task, emphasizing on points such as extensibility, scriptability and multi-paradigm programming. The presentation will include reflections about the software engineering aspects (internals), as well as about the surface layer of TeX itself. Most notably, I will explore the possibilities of providing a more consistent syntax to the TeX API, while maintaining backward compatibility with the existing code base.

Monday, March 12 2012

Clon 1.0b21 is out

One year between b19 and b20. 4 days between b20 and b21...

This new version of Clon introduces support for a new compiler, Allegro Common Lisp, in both standard and modern form. Support for dumping is only rudimentary for ACL (although it's only a marginal feature of the library). The dump macro uses Allegro's dumplisp mechanism to dump a lisp image which is not directly executable (full application delivery is complicated and only available in the Enterprise edition). Apart from that, the rest should work fine. As in the case of CLISP, Allegro may benefit from the presence of CFFI in order to provide terminal autodetection. This is an optional dependency only.

Grab it at the usual place.

Thursday, March 8 2012

Clon 1.0b20 is out

I'm happy to announce a new release of Clon, the Command-Line Options Nuker for standalone Common Lisp executables. In addition to a lot of uninteresting code and infrastructure changes, this new release comes with several important improvements and new features.

At the end-user level

  • there is a new error handler available via the --clon-error-handler option, called "interactive". This error handler provides the same restarts as the one called "none" (which actually triggers the Lisp debugger), but in a less frightening way for end-users not knowing about Lisp at all. In particular, the error and restart messages are more readable and you don't see a Lisp stack anywhere. See the end-user manual and the user manual for more information.
  • there is a new option called --clon-lisp-information which, as its name suggests, provides information about the underlying Lisp (implementation type and version). This will in fact be more useful for developers than for end-users, but it's still and end-user level feature. See the end-user manual for not much more information.

At the user-level

  • Clon now provides a command-line polling API through the functions cmdline-options-p and cmdline-p. See the user manual for more information.
  • Support for using Clon interactively, that is, without dumping executables has been improved. This is mostly useful for debugging purposes. See the user manual for more information.
  • Clon now provides a compile-time / run-time unified configuration facility thanks to a variable named cl-user::com.dvlsoft.clon.configuration that is handled before the ASDF system is loaded. Thanks to this, Clon is now able to communicate its own indentation information to (X)Emacs directly (thanks to a process that I've previously described here), and also handles portability problems in a smoother way (see below).
  • One of the available configuration options is called :restricted mode. In this mode, Clon never attempts to communicate with ttys via ioctl calls, at the expense of terminal autodetection (size and highlighting). This is implemented by making a termio ASDF module conditionally loaded in the system definition. There are cases where Clon will switch to restricted mode automatically (e.g. when using CLISP compiled without FFI support). However, some other situations are more problematic, for instance when using SBCL under MinGW, in which case the SB-GROVEL module is available but doesn't work. In such situations, it is necessary to configure Clon explicitely for restricted mode before loading the system. See the user manual for more information.


That's it. Grab it at the usual place. Yesterday, I realized that it's been slightly more than a year since the b19 release. Gee, time flies like the wind...

Monday, February 13 2012

ILC 2012 (International Lisp Conference)

The next ILC has been announced. It's going to take place in my favorite city in the whole world. Here's the original call for papers with all the important deadlines.

+----------------------------------------------------------------------+
|                                                                      |
|                  INTERNATIONAL LISP CONFERENCE 2012                  |
|                                                                      |
|             http://www.international-lisp-conference.org             |
|                                                                      |
|       Campus Plaza Kyoto, Kyoto, Japan -  October 21-24, 2012        |
|                                                                      |
|            Sponsored by:  The Association of Lisp Users              |
|                                                                      |
+----------------------------------------------------------------------+

   General Information:

     The Association of Lisp Users is pleased to announce the 2012
     International Lisp Conference will be held in Kyoto, Japan at
     Campus Plaza Kyoto from October 21st to 24th, 2012.

     This year's program consists of tutorials at beginners' and
     advanced levels, prominent invited speakers from the Lisp
     communities, an excellent technical session, tours of
     Jidai-Matsuri: festival enjoyed by people of all ages,
     participating in its historical reenactment parade dressed in
     authentic costumes representing various periods, and characters
     in Japanese feudal history.

     General conference announcements are made on a very occasional
     basis to the low-volume mailing list
     ilc12-announce. http://www.alu.org/mailman/listinfo/ilc12-announce

   Technical Program:

     Original submissions in all areas related to the conference themes
     are invited for the following categories:

     Papers: Technical papers of up to 15 pages that describe original
     results.

     Demonstrations: Abstracts of up to 2 pages for demonstrations of
     tools, libraries and applications.

     Workshops: Abstracts of up to 2 pages for groups of people who
     intend to work on a focussed topic for half a day.

     Tutorials: Abstracts of up to 2 pages for indepth presentations
     about topics of special interest for 90 - 180 minutes.

     Panel discussions: Abstracts of up to 2 pages for discussions about
     current themes. Panel discussion proposals must mention panel
     member who are willing to partake in a discussion.

     Lightning talks: Abstracts of up to one page for talks to last
     for no more than 5 minutes.


   Important Dates:

     Please send contributions before the submission deadline, including
     abstracts of 4 pages for technical papers and abstracts of 2 pages
     for all other categories.

     Deadline for abstract submissions: July 15, 2012
     Notification of acceptance or rejection: July 31, 2012
     Deadline for final paper submissions: August 31, 2012

     Papers to be presented should be submitted electronically at
     easychair 
     (https://www.easychair.org/account/signin.cgi?conf=ilc2012)
     and need to use the ACM format
     (http://www.acm.org/sigs/publications/proceedings-templates)

   Scope:

    Lisp is one of the greatest ideas from computer science and a
    major influence for almost all programming languages and for all
    sufficiently complex software applications.

    The International Lisp Conference is a forum for the discussion of
    Lisp and, in particular, the design, implementation and
    application of any of the Lisp dialects.  We encourage everyone
    interested in Lisp to participate.

    We invite high quality submissions in all areas involving Lisp
    dialects and any other languages in the Lisp family, including,
    but not limited to, ACL2, AutoLisp, Clojure, Common Lisp,
    ECMAScript, Dylan, Emacs Lisp, ISLISP, Racket, Scheme, SKILL, etc.

    Topics may include any and all combinations of Lisp and:

      * Language design and implementation
      * Language integration, inter-operation and deployment
      * Applications (especially commercial)
      * Reflection, meta-object protocols, meta-programming
      * Domain-specific languages
      * Programming paradigms and environments
      * Parallel and distributed computing
      * Theorem proving
      * Scientific computing
      * Data mining
      * Semantic web


   Organizing Committee:

     General Chair: KURODA Hisao (Mathematical Systems Inc. / ALU)
     Members: Daniel Herring (ALU)
              Jon L White (ALU)
              Rusty Johnson (ALU)

     Program Chair: Hiroshi Okuno (Kyoto Univ.)
     Members: Keith Corbett (Clozure Associates)
              Alex Fukunaga (University of Tokyo)
              Antonio Leitao (INESC-ID)
              Joe Marshall (MIT)
              Scott Mckay (ITA software)
              Nancy Reed (University of Hawaii)
              Kent Pitman (nhplace.com)
              Duane Rettig (Franz Inc.)
              Didier Verna (EPITA)
              Takuo Watanabe (Tokyo Institute of Technology)
              Edi Weitz (weitz.de)
              Taiichi Yuasa (Kyoto University)

     Local chair: Tetsuya Ogata (Kyoto Univ.)
     Members: CHIBA Masaomi
              SANO Masatoshi

  Contacts:

    * General Questions: ilc12-organizing-committee at alu.org
    * Program Committee: ilc2012 at easychair.org

For more information, see http://www.international-lisp-conference.org

Tuesday, January 31 2012

JSPP: Morphing C++ into JavaScript

I'm happy to announce the publication of a new technical report entitled JSPP: Morphing C++ into JavaScript. The abstract is given below.

In a time where the differences between static and dynamic languages are starting to fade away, this report brings one more element to the "convergence" picture by showing that thanks to the novelties from its recent 0x standard, it is relatively easy to implement a JavaScript layer on top of C++. By that, we not only mean to implement the language features, but also to preserve as much of its original notation as possible. In doing so, we provide the programmer with a means to freely incorporate highly dynamic JavaScript-like code into a regular C++ program.

Tuesday, January 17 2012

Patcher 4.0 is released

I'm happy to announce the release of Patcher version 4.0. This is a major release introducing many new features and enhancements.

Patcher is a tool designed to automate and ease the maintenance of archive-based projects. It provides assistance in building, reporting and committing patches, as well as in handling the corresponding ChangeLog entries, for example by creating skeletons. Patcher is the official tool for XEmacs development.

NEW FEATURES

  • Support floating projects and temporary relocation allowing to use the same project descriptor for various directories.
  • Support for automatic detection of submodules via the :submodule-detection-function project option and the patcher-detect-submodules function. Currently supported RCS submodules are Mercurial and Git via the functions 'patcher-hg-detect-submodules.
  • Support ephemeral ChangeLogs thanks to a new :change-logs-status project option. Ephemeral ChangeLogs are not stored in ChangeLog files, but exist only temporarily for mail or log message insertion (See ChangeLogs Status in the documentation).
  • ChangeLog minor mode providing easy navigation through the mail/ChangeLog buffers cycle via C-c C-p n, C-c C-p p, C-c C-p N, C-c C-p P and C-c C-p m (See ChangeLogs Navigation in the documentation).
  • Support for switching to mail buffer and inserting ChangeLogs at once via C-c C-p l from ChangeLog buffers.
  • patcher-mail-insert-change-logs gets a prefix argument allowing to temporarily change the ChangeLogs appearance. It also supports inserting ChangeLogs even when the project is set not to.
  • Additional binding for patcher-logmsg-commit: C-c C-p c
  • Commit command buffer is now editable Commit is done via C-c C-p c or C-c C-c (patcher-cmtcmd-commit).
  • Fontification of commit command and log message buffers with comment syntax and initial informative help. See new Patcher faces.
  • Support for commit or log message canceling via C-c C-z.
  • Support for project abortion via C-c C-p k or C-c C-k in all relevant buffers, including ChangeLogs.
  • Support Subject: header modification in mail adaptation routines via a new project option :subject-rewrite-format.
  • Support project-wide dynamic subject modification via C-c C-p S in both mail and log message buffers.
  • Implement :kill-source-files-after-sending project option
  • Support for source file saving
  • Support for CVS diff's broken exit code policy via a new project option: :ignore-diff-status.

FIXES AND IMPROVEMENTS

  • Improved support for temporary subprojects making them behave like permanent ones (with a specific subdirectory and set of files).
  • Much better error handling including exit code checking for external processes.
  • Improved support for overlapping Patcher instances through buffer and file referencing for both ChangeLog and source files.
  • Documentation rewrite and sections organization cleanup
  • More checks for project consistency including missing or spurious ChangeLog entries, source diffs, undiffable and uncommittable projects etc.
  • Improved project rediffing including support for partially generated ChangeLog skeletons, and interactive prompting for skeleton un/re-generation.

BACKWARD INCOMPATIBLE CHANGES

  • Mercurial themes renamed from 'mercurial to 'hg in order to remain consistent with the other RCS theme names.
  • ChangeLogs insertion in mail buffers rebound to C-c C-p l
  • Compressed ChangeLogs insertion in logmsg buffers rebound to C-c C-p L
  • Removed directory-sep-char hacks until the need for it raises again. Probably better implemented via project options anyway.
  • Diff commands can no longer be changed from patcher-mail-adapt but instead, the prefix argument allows for temporary subproject specification.
  • patcher-*-subproject entry points removed since they are no longer needed (see above).
  • Removed :kill-source-file-after-diffing option
  • :kill-source-files-after-sending renamed to :kill-sources-after-sending
  • patcher-mail-check-change-logs-insertion is now a project option named :check-change-logs-insertion.
  • patcher-mail-check-commit-action is now a project option named :check-commit.
  • :change-logs-diff-command option now understands nil instead of 'diff
  • The 'packed ChangeLogs appearance has been renamed to 'pack

Tuesday, January 3 2012

ACCU 2012 session on language extensibility

I'm pleased to announce that I will hold a 90 minutes session on language extensibility at the next ACCU conference. A shortened abstract is given below (a longer one is available at the conference website).

Impact of Extensibility on Domain Specific Language Design and Implementation

Domain-specific languages (DSLs) are usually very different from the general purpose language (GPL) in which the embedding application is written. The need for designing a DSL as a completely new language often comes from the lack of extensibility of the chosen GPL. By imposing a rigid syntax, a set of predefined operators and data structures, the traditional GPL approach leaves no choice but to implement a DSL as a different language, with its own lexical and syntactic parser, semantic analyzer and possibly its own brand new interpreter or even compiler.

Some GPLs, however, are extensible or customizable enough to let one implement a DSL merely as either a subset or an extension of the original language. While the end-user does not see a difference with the traditional approach, the gain for the developer is substantial. Since the DSL is now just another entry point for the same original GPL, there is essentially only one application written in only one language to maintain. Moreover, no specific language infrastructure (parser, interpreter, compiler etc.) is required for the DSL anymore, since it is simply expressed in terms of the original GPL.

The purpose of this presentation is to illustrate the most important factors that make a language truly extensible, and to show how extensibility impacts the process of DSL design and implementation.

Tuesday, December 27 2011

XEmacs now has a "foreback" face property

The "foreback" face property at workHere's another new face property in XEmacs. This one is probably not going to be used ever, but still it fixes one particular problem. Until now, XEmacs used the background and foreground colors to display a face background bitmap (as opposed to a regular pixmap). This basically rendered the text unreadable.

The new face property is called "foreback" (I'm running short of sensible property names these days). It's the "foreground of the background" if you will. When a face has a background bitmap, it uses the regular background color for bitmap's background, but the foreback color for the bitmap's foreground. See the attached screenshot for a concrete example of the problem it fixes.

The bitmap I used for this example is X11's xsnow bitmap. Nice Christmas XEmacs screenshot, isn't it? :-)

In order to set a face's foreback color, either use the Custom interface, or the set-face-foreback function.

Thursday, December 22 2011

XEmacs now has a "flush" face property

The "flush" face property at workI have just implemented a new face property in XEmacs 21.5, called "flush". When some text is displayed in a face which has this property set to t (it's a Boolean property), then the face extends until the right border of the window instead of just the end of the actual line of text. The effect is only visible if the face has a non-default background color or pixmap and gives the text segment the appearance of a block instead of being ragged right. In fact (if that rings a bell to you), this is the equivalent of the block value for the HTML display property.

See the attached screenshot for an example. In that particular case, the buffer displays an article in Gnus and the concerned face is mm-uu-extract. You can see two versions of the same buffer, with and without the property set. There are a number of situations in which setting a face to flush is nicer visually. Probably the most obvious case is that of text selection. Below is a list of faces that I'm currently setting to flush. I'll be updating this list as needed. In order to set a face to flush, either use the Custom interface or the set-face-flush-p function directly.

zmacs-region
diff-nonexistent-face
gnus-summary-cancelled[-face]
mm-uu-extract
mmm-default-submode-face
mmm-code-submode-face

Monday, November 28 2011

CL-RCFiles 2.0

Just a quick note to mention the release of CL-RCFiles 2.0. This version adds pre-loading initialization files. From the README file:

This very small Common Lisp library provides a way to add initialization files to ASDF systems. Every time ASDF loads <system>, one or several corresponding <system>.lisp files are loaded automatically afterwards. This lets you conditionally plug in additional behavior on a per-system basis without cluttering up any global Common Lisp init file.

By default, these initialization files are expected to be found in: - ~/share/common-lisp/rc/pre/ for pre-loading initialization, - ~/share/common-lisp/rc/post/ for post-loading initialization.

For backward-compatibility, files found directly in the rc/ directory are considered to be post-loading initialization files.

You can modify the rc-files location by changing the values of the global variables *directory*, *pre-directory*, and *post-directory*.

Get it here.

Tuesday, October 25 2011

ILC 2012

The ALU has announced the next International Lisp Conference. ILC 2012 will take place at the end of October or Early November. I can't wait to meet the international Lisp crowd again, and what's more, in Kyoto, my favorite city in the world! I think I will take the opportunity to buy a new Hakama there. Maybe a Noren or two as well...

In the meantime, stay tuned for the next European Lisp Symposium, to occur in Zadar (Croatia) sometime around end April / early May 2012 !

John McCarthy died last night

John McCarthy John McCarthy, the creator of the most elegant and powerful language ever, has died. I won't repeat what others in the Lisp community are and will be saying all over the place in the next few days. There is only one thing I would like to say right now: I remember him, and I am very happy (for him) that he was still here with us to celebrate the 50th anniversary of his wonderful baby...

 

Wednesday, July 20 2011

One more indentation hack

Here's yet another indentation hack that I came up with recently.

All the work done by Nikodemus on the Slime indentation contrib is pretty cool, especially the notion of indentation style (though I wish the styles were Custom variables, but that is another story). I tend to use indentation styles for global, maybe collaborative preferences, but on several occasions however, I find that this approach has a couple of drawbacks.

  • One of them is that the indentation information is far away from the corresponding symbol, in a separate file. If you change a function's prototype for instance, you may also need to load the file(s) in which the corresponding style(s) is (are) defined and edit them.
  • The other problem is that if you want to let other people edit your source code and honor your indentation style, you also need to provide them with the style definition, and they need to load it separately.

For those reasons, I tend to think that the indentation style approach is not very well suited for project-specific indentation settings. What I would like is to provide indentation information close to the function definition, and also to have that information automatically available when anyone loads the project into Slime. Here's a way to do it.

The key to success here is the function swank:eval-in-emacs which, as its name suggests, sends some Emacs Lisp code to your (X)Emacs session for evaluation. This function effectively allows you to trigger some Emacs Lisp computation from a Common Lisp file. Remember that indentation information is stored in the common-lisp-indent-function property of a symbol. The function clindent below does this:

(defun clindent (symbol indent)
  "Set SYMBOL's indentation to INDENT in (X)Emacs.
This function sets SYMBOL's common-lisp-indent-function property.
If INDENT is a symbol, use its indentation definition.
Otherwise, INDENT is considered as an indentation definition."
  (when (and (member :swank *features*)
	     (let ((configuration
		     (find-symbol "MY.PACKAGE.CONFIGURATION" :cl-user)))
	       (when (and configuration (boundp configuration))
		 (getf (symbol-value configuration) :swank-eval-in-emacs))))
    (funcall (intern "EVAL-IN-EMACS" :swank)
	     `(put ',symbol 'common-lisp-indent-function
		   ,(if (symbolp indent)
			`(get ',indent 'common-lisp-indent-function)
		      `',indent))
	     t)))

As explained in the docstring, this function will ask (X)Emacs to put SYMBOL's common-lisp-indent-function property to a definition, either provided directly, or retrieved from another symbol. For example, if your package defines an econd macro, you may want to call it like this:

(clindent 'econd 'cond)

This function ensures that Swank is actually available before using it (first condition in the and clause). I will explain the other weird bits later on.

The next question is when exactly do we want to call this function? The answer is: pretty much on all occasions. Your code might be loaded from source and interpreted, or it might be compiled. But then, it might be compiled within or outside a Slime environment. In any case, you want your indentation information to be sent to (X)Emacs everytime it's possible. So obviously, we're gonna wrap this function in an eval-when form thanks to a macro. This is also a good opportunity to save some quoting.

(defmacro defindent (symbol indent)
  "Set SYMBOL's indentation to INDENT in (X)Emacs.
SYMBOL and INDENT need not be quoted.
See CLINDENT for more information."
  `(eval-when (:compile-toplevel :execute :load-toplevel)
     (clindent ',symbol ',indent)))

And now, right on top of your econd definition, you can just say this:

(defindent econd cond)

Now here's one final step. If your package uses its own readtable, it's even more convenient to define a reader-macro for indentation information. I choose #i:

(defun i-reader (stream subchar arg)
  "Read an argument list for the DEFINDENT macro."
  (declare (ignore subchar arg))
  (cons 'defindent (read stream)))
 
(set-dispatch-macro-character #\# #\i #'i-reader *readtable*)

And now, the code in my package will look like this:

#i(econd cond)
(defmacro econd #|...|#)

Pretty cool, eh?

All right. We still have two weirdos to explain in the clindent function.

First, you noticed that the function's computation is conditionalized on the existence of a cl-user::my.package.configuration variable, which actually stores a property list of various compiling or loading options for this package. The option we're interested in is :swank-eval-in-emacs, which must be set to non-nil. Here's why. The execution of Emacs Lisp code from Swank is (rightfully) considered as a security risk so it is disabled by default. If you want to authorize that, you need to set the (Emacs) variable slime-enable-evaluate-in-emacs to t. Otherwise, calling swank:evaluate-in-emacs is like calling 911. So we have a chicken-and-egg problem here: if we want to avoid an error in clindent, we would need to check the value of this variable, but in order to do that, we would need to evaluate something in (X)Emacs ;-)

The solution I choose is hence to disable the functionality by default, and document the fact that if people want to use my indentation information, they need to set both the Slime variable and my package-specific option to non-nil before loading the package (possibly setting them back to nil afterwards). They also need to trust that I'm not going to inject anything suspicious into their (X)Emacs session at the same time...

The last bit we need to explain is the final t argument passed to swank:eval-in-emacs. The corresponding parameter is called nowait in the function's prototype. It has something to do with asynchronous computation, and in fact, I don't really know what's going on under the hood, but what I do know is that if you set it to t, Swank doesn't care about the return value of your form anymore, which is fine because we're only doing a side effect. On the other hand, if you omit that parameter, Swank will try to interpret the return value in some way, and you will most probably get a serialization error. Indeed, the return value is the indentation definition itself, so for example, (&rest (&whole 2 &rest 1)) doesn't make (Common Lisp) sense.

That's it. Happy indenting!

Tuesday, July 19 2011

LaTeX Coding Standards

I'm happy to announce that my contribution to TUG 2011, the next TeX Users Group International conference, has been accepted. Please find the title and abstract below.



LaTeX Coding Standards

Because LaTeX (and ultimately TeX) is only a macro-expansion system, the language does not impose any kind of good software engineering practice, program structure or coding style whatsoever. As a consequence, writing beautiful code (for some definition of "beautiful") requires a lot of self-discipline from the programmer.

Maybe because in the LaTeX world, collaboration is not so widespread (most packages are single-authored), the idea of some LaTeX Coding Standards is not so pressing as with other programming languages. Some people may, and probably have developed their own programming habits, but when it comes to the LaTeX world as a whole, the situation is close to anarchy.

Over the years, the permanent flow of personal development experiences contributed to shape my own taste in terms of coding style. The issues involved are numerous and their spectrum is very large: they range from simple code layout (formatting, indentation, naming schemes etc.), mid-level concerns such as modularity and encapsulation, to very high-level concerns like package interaction/conflict management and even some rules for proper social behavior.

In this talk, I will report on all these experiences and describe what I think are good (or at least better) programming practices. I believe that such practices do help in terms of code readability, maintainability and extensibility, all key factors in software evolution. They help me, perhaps they will help you too.

Wednesday, June 29 2011

Declt 1.0b12 is out

I've just released the next version of Declt, my reference manual generator for ASDF systems.

This release includes some fixes for the Info format target but most notably, support for documenting (generic) writer functions and methods. When it makes sense, the documentations for func and (setf func) are grouped together. Getting closer to an official 1.0 stable version...

Grab it here, and enjoy!

Tuesday, June 21 2011

read-time string concatenation

Sometimes, I miss the string concatenation capability of C. I mean, the way that you can split a long string into smaller ones and have them automatically concatenated together. The format function has a tilde (~) directive that does something along these lines, but there are two problems:

  • first, I'm not necessarily facing the problem in format calls,
  • next, my favorite text editor cannot properly indent the string contents when I press the TAB key.

Here's an example:

(defclass sample ()
  ((slot :documentation
	 "A very long slot documentation, that doesn't even fit in 80 columns, which is a shame...")))

If that were C code, I could write this:

(defclass sample ()
  ((slot :documentation
	 "A very long slot documentation, "
	 "that doesn't even fit in 80 columns, "
	 "which is a shame...")))

But (thank God) this is not C code. We can come very close to that however. Here's a small reader function that will automatically concatenate strings prefixed with a tilde (~) character (in honor of format's directive):

(defun tilde-reader (stream char)
  "Read a series of ~\"string\" to be concatenated together."
  (declare (ignore char))
  (flet ((read-string (&aux (string (read stream t nil t)))
	   (check-type string string "a string")
	   string))
    (apply #'concatenate 'string
	   (read-string)
	   (loop :while (char= (peek-char t stream nil nil t) #\~)
		 :do (read-char stream t nil t)
		 :collect (read-string)))))

Let's add it to the current readtable:

(set-macro-character #\~ #'tilde-reader)

And now I can write this:

(defclass sample ()
  ((slot :documentation
	 ~"A very long slot documentation, "
	 ~"that doesn't even fit in 80 columns, "
	 ~"which is a shame...")))

Everyday of my life I thank Common Lisp for being so flexible. The next step would be to make cl-indent.el aware that tilde-strings really are the same object, and hence should be vertically aligned in all contexts. I'm not there yet. Jeeze, this indentation hacking will never end... :-)

Tuesday, May 31 2011

Declt 1.0b11 is out

I've just released a new version of Declt, my Texinfo reference manual generator for ASDF systems. This release contains only one bugfix: when trying to create links to source files, Declt now checks whether the files actually exist or not.

Tracking this bug down had the side-effect of exhibiting a misfeature of SBCL's introspection facility: the COPY-<struct> functions (automatically generated by defstruct calls) have their definition source set to target-defstruct.lisp which is an SBCL source file. It would make more sense to set it to the file containing the defstruct call instead, as is already the case for constructors, predicates and accessor functions. Patch sent to the SBCL developers.

- page 1 of 5