-
Notifications
You must be signed in to change notification settings - Fork 1
common lisp rosetta for the devs
#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.
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.
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.
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
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.
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)
Local macro. Not seen in Julia sofar, usual caveits of macros apply.
'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!
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)
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)
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.
Opens streams and closes them at the end of the macro body. Very useful. (destructors could do it?)
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).
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. -_-
Alexandria is an oft-used macro for various function/macros that are a bit lacking in the CL spec.
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.
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.
Allows you to write code to write html inside a lispified html form that writes other html you want to write.