Skip to content

Instantly share code, notes, and snippets.

What would you like to do?

From E. Fukamachi's blog:

Enable reader macros throughout the project

Recently the landing page of our new service "Pocket Change Pay" has been released.

Pocketpay is a platform that can make original electronic money . There is Pokethe like the mechanism that can also exchange money in the platform.

Although I said that I am working at Common Lisp since I changed my job last year, there was frustrating that I could not say I was asked what I was doing in concrete terms. I am making this.

Common Lisp is used for client side applications of server side and charge terminal such as API .

Today is a small story as to talk about Pokepei someday.

Common Lisp reader macro

Common Lisp has a function called "leader macro".

A leader macro is a function that allows you to hook in according to a specific character when you read the program and add your own processing. The process of hooking can be written by Common Lisp itself. This allows you to create your own syntax .

To give a concrete example Common Lisp in the annotation to introduce the " cl-annot Toka".

 ( defun foobar () 
   ... )

@ It combines with the following form by hooking up the letter to expand into the S expression.

( export 
  ( defun foobar () 
    ... ))

The so-called "macro" is compile- time, but it differs in that it is executed at a faster parsing time.

Since this cl - annot can also define annotations , "Caveman 2" of the lightweight web framework has annotations for routing .

@route GET  "/" 
( defun index () 
  ( render #P "index.tmpl" ))

@route GET  "/ hello" 
( defun say-hello ( & key  (| name |  "Guest" )) 
  ( format  nil  "Hello, ~ A"  | name )

Macros can do the same "function", but I like it in the sense that I will clarify the intention of "modification". For details of the reasons please refer to the article written long ago.

Use common readtable throughout the ASDF system

This leader macro is convenient as it is used (syntax:use-syntax :annot), but it is troublesome to have to write it at the beginning of a file . Even when using it, you can not use it unless you confirm "This annot is enabled in this file ...".

This is incompatible with package-inferred-system which splits the file especially for each package.

Anything related to syntax such as readtable in the first place requires agreement of all members of the project and there seems to be little demand to change the syntax for each file .

So, you can use common readtable with cl-annot enabled in the whole ASDF system? I thought and tried.

ASDF : around-compile

 (defsystem "pokepay-server"
   : class: package-inferred-system
   : version "0.1"
   : author "Pocket Change, Inc."
   : description "Pokepay Project API & Admin site."
   : depends-on ("pokepay-server / boot"
+: around - compile (lambda (thunk) 
+ (uiop: symbol - call: cl - syntax:% use - syntax: annot) 
+ (uiop: symbol - call: cl - syntax:% use - syntax: interpol) 
+ funcall thunk))
   : in-order-to ((test-op (test-op pokepay-server / tests))))

:around-compileIn the inner cl-syntax:use-syntaxjust are. In the above example, interpol is also enabled at the same time .

This will automatically enable annotation and character string interpolation for all files in ASDF 's system .


We introduced a method to enable the leader macro in the whole ASDF system. I actually use it in our application.

Eventually CL21 hash like a literal Toka regular expression literal might be interesting if carried out in the effective Toka.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.