Hacker News new | ask | show | jobs
by ljackman 2707 days ago
This approach being even viable is a testament to the host platform portability of Clojure, but even more to Common Lisp's ability to read other language's token-level syntax via reader macros (unless I've misunderstood how this projects ports Clojure to CL).

Reader macros in CL allow it to implement much of Clojure, but Clojure's lack of them means it could never implement CL unless it implemented built-in readers to handle every possible reader macro that a CL implementation loaded in.

As arbitrary library code can access the reader in CL, this would apparently be impossible.

I suppose it comes down to whether a Lisp dialect wants to support arbitrarily-powerful metalinguistic abstractions in its own Lisp syntax or provide the ability to create whole new languages with different fundamental tokens.

If a dialect only wants to achieve the former but has no interest in the latter, AST macros would suffice and custom reader macros would be of little interest, which is presumably the reasoning behind Clojure's lack of them.

Anyway, kudos for a great project.

1 comments

I'm not sure it is a good idea to use reader macros to implement the syntax. Probably better to implement a new parser for it.

The Clojure syntax is sufficiently different from Common Lisp, so that it might be a pain to implement that syntax as reader macros.

Generally I would think that reader macros are not a general mechanism to implement Lisp-like syntax, but specifically Common Lisp lexical syntax and extending/modifying it.

Well most closure syntax is pretty similar: change commas to whitespace, add delimited readers for [ and {. The hard parts are I think:

1. Package/namespace differences as CL has top level packages and clojure has nested packages. In CL keywords are symbols in the keyword package but in clojure they are symbols starting with a colon in any package.

2. Using e.g. {} or :for as a function

3. Different object systems.

If you want to parse pure Clojure lexical syntax with read tables, one has to get rid of all CL lexical syntax, otherwise it would parse a mix of Common Lisp and Clojure syntax.

Symbols in CL are totally different. There are escape characters and symbols can have different characters in their names. Symbols can start with numeric characters. / and . have no special meaning in CL. Keywords in CL don't need to start with : . If we want to read a Clojure keyword, one probably don't want to read a CL keyword, but a different data type.

Lists in CL don't exist. Instead we have cons cells with dot notation and list-like notation optimization. ( a b . nil) = (a b) = (a . (b . nil)), (a b . c). In Clojure there are no cons cells in the syntax. If you read (a . b) with the CL reader, then it is a cons cell, in Clojure it would be some kind of list with three elements. If you read (a b .) in CL, then one gets a reader error. Clojure does not care. (a . (b . nil)) in CL are two cons cells which form a single list, in Clojure it would be two nested lists.

CL has different numeric syntax. CL has various other notation for arrays, structures, bitvectors, ...

CL has no metadata. CL has different backquote syntax.

If one implements the Clojure reader stuff in

https://clojure.org/reference/reader#_reader_forms

one might as well implement the reader from scratch.