Skip to content

common lisp rosetta for the devs

o-jasper edited this page Mar 4, 2012 · 1 revision

#Common Lisp differences with Julia

A list of all CL language symbols. Note that 'some dude' wrote this stuff. Note that common lisp has too much in the spec and no standard libraries. Probably would have been better to separate the two.

defvar, defparameter

Not really the same as Julia toplevel variables, in CL these are special variables;

(defvar *special* 1)
(print *special*)    ; -> 1
(defun print-special () (print *special*))
(let ((*special* 2))
  (print-special)) ; -> 2 local variable went right through to the function body.
(print-special) ; -> 1

Can be useful in having basically a 'context' that you do not have to keep passing and accessing a 'context object'. Could to better than the asterix convention to remind that the vars are special.

Boolean stuff

There is a bool type in CL but stuff going to conditionals is rather different. nil is false, everything else is true. It can be handy, for instance (or a b c d) returns the first non-nil one. Guessing this is shallow though, could easily make something in Julia returning the first non-nothing or non-false one.

Defining functions

There is defun you can declare types, but basically defmethod just makes functions that 'are selected by type'. You can't select by type in local functions, and i think defmethod is a bit weaker that Julias abilities. (Of course a macro might be able to do that)

It forces you to make up your mind what the parameters of methods are in a defgeneric form. There might well be a good reason for that?! What are the caveits of function overloading?

case, typecase, cond

case basically a C switch type macro, you give a value and each clause has a value or list of values of which if any match, that clause is chosen.

Afaik Julia doesn't seem to have anything like that.

typecase is the same as case but instead of values, the user provides types. Can do much more than CLs defmethod. Of course defmethod and in Julia, typed functions can fill much of the role, selecting versions of an overloaded function instead of clauses.

cond fills the if .. .. elseif .. ., elseif ... else .. end-like stuff.

defmacro

Defines macros. Different with julia is that argument lists don't have to be flat for instance

(defmacro some-macro (a (b c) d) `(print ,a ,b ,c ,d))
(some-macro 1 (2 3) 4)  ; -> (1 2 3 4)
(some-macro 1 2 3)      ; -> macroexpansion-time error '2' should have been a list.

Defining macros seems a little trickier in some respects in Julia, and 'easier' in other respects. Making macros shouldn't be taken too lightly, usually you shouldn't.(where it is useful and mostly caveitless is usually either binding variables or defining stuff)

Probably more to say about the differences of representation of code in CL(just nested lists) and Julia.(Probably mostly Expr,QuoteNode objects)

destructuring-bind takes a list and similarly takes apart.(not seen it one Julia so far)

macrolet

Local macro. Not seen in Julia sofar, usual caveits of macros apply.

symbol-macrolet

'Local macros for symbols'. Have not seen this macro on julia yet. Caveit that in CL, let does not disable symbol-macrolet for the variables defined. (symbol-macrolet ((x y)) (let ((x 1)) x)) -> y not defined!

multiple-value-bind and values

values is somewhat like (a,b) notation but is hugely different in that you basically need to use the multiple-value-bind to get more than the first value back. values as CL does it can be handy when you want to return something that users might need but often just want to discard. But doesn't seem all that valuable.

compiler macros, define-compiler-macro

Adds a macro that will be called on a function call of that name. In Common Lisp these are identical to macros but for two big differences; they can return nil, and then the implementation will ignore that the 'macro' ever ran and just keep the function. Or it can return something else, and the code might be replaced.

This sounds like something that may be nice to have. Caveit is that it is a full macro and could do anything, they have to be made pretty carefully.(But it can probably exist alongside other optimization stuff)

loop, iterate

iterate is a library, for the record. Thought they should be mentioned. They're ... not horrible but i dont really like them either. for syntax plays some of the same roles in Julia.

Note that there are more libraries in CL that make various sorts of binding easier. (had a 'phase' wasting time making stuff like that use none now)

All the 'with' stuff

For instance lispbuilder-sdl has with-sdl if they're about creation and then destruction after you're done, destructors might be able to perform the same role. Most libraries like that have some with.. macro.

###with-slots, with-accessors Uses symbol-macrolet to attach accessing struct/class members to symbols. the struct.member notation is pretty short,(certainly shorter than (slot-value obj 'slot)) but getting them this may still be interesting to have in Julia.

with-open-file, with-input-from-string

Opens streams and closes them at the end of the macro body. Very useful. (destructors could do it?)

Docstrings

Julia throws a lot of line numbers in. So autodoccers should be able to find them and use them for autodocumentation. (I do not know how get a 'hook' on macroexpansion yet something like macroexpand-hook, but i found that weak, so i made this(shameless plug).

disassemble

I dont use it basically ever tbh, but it is awesome. It shows you the assembler bytecode or whatever such the CL implementation produces 'upon seeing that value'.

Annoying is to see how short it is but yet you cannot make a few-kilobyte binary with the compiler. -_-

Libraries

Alexandria

Alexandria is an oft-used macro for various function/macros that are a bit lacking in the CL spec.

rcurry, curry, compose

Various ways to 'fill in a variable' infront of in the back of a function or to compose functions. Can be slightly tricky to read; i just use one layer of these and proceed to lambda after that, but can make defining functions more convenient.

An more flexible but 'uglier-code-producing' way to the same is to access lambda quickly and without making a parameter list, by using numbered parameters.

if-let, when-let

Often you're only interested in a variable if it is non-nil, that is what these are for. In Julia things are a bit different; Julia requires a Boolean type. Still something like

if (x = 3)==3
  x
end

Seems to work; basically allowing binding of new variables anywhere.

with-gensyms also, it is covered by a,b = gensyms(2)

Automatic memoization. Never ended up using it, but sounds neat.

There was a 'superset-of-Haskell' lib somewhere..

Allows you to write code to write html inside a lispified html form that writes other html you want to write.

Sure i forget about things