
How to write Common Lisp in 2017 – an initiation manual - macco
http://articulate-lisp.com
======
hydandata
I started a big project at work using Common Lisp in 2017 and could not be
happier. Sure, most nice features have trickled down to other languages, but
they are rarely as nicely integrated. And Lisp still has many advantages that
are not found elsewhere: Unmatched stability, on-demand performance, tunable
compiler, CLOS, condition system, and Macros to name a few. It has its warts
too but which language does not?

I found lack of high quality library documentation a bit annoying, but a non-
issue, there were tests and/or examples included in practically all of the
libraries I have used so far.

Lastly, this rarely gets brought up, but I think Common Lisp has some of the
best books available out of any programming language. The fact that it is so
stable means that most of material, and code, from the end of 80's and 90's is
quite relevant today, and new stuff is being written.

The biggest downside is that it makes JavaScript and Python revolting to work
with. But I can still enjoy SML for example.

~~~
shady-lady
Curious over why CL vs Clojure? Any comments.

~~~
Guthur
I have used both in production setting and can say that the tooling for most
CL implementations is just plain light years ahead of Clojure, and there is no
sign of it really improving.

For Clojure the interactive debugging experience is just plain dreadful and
for a dynamic language this is pants on head crazy imo. For me a dynamic
language has to have a good interactive debugging experience because you have
foregone the support of a static compilation and instead wish to reason about
your program at runtime. But with the JVM stack traces and lack of interactive
debugger Clojure just does not support you in this regard. And as a side note
the lack of an identity print is annoying as well e.g. (+ (print 4) (print 4))
"4" "4" 8 (yes, it's easy to add...)

Clojure's decision to use persistent data structures is good but it's really
the only standout thing for me other than some syntax sugar like hash maps.

~~~
cdegroot
The JVM indeed quickly got me disinterested in Clojure. However, I have
similar issues with other (free) Lisps, with probably only Emacs Lisp being
the exception.

As a Smalltalker ("the other heroin of the programming world") I'm used to a
highly integrated and responsive development environment; from what I heard
from other Lispers, the quick feedback and gradual building up of your program
is a shared aspect, but the thing that Smalltalkers always bring up and
Lispers less so is also that your program and your IDE are basically
indistinguishable, which is quite powerful because it makes it trivial to
adapt your IDE to your project as you go. In the Lisp environments I've tried
- latest being Emacs+SBLC - the split between editor and REPL seems unnatural
to me, more so because in the standard case you work with two different
dialects of the language. It seems that only ACL and LW have more unification.

Am I wrong and are the $$$$ versions not better in that respect and should I
just drop my Smalltalk habits/arguments when learning CL?

~~~
lispm
> also that your program and your IDE are basically indistinguishable

Lisp provides that,too. But you can also deliver programs with the IDE and
much of the development tools removed.

Examples for integrated IDEs:

Allegro CL on Windows/Unix+Gtk, Clozure CL (free) on Macs, LispWorks on
Windows/Macs/Unix+GTK/Unix+Motif. There the IDE and the user code runs in one
Lisp. Other examples: Lisp Machines, CMUCL on X11, ... there is also the
McCLIM project where some ideas from the Symbolics GUI are used.

There are also countless other implementations from the past, which are now
mostly forgotten, which had an integrated IDE (Golden Common Lisp for Windows,
Corman Lisp for Windows, Macintosh Common Lisp, Medley, Open Genera for
X11...),

~~~
vram22
Hi,

I read this article on your site:

[http://lispm.de/why-lisp-is-different](http://lispm.de/why-lisp-is-different)

Quote from it:

[ When in doubt design software to be introspective.

when in doubt design software to be reflective. ]

What is the difference between introspective and reflective? I've used
introspection in Python and know about and used (a bit) reflection in Java
earlier, but thought they were roughly the same sort of thing. Please explain
the difference if possible.

~~~
lispm
Introspection means that the program's structures and procedures are
discoverable and we can query about them. Typical questions we might want to
have answers for:

* find me the class, typically by name or by some relationship

* what are the fields of that class?

* find me a function

* what are the arguments of the function? does it have documentation? Who wrote it? Where is its source? What values does it return?

* where is the function used? what functions does it call?

* what are the values of a field of some object? What class does it have?

This and more for example enables you to inspect a program at runtime and find
out what it does, how it does it and what its state currently is.

Reflection means that elements of the programming language are itself exposed
and we can change/extend them.

Two examples of the Lisp world. Very unusual is the reflective tower, where a
Lisp program is run by some kind of machine, which for example is a Lisp
interpreter. This Lisp interpreter is itself a Lisp program. Thus you can not
only write the program, but you can change/extend the interpreter running the
program. A certain Lisp dialect allowed also to look at the interpreter
running the interpreter running the interpreter running the interpreter ...

In Common Lisp a typical form of reflection is the Meta-Object Protocol of
CLOS. It allows you to program the object system to implement new variants:
persistent objects, transactions over objects, different inheritance
mechanisms, classes which record their instances, ... Thus the MOP exposes
classes, methods, generic functions, slot descriptors, ... as CLOS classes and
methods - and protocols about them. Thus CLOS can be programmed in itself.
Even at runtime.

More primitive reflection would allow you to create/change/remove things like
user classes and user methods. Task: create a new subclass of an existing
class at runtime.

~~~
vram22
Interesting, and thanks for the answer. It's a while ago, but when I used
reflection in Java (in v1.4, IIRC), what it did seemed like some of the
capabilities you describe under introspection above. Maybe they just used a
different term for it than you do. Example: Finding the methods of a class and
calling them dynamically at runtime, finding the number and types of the
arguments of a method, etc. These capabilities were part of the java.reflect*
package, IIRC.

~~~
lispm
[https://en.wikipedia.org/wiki/Type_introspection](https://en.wikipedia.org/wiki/Type_introspection)

> Introspection should not be confused with reflection, which goes a step
> further and is the ability for a program to manipulate the values, meta-
> data, properties and/or functions of an object at runtime.

~~~
vram22
Thanks.

------
yarrel
I'd replace the first few steps with "Install Roswell" -

[https://github.com/roswell/roswell](https://github.com/roswell/roswell)

Roswell will install a Lisp and QuickLisp for you, and give you a single point
of entry to install libraries, create and run code, and launch en editor
(Emacs with Slime of course).

I can't recommend it highly enough (I'm nothing to do with the project, just a
very happy user).

~~~
iak8god
Neat. Does Roswell do all this without modifying your current
lisp/emacs/slime/quicklisp if you already have them set up the way you like
but want to play around with it?

And is there something like Roswell for Clojure?

~~~
aidenn0
I don't know about emacs/slime, but it can manage local quicklisp and local
implementations (and even have e.g. multiple sbcl versions installed
simultaneously).

~~~
nerdponx
This sounds a lot like Pyenv and Virtualenv for Python. Neat!

~~~
_pmf_
I don't like Clojure (any more), but one nice thing about it is that is
includes the Clojure implementation itself as regular versioned dependency on
a project-by-project base (thanks to the transparent usage of Maven by the
leiningen build tool). Once you tried this, everything else feels like a
cludge; there's simply no reason the language version should be managed by
some obscure mechanism instead of being a regular dependency!

------
Scarblac
I'm used to languages like Python, that have a number of files that are
modules, and to start a program you run one of them as an entry point.

C programs consist of a lot of files that are compiled and linked into a
binary executable.

Whenever I've tried to learn CL, I couldn't really wrap my head around what
the eventual program would be. You build an in-memory state by adding things
to it, later dump it to a binary. How do you get an overview of what there is?

I'm just too used to my files, perhaps. Or I'm missing something.

~~~
brudgers
I mentioned elsewhere I'm learning Common Lisp. I'm also learning Python by
translating some Common Lisp code into Python and part of that is to make sure
I understand what the Common Lisp is doing. As an understatement, that's meant
building some very unPythonic abstractions (yay, me).

Anyway, I think there is a fundamental design difference between Common Lisp
and other 'first class' programming languages: Common Lisp was designed as a
way to _use_ computers because a computer user would sit down at a Lisp
Machine (which was the future when Common Lisp was designed) and use Common
Lisp to do ordinary computer stuff like store their recipes and manage
appointments and copy files between directories. It's reflected in the :cl-
user package not being called :cl-programmer and the logic of typing (in-
package :tps-report) on Saturday at the usual time.

Most other languages don't have this idea...In Unix users don't fool around
with stdio.h. In Python, there's no clean way of switching between
applications at the REPL -- or rather interpreter -- because of how Python
handles the hard job of naming things (like most languages, there's a bit of
punting on third down with the catchall epithet 'unpythonic').

This makes it hard to get one's head around Common Lisp, but it explains why a
person might leave a REPL running for a week _and_ make better progress
because of it.

~~~
ScottBurson
I have a couple REPLs for specific projects that I routinely keep running for
months at a time.

The idea that user = programmer was part of the MIT AI Lab culture before
there were Lisp Machines. For example, the top level of ITS, the PDP-10 OS
they used, was the debugger. Imagine if the default Linux shell was GDB!

~~~
ihaveajob
That's kind of how my old MSX was, essentially a MS Basic shell that you could
program on. If you wanted to run a compiled program (a game, who are we
kidding?), you used Basic to bootstrap the load and replace itself with
whatever the tape had. Good times.

~~~
jhbadger
That was pretty much how most 8-bit computers worked -- the user interface
upon bootup was the Basic interpreter.

~~~
int_19h
Some vestiges of that persisted for much longer. For example, QBasic, and even
VB for DOS, still had the FILES command. Which, as you'd expect, produced the
list of files in the current directory - except it didn't return it, but
simply printed it out to the console. So it was something rather useless in an
application, but handy in a shell.

Less obvious things were having a variety of filesystem-related functionality
as built-in statements with special syntax, rather than functions. For
example, renaming a file: NAME "foo" AS "bar".

------
kunabi
I've been working on a CL project for a couple of years. Was my first big stab
at using CL for something other than a toy. Sbcl is a nice choice, but far
from the only option. It has many tradeoffs. CL is not without its
frustrations. Documentation that has not aged well. A community that can be
less than welcoming. (in contrast to say the Racket community)
Inconsistencies, e.g. first, nth, elt, getf, aref... However portability
appears to be a strong point vs on the scheme scene. Single binary compilation
on SBCL/LW/ACL/CCL are great. Found GC to sbcl to be lacking on large garbage
rates. Tended to promote garbage to a tenure that prevented it from being
removed. It would max out 32GB of memory, even with explicit gc's enabled
between files. Where as the other implementations would stay below 4GB.

So ymmv.

Performance benchmarks using cl-bench really highlighted some strong points
[http://zeniv.linux.org.uk/~ober/clb](http://zeniv.linux.org.uk/~ober/clb) AWS
Cloudtrail parser.
[https://github.com/kunabi/kunabi](https://github.com/kunabi/kunabi)

~~~
azrazalea
This talks about GC settings that worked for them in SBCL for production, not
sure if you already tried the same kind of stuff but may be an interesting
read [http://tech.grammarly.com/blog/posts/Running-Lisp-in-
Product...](http://tech.grammarly.com/blog/posts/Running-Lisp-in-
Production.html).

If you can make an easy to run example of the garbage collector not working
correctly, the folks in #sbcl on freenode are very responsive and have commit
access to fix it.

~~~
kunabi
Good to hear someone had good interactions in #sbcl Still have a bitter taste
from attempting to report the issue there.

~~~
azrazalea
Yeah, i've had good and bad interactions.

They seem to be cranky due to getting a lot of idiots (including sometimes me)
coming in thinking something is sbcl when it was actually the programmer's
fault.

Generally if I think something is sbcl now I put together example code that
clearly shows the issue and that seems to work well.

------
pnathan
Hi, HN! I made this! Ask me any questions you like. I'll try to respond as the
workday progresses and I wait for deploys to complete!

paul@nathan.house if you want to email me instead. (or @p_nathan on Twitter,
if that's your thing).

~~~
aidenn0
Also, the ASDF information is somewhat dated. It will work, but the central-
registry has been deprecated for years. I'm not even sure how it might work on
windows.

If you're recommending quicklisp, there's the local-projects approach,
otherwise there's $HOME/common-lisp/

~~~
pnathan
Yeah, I need to examine a bit more of the situation with local-projects. I
reject ~/common-lisp because I have my own directory structure, thanks. If I
can symlink farm under ~/common-lisp, then what's the difference? :)

(and it's not even a hidden directory, so it clutters up ~).

~~~
aidenn0
> (and it's not even a hidden directory, so it clutters up ~).

Well in that case you have two options still:

    
    
        ~/.local/share/common-lisp/source/
    

or put config file(s) in:

    
    
        ~/.config/common-lisp/source-registry.conf.d/
    

And keep your lisp source in any arbitrary number of directories.

Of course if the symlink farm is working for you, that's fine; it just has
issues (some historic with some implementations doing odd things with
TRUENAME, and of course the big one is "windows").

[edit] forgot some other options:

* setting the CL_SOURCE_REGISTRY environment variable

* using one of the newer functions for configuration, particularly with the :tree directive which in many cases removes the need for symlink farms.

~~~
pnathan
I do need to study the matter. I've found the ASDF docs to be unusually opaque
(last time I read them), and my current solution to be Very Simple (and a
little Stupid), so I've been content not changing the setup.

Thank you for your kind information.

~~~
aidenn0
Indeed, I think nearly every section of the chapter on configuration requires
you to know the contents of all the other sections for it to make sense. I
have probably spent a few hours going over that one chapter at this point...

------
znpy
Some notes based on my (brief) experience toying with Common Lisp:

* Why hasn't anyone made a more eye-frendly version of the Common Lisp Hyper Spec ? Having good, easily-browsable documentation is a core-problem.

* The relation between the various native data-types were quite unclear to me.

* dealing with the external world was quite a mess. Many project/libraries implementing only half of something and then got abandoned.

* some libraries had a compatibility matrix... with common lisp implementations. that seemed weird to me.

~~~
TeMPOraL
> _Why hasn 't anyone made a more eye-frendly version of the Common Lisp Hyper
> Spec ? Having good, easily-browsable documentation is a core-problem._

A friend of mine is working on that as we speak. The CLUS, or Common Lisp
UltraSpec:

[https://phoe.tymoon.eu/clus/doku.php](https://phoe.tymoon.eu/clus/doku.php)

That said, CLHS isn't bad - it's lightweight, available off-line, and on-line
you can pretty much always find what you're looking for by searching for "clhs
[term of interest]".

> _some libraries had a compatibility matrix... with common lisp
> implementations. that seemed weird to me._

Common Lisp has a pretty good standard, but it's a bit old so it didn't
predict some things we're currently using, and also left some other things to
the implementers. So some features are only available via vendor-specific
extensions, which makes it necessary for some projects - especially
compatibility libraries - to be tested across plethora of CL implementations.

The flip side is that you have a few commercial and open source
implementations to choose from, which is valuable if your project can exploit
strengths of a particular one.

~~~
db48x
Ah, this is something to follow. Sadly it doesn't seem to have a permuted
symbol index, which is what I really love about the CLHS. Still, I suppose
they have to start somewhere.

------
AlexCoventry
Can someone point me at an argument for why I'd want to write CL in 2017,
given all the great alternatives available now?

~~~
pnathan
It's a seamless dynamic programming language, which can, with care, be given
_excellent_ performance and a high level of abstraction. In my opinion, it's
miles better than the other dynamic languages out there, by nearly every
factor. It rewards investment and development very well; it's a tool for
mastery, not for quick and easy starting.

If you're looking for statically typed languages, it's not going to win there.
But my experience writing a lot of Perl and Python, with a certain amount of
helping with Clojure and Ruby experience, strongly indicates that Common Lisp
is very very competitive there outside of the 'library' front.

~~~
edem
Do you prefer it over Clojure? If yes why? I'm a bit versed with Clojure but
sometimes I feel that it is not a _true_ lisp.

~~~
cronjobber
> sometimes I feel that it is not a true lisp.

That feeling may be the result of some questionable syntactic design decisions
in Clojure.

Hickey went over Lisp syntax and tried to remove parentheses wherever
possible. (It was the hip thing, PG's Arc did it, too, which may be where
Hickey got it from.) As a result, you get a sub-par editing experience
—generic sexp-based structure editing doesn't get you as far as with a Lisp—
and diminished readability once you get above three omitted pairs of
parentheses in a row.

On the other hand, Clojure arbitrarily mandates a secondary kind of list
literal in some places of the syntax, again making Clojure harder to write and
edit. I don't even see a readability benefit, but of course YMMV.

TL;DR: Clojure syntax is a "complected" derivative of Lisp :-)

~~~
joe-user
> you get a sub-par editing experience [in Clojure]

Paredit and vim-sexp have no problem doing structural editing. I don't use it
myself, but Parinfer was created with Clojure in mind and people seem
incredibly happy with it.

> diminished readability [in Clojure]

If you watched the talk that you lifted "complected" from, you'd know that
this is subjective. Is German unreadable because I don't know German?

> Clojure syntax is a "complected" derivative of Lisp :-)

Complected in some ways sure, but far less so than many lisps, and certainly
less so than Common Lisp. It seems your familiarity is complected with your
reasoning.

------
agentultra
If you're so inclined I'd make it a "living document" that gets updated as the
state-of-the-art evolves. Writing CL in 2017 is not likely to change rapidly
in the next decade but even compared to what writing CL was like 8 years ago
it has changed enough.

Nice job.

~~~
azrazalea
It is. [https://github.com/articulate-common-lisp/articulate-
common-...](https://github.com/articulate-common-lisp/articulate-common-
lisp.github.io)

------
TeMPOraL
While I remember - we need a refreshed SOTU for 2017. 2015 one[0] seems to be
still mostly correct, but the CL scene is pretty active.

[0] - [http://eudoxia.me/article/common-lisp-
sotu-2015](http://eudoxia.me/article/common-lisp-sotu-2015)

------
mikelevins
For people using macs, it's probably worthwhile to mention CCL's IDE, which
you can easily build from within the CCL sources using (require :cocoa-
application), or which you can get for free from the Mac App Store (it's
called "Clozure CL").

It's a little bit bare bones and a little bit perpetually unfinished, but it
works and it gives you a Lisp-aware environment for editingand running Lisp
code, and even has a few handy tools.

~~~
sigjuice
Is there something like paredit available for CCL's IDE?

------
Grue3
>Repository for local libraries with the ASD files symlinked in

This method is so old, I can't believe people are still doing this. You can
easily setup ASDF to look in a subtree of a directory and never care about it
finding your libraries again.

[1] [https://common-
lisp.net/project/asdf/asdf.html#Configuring-A...](https://common-
lisp.net/project/asdf/asdf.html#Configuring-ASDF-to-find-your-systems)

------
edem
How does Common Lisp compares to Racket nowadays? I've seen a lot of activity
but I can't decide which one to try out. I only have time for one of them ATM.

~~~
spdegabrielle
1\. Racket is a multi-paradigm programming language. It has Java-style
class/object system, a CLOS-like object system(swindle) and a prototype object
system (like self and JavaScript). 2\. The macro system is arguably the most
sophisticated available. 3\. Functionsl programming! including
'(purely)Functional Data Structures'. 4\. Parallelism (futures) 5\.
concurrency 6\. Contracts 7\. Typed Racket 8\. Pattern matching 9\. Modules
10\. Units 12\. Pattern Matching 13\. Exception, continuations 14\. Reflection
15\. arguably the most sophisticated tools for creating full languages and
DSLs 16\. Datalog language (like in datomic) 17.an amazing IDE - it has a tool
to debug macros! (but you can also use Emacs) 18\. Typed Racket 19\.
Functional pictures (pict) 20\. OpenGL 21 cross platform (win, mac, Unix,
Linux) it will even run on a raspberry pi 22\. Amazing community 23\. Math
library (and plot library) 24\. Scribble/@-expressions (like markdown but
_much_ more powerful) 26\. Quite a few libraries

~~~
slmyers
> 17.an amazing IDE - it has a tool to debug macros!

This may be true for an experienced user, but I've mainly used VS
Code/Atom/Sublime etc, and I did not enjoy DrRacket -- I'm assuming that's
what you're talking about. Some of the dropdown menus didn't render for me,
and while this may sound stupid, I had the damnedest time figuring out that
half my screen was a REPL and the other half a file.

~~~
peatmoss
How long ago did you try it / what platform are you running on? It was a few
years ago now, but they rewrote the GUI libs to be native rather than whatever
x-platform lib they used. DrRacket seemed to get... better then.

I mostly use emacs, but was playing with paredit for DrRacket with emacs
keybindings the other day and decided that I could get to like some of the
other creature comforts of DrRacket.

------
lisper
If you have a Mac you should try Clozure Common Lisp
([http://ccl.clozure.com](http://ccl.clozure.com)). It has an integrated IDE
so you don't have to futz with emacs and slime.

Also, this library smooths over some of CL's rough edges:

[https://github.com/rongarret/ergolib](https://github.com/rongarret/ergolib)

------
gravypod
If this could have a "start" page and a "next" button that will take me from
topic to topic in order I'd enjoy that.

------
ntdef
Ah yes this is exactly what I needed. I was recently trying to start a CL
project but I had trouble wading through all the outdated material, especially
with regards to including external packages. Thanks for putting this together!

~~~
brudgers
I'm going through a similar process. My caution is that 'package' has a very
technical meaning in Common Lisp that is at odds with how 'package' is used in
other languages (and a bit at odds with how the author uses it in their
tutorial).

A package in Common Lisp is a set of interned symbols. In Common Lisp, systems
are more in keeping with an ordinary understanding of packages...but combined
with the idea of a build system just for fun.

ASDF is a way for managing systems (but it is worth keeping in mind that
Common Lisp does not have any 'official' understanding of systems). ASDF is
pretty much a _de facto_ standard by consensus.

Quicklisp is a 'package manager' in the sense that it will go out and fetch a
dependency from a repository. But what it fetches is a system: it is usually
not a package in Common Lisp's technical sense.

From the Quicklisp FAQ:

 _How is Quicklisp related to ASDF?_

 _Quicklisp has an archive of project files and metadata about project
relationships. It can download a project and its dependencies. ASDF is used to
actually compile and load the project and its dependencies._

 _ASDF is a little like make and Quicklisp is a little like a Linux package
manager._

On the other hand, Common Lisp is very stable around ASDF and SLIME and
QuickLisp. ASDF was started in 2002. Quicklisp in 2005. SLIME in 2003.

~~~
pnathan
Hmmm. I tried to convey the idea, without getting _too_ bogged down in the
details that don't per se matter on Day 1.

I would be interested in any PRs you have to clarify the matter adequately for
people just starting out.

~~~
brudgers
A few remarks:

0\. It's a hard problem. I have a deep respect for your trying to tackle it.

1\. The hard part is that it all matters on day one and everyone will get a
lot of stuff wrong for a long while and some stuff wrong always when
attempting non-trivial projects. This is the rule whether it's Python or
Common Lisp or Racket.

2\. I'm a fan of polyglotting languages in general and Lisp's in particular.
For a person really just starting out, I'd point them at the Racket ecosystem
because it is designed to be newbie friendly with student languages and Common
Lisp is designed for production programming on hard problems.

2\. For people with some programming experience and simple curiosity, I'd just
advise them to install SBCL and play around in the REPL. With an exercise of
adding a script to wrap it in readline. And some exercises using the text
editor of their choice to load and read and write files and such.

3\. I don't think that there's a way to add training wheels to SLIME and
Quicklisp and ASDF as the development environment. It just won't ever be
DrRacket. At best it produces something like Aphyr's _Clojure from the Ground
Up_...which uses Emacs; is more like a book; and definitely a labor of love.
It also dives into the details at day one.

None of which means I might not submit a pull request. But I take what Norvig
says seriously --
[http://norvig.com/21-days.html](http://norvig.com/21-days.html)

Again, kudos for taking it on.

~~~
pnathan
The niche of "welcome to Lisp, here's how to code" has been super well filled
over the years. And regularly people write sort of intros to SBCL, CCL, etc.
articulate-lisp isn't intended to do that - there are a few notes in that
regard, just to whet your thoughts - and because I was bored - but it's not a
thing there really.

But what is typically lacking is how you go from just a Lisp environment to a
development environment that lets you operate at a professional level.
Articulate-lisp is intended to deliver the thumbnail of how to get that put
together, along with assorted references to further study.

At the time I created it, there was nothing really suitable for pro
development out there. I guess roswell and portacle are things now.

Training wheels aren't really my bag of things. I'm notorious for preferring
to read the O.G. paper on subjects rather than work through tutorials and
simplified whatsits. But giving all the data at once doesn't provide the map
of the territory that newbies crave.

There's no Royal Road to Lisp... or geometry. But a map to get you to where
you're going does exist for geometry, and Lisp, I think deserves one too.

If that-all makes sense.

~~~
brudgers
What you say makes sense to me.

I think a resource for "leveling up" is probably better if it is opinionated.
I mean, there are reasons a person might not want to use Emacs for Common Lisp
development (aside from using a product with a built in IDE), but there's no
reason to handle edge cases which have little to do with "leveling up" on
Common Lisp...there may be a SLIME mode for Atom, but someone who chooses it
is swimming upstream in terms of Common Lisp.

The situation is similar in regard to Lisp installations. There are good
reasons not to use SBCL, but they probably don't have that much to do with
"leveling up" (again outside the commercial IDE world) and trying to cater to
those non-leveling up reasons is a distraction.

To put it another way, a person who is just starting out is not in a position
to make decisions based on experience. A year later, they may have the
experience to make informed decisions because they have learned what matters
and what does not.

I hopeful for Roswell and Portacle, but not terribly optimistic in ways that
are similar to when I hear about a new Linux distro. The hard work is not the
exciting honeymoon period. It's grinding out maintenance over the years
without getting paid. It's designing good features _for other people_ without
getting paid. Most projects cannot do it.

Part of the problem is that leveling up on Common Lisp is mostly a matter of
will to RTFM. Sure a site can have a great article explaining Common Lisp
packages, but to understand packages, readers will need to understand symbols
and so the options are:

1\. Expect the reader to already understand symbols.

2\. Describe all of Common Lisp.

3\. Accept that the reader will still have a lot of work to do after reading
the article.

1 and 3 collapse into similar requirements for an author. 2 works if the
author writing a book _and_ really knows their stuff.

Not sure how any of that is applicable here.

------
GreyZephyr
Wondering if anyone has any experience using lisp for machine learning? I'm
aware of mgl[0], but it seems to be abandoned. The lack any wrappers for
tensor flow or caffe is also a bit surprising to me. The cliki page [1] is
also unhelpful and out of date. Is machine learning on lisp dead or are there
projects out there that I'm just not aware of?

[0] [https://github.com/melisgl/mgl](https://github.com/melisgl/mgl)

[1]
[http://www.cliki.net/machine%20learning](http://www.cliki.net/machine%20learning)

~~~
cat199
Not directly, but have been following various projects over the years..

My take on this is that the people using CL for machine learning have been
doing this for some time, and so have their own toolsets; tensor flow is
relatively new in that regard, and w/r/t lisp interfacing would entail low-
level binary interfacing (and therefore mostly non-portable between
implementations) to hook CL code with tensorflow kernels (definately not an
expert here on either however).

also, what is popularly referred to as 'machine learning' is in my opinion
mostly only one aspect of the field - e.g. classification neural networks -
while lisp can definitely do this, lisp AI programming (in my amateur opinion)
shines more in the realm of machine reasoning/inference due to the symbolic /
dynamic nature of the environment - e.g. constructing a set of reasoning
primitives (e.g. functions and facts and decision trees) and a meta-
interpreter to reason/infer about external data and walk around a problem
space.. also, owing to the dynamic and rapid development nature of the
language, likely many people are working with their own prototype/core
frameworks, possibly cobbled together from various small bits and pieces of
3rd party code. Also, neural networks have been around for quite a while -
what these new frameworks bring to the table is not so much new core
algorithms, but the ability to quickly cobble them together in a more
popular/user friendly way, and also take advantage of fast hardware (e.g.
GPUs)

as for projects - in the general sense, lisp has been a latecomer to the
'languages with cpan-style trove of public addon modules' crowd, owing in my
opinion to the need to support multiple implementations in order for such a
project to take hold - so older but yet still quite functional libraries might
be around in various hodge-podge repositories which are not standardised but
old timers have already included in their own local systems, etc. (see also
CMU AI repository)

In the last few years, much has been done in the module space - I would
definately consider 'quicklisp' to be roughly the defacto definitive list of
current modules, especially those under active development, since the active
community is basically converging on this as a module/distribution platform
and so many (most?) active community projects are available as quicklisp
modules and included here - and so would probably be the one of the first
places to start in checking into for available libraries for any topic.

Also, the best way to 'explore' quicklisp is to install it, and then install
various packages and then muck around/explore with the source code that they
download into your environment - the documentation tends to be much less
'external' (e.g. websites) and much more 'internal' (e.g. READMEs, in-tree
code examples or unit tests).

[https://www.quicklisp.org/beta/releases.html](https://www.quicklisp.org/beta/releases.html)

------
juanre
I wrote in Common Lisp the star map generation software at the core of my
startup, [http://greaterskies.com](http://greaterskies.com), and could not be
happier. But now that it's getting off the ground I wonder whether it may
adversely impact my chances of being acquired. Are there any known examples of
recent CL-based startups?

~~~
dtornabene
I don't know about being acquired but I believe there is a canadian travel-
oriented startup using CL for an algorhythmically important part of their
stack. I forget what it was called.

------
na85
If emacs is an obstacle to Common Lisp in 2017, maybe what's needed is a Lisp-
interaction plugin for vi(m) (or whatever it is that vim uses in lieu of emacs
modes). I don't get the hype for modal editing but you can't argue with the
data clearly showing emacs users are in the minority.

~~~
kahrkunne
Honestly I don't think Emacs is an obstacle to people who use Vim. It's an
obstacle to people who use IDEs

~~~
ruleabidinguser
I use(d) vim and see EMacs as annoying.

~~~
kahrkunne
It might be annoying but it probably wouldn't be an "obstacle", especially
considering things like evil-mode exist.

That's how it went for me, anyways. From vim user to trying Emacs because it
has some feature that I need to becoming a full-time Emacs users with evil-
mode

------
macco
If somebody is not comfortable to use emacs (I am), there is a atom plugin for
use with CL: [https://atom.io/packages/atom-
slime](https://atom.io/packages/atom-slime)

It doesn't replace emacs, but it works as a first Lisp ide.

~~~
snowcrshd
Hmm, this just gave me an idea: Visual Studio Code Common Lisp plugin might
also be a good way to expose the language to people unfamiliar to the
language.

~~~
int_19h
Every time I tried to get into CL, having to use Emacs/SLIME (which, let's
face it, is _the_ development environment for it for all practical purposes)
has been a huge turn-off.

So, yes. Please?

~~~
provemewrong
I had (and still have) a similar aversion to emacs, so I used to use Sublime
with SublimeREPL plugin, which allowed me to run Common Lisp and Clojure (or
any other language with a REPL) inside the editor. Pretty much a makeshift
IDE, with an interface you're already used to. I've since moved on to VSCode,
and I bet there must already be a way to replicate this in it, I just haven't
had the need to work with Lisp since to explore this.

------
s_kilk
While people are directing their attention here:

Last year I looked into Common Lisp for a while, but got turned off when I
found that there's no distinction between the empty list and boolean false (or
nil, in CL-speak).

I found this kinda weird and vaguely off-putting. I don't want to write code
to handle the diffence between, say, an empty array and false or null in
deserialized JSON data.

Can anyone comment on whether this comes up as an actual issue in practice?

~~~
aidenn0
It comes up in practice but is easilly avoided with the mapping of:

    
    
        null -> :null [] -> #() and false -> nil
    

Mapping arrays to lists instead of arrays seems wrong to me, but is what most
json libraries do by default. Fortunately most of them allow you to change
that.

~~~
s_kilk
Would that mean I'd need to carry the `:null` symbol all throughout the
codebase, wherever that data-structure might be accessed?

~~~
aidenn0
I'm not sure I understand the question. If you need to check if a value is
null, you compare it with :null. It does mean that values you are going to
serialize out to JSON should use :null rather than the more lispy nil, but
JSON interfaces where you are required to send null values are quite rare (in
fact I don't recall ever encountering one), so it hasn't been a problem for me
in practice.

------
throwaway7645
"Dear windows user, tell us how this is done for SBCL"

Watch YouTube video from Baggers. It's a lot more complicated than your
average windows user will want to go through. Than you have to setup EMACS,
quicklisp...etc. I never really new what quicklisp was doing and it made me
nervous (I trust VS nuget).

~~~
Grue3
Everything should Just Work (TM) on Windows these days. SBCL provides
reasonably fresh binaries to download. Quicklisp can be installed by entering
the necessary commands into SBCL console. Emacs has a Windows installer. SLIME
can be installed from Quicklisp. And so on. I develop in Lisp on both Windows
and Linux machines, it works exactly the same (which cannot be said of some
other languages).

------
tarrsalah
A newbie question please, How to deploy CL on production? I mean for long
running programs.

~~~
aidenn0
There are a few ways of doing it all with different tradeoffs:

If very quick startup times are a necessity, then you just build a standalone
image. This is very much like deploying a program in e.g. C. You build it with
asdf, and then install it (and any dynamic libraries) into your deploy
environment.

For "long running" programs, this may not be as necessary, and since the lisp
runtime includes a full lisp compiler, it's not uncommon to just have a script
that launches your lisp executable, uses ASDF to load the system, and calls
the entry point.

For either one, it can also be useful to expose a swank server, though that
does have security implications (anybody who can connect to the swank server
(either localhost or unix domain sockets) can run arbitrary code).

------
killin_dan
The biggest problem with lisp adoption imo is that the first step of every
path begins with emacs.

Emacs needs to die for lisp to flourish in a more modern editor.

Light Table was a good start, but we need some power behind similar projects.

I always thought guilemacs was the obvious successor, but it still hasn't
happened.

~~~
peatmoss
Since you mentioned Light Table, I'm going to guess that you're open to other
lisps. I think this is one thing that the Racket folks get right. My wife's
first foray into programming was a coursera course starting with a simplified
variant of Racket, and the dev environment could not have been less of an
issue.

EDIT: Also, emacs doesn't have to die. I love emacs! But DrRacket is a nice
alternative for beginners (and I'm told) advanced users alike.

~~~
killin_dan
Yes, but racket is a terrible language to work with. I've mentioned for years
that drracket needs a general sexpr mode and integrated terminal for something
like geiser. They don't listen.

I am working on a general purpose solution, but I'm just one person. And I
don't leverage public dollars to write bad tools from the safety of
university, so that slows it down a bit.

~~~
peatmoss
> racket is a terrible language to work with.

> ...

> I don't leverage public dollars to write bad tools

That's, like, your opinion, man!

Further, if your habit is to make feature requests in combination with this
kind of subjective disparagement, I can see why the Racket community didn't
jump to implement your request.

Lighten up. Everyone here is on the same team.

------
quickoats
i do not know how to message the guy "Scott" author of page, so i am putting
this here.

in the "LispWorks CL" page, under "Implementations", the "Notes" section
elicidates a mystery about the Personal Edition not recognizing the lisp init
files. This is actually a limitation in LispWorks Personal Edition which is
described on the link provided to retrieve said edition.

~~~
pnathan
Ah, interesting! I don't remember reading that when I wrote it.

I'll go back and correct it after my current project wraps up (but PRs are
also accepted!).

~~~
lispm
The Personal Edition has several limitations:

does not load init files

supposed to be used with the IDE

IDE quits after some hours

Memory is limited

can't create applications

\---

Actually the Personal Edition is mostly for people to play around a bit or
students doing some homework.

Other than that the typical user will buy a version, which won't have the
above limitations. Users also may also test a time-limited full version,
before buying. People use either LispWorks or Allegro CL, then.

~~~
pnathan
Yeah, I recall using it a bit more now.

The personal edition is really a trial edition, it's not a 'low budget low
features' edition, which is what I was thinking when I originally was fooling
with it back then.

(These days I use SBCL nearly exclusively for my CL implementation)

~~~
lispm
> 'low budget low features' edition

In some school/university course it would be like that. The students get a
simple installer, get the IDE up and running after a few clicks and thus they
don't have to learn GNU Emacs + installing Lisp infrastructure for some basic
homework.

------
lerax
NICE!

------
ConanRus
Short answer: don't do that, use Clojure instead. It doesn't have any of
listed problems.

~~~
baldfat
I am sure there are plenty of people who have a preferred Lisp. It does drive
me nuts how if there is a post on R the top comments are people touting Python
as being the bigger player in statistics and data science (Which it isn't) or
a ton of other languages.

PS I perfer Racket :)

~~~
mehaveaccount
R is pretty pointless though. Unless you want to rewrite everything between
prototyping in R and real deployment with a real language, you are better off
writing in Python.

~~~
baldfat
That right there is what I am talking about. I make a point and people have to
attack that that the language is pointless when it is the number one language
in that domain, which just happened the last two years.

Why would you ever have to rewrite the code? Python isn't faster and has less
function then R and if you want you can just drop a few lines of Python in a
cell of a Notebook. I like Python and its a good choice but R is a great
language that in fact that Python's pandas library is trying to make a R
equivalent.

~~~
mehaveaccount
>I make a point and people have to attack that that the language is pointless
when it is the number one language in that domain, which just happened the
last two years.

That's not true though, R doesn't have anywhere near the ecosystem that Python
does for Natural Language Processing, Web Frameworks, Machine Learning,
Computer Algebra and Symbolic Reasoning, Systems Programming, Image
Processing, Document Processing, and other things I don't know about but if I
needed something else then I can use Python confidently that there will be
good packages for them with a community around it.

The entirety of R's unique mindshare is that it has a million variations on
linear regression and contingency table tests. And frankly they're all so
simple to implement that if you can't be bothered to learn how to implement it
in 2 lines of Python then you probably don't know what your program is
actually doing.

R is something that caught on because it made its statistics package top-
level, saving keystrokes for statistics and bio-statistics professors who
never needed anything else and didn't know how to otherwise program. It's
unique syntax has lead their poor students to have to learn C-family syntax
many years after they could have been working and being productive with it.

Now some companies are accommodating R for their entry-level data scientist
positions in order to hire cheaper help that can't find better options, but
their skills are limited by being disconnected from the rest of the
programming world in both packages and syntax.

~~~
baldfat
> That's not true though, R doesn't have ...

Your comparing a general purpose language and a domain specific language.

Domain specific just talking in statistics and data science. I don't need a
webframe work I need to make my report and have the charts work. I also push
out my reports in Word and PowerPoint and I can't do that in Python but I can
in R with ReportR library (The whole reason why I left Python and Pandas and
came to R)

I say if you want to do more then the domain specific then sure Python is an
awesome language and you can use your Python skills for more, but if you want
the extras that the domain specific language gives you come on board.

To say R is a "Pointless Language" is very troll like especially with
companies spend millions of investment and infrastructure that have come to R
in the last 24 months.

I could also say what I always say about Python. It is the World's Great
Second Best Lanaguge. It doesn't do anything "best", but it is a awesome
second best and if that is fine with you have fun. I love Python but I also
see the limits of the language. I thought 15 years ago Python would
revolutionize everything and everything would be written in it. We now have
Lua that took over for game scripting. We have C++ still ruling the day for
applications. Web development has been dominated by JavaScript and Mobile
development and Python is well .... So the two largest platforms aren't really
impacted by Python.

> Now some companies are accommodating R for their entry-level data scientist
> positions in order to hire cheaper help

[http://www.datasciencecentral.com/forum/topics/what-pays-
mos...](http://www.datasciencecentral.com/forum/topics/what-pays-most-r-
python-or-sql)

[http://www.kdnuggets.com/2015/05/r-vs-python-data-
science.ht...](http://www.kdnuggets.com/2015/05/r-vs-python-data-science.html)

It isn't a clear picture but NO way is Python dominating in pay or work. R is
a GREAT language and so is Python but for some weird reason Python community
hates on R. While the developers of R and Python respect and work with
eachother and help both sides. I am shocked you feel Python is so over
powerfully awesome.

------
cody8295
Probably the worst implementation of the 5-puzzle problem you can write.

codydallavalle@gmail.com Artificial Intelligence Assignment 1

Problem 09: Write GET-NEW-STATES to implement all possible movements of the
empty tile for a given state.

CG-USER(151): (defun get-new-states (state) (setf new-states '()) (cond ((= 0
(first state)) (setf new-states (list (list (second state) 0 (third state)
(fourth state) (fifth state) (sixth state)) (list (fourth state) (second
state) (third state) 0 (fifth state) (sixth state))))) ((= 0 (second state))
(setf new-states (list (list (first state) (fifth state) (third state) (fourth
state) 0 (sixth state)) (list 0 (first state) (third state) (fourth state)
(fifth state) (sixth state)) (list (first state) (third state) 0 (fourth
state) (fifth state) (sixth state))))) ((= 0 (third state)) (setf new-states
(list (list (first state) 0 (second state) (fourth state) (fifth state) (sixth
state)) (list (first state) (second state) (sixth state) (fourth state) (fifth
state) 0)))) ((= 0 (fourth state)) (setf new-states (list (list 0 (second
state) (third state) (first state) (fifth state) (sixth state)) (list (first
state) (second state) (third state) (fifth state) 0 (sixth state))))) ((= 0
(fifth state)) (setf new-states (list (list (first state) 0 (third state)
(fourth state) (second state) (sixth state)) (list (first state) (second
state) (third state) 0 (fourth state) (sixth state)) (list (first state)
(second state) (third state) (fourth state) (sixth state) 0)))) ((= 0 (sixth
state)) (setf new-states (list (list (first state) (second state) 0 (fourth
state) (fifth state) (third state)) (list (first state) (second state) (third
state) (fourth state) 0 (fifth state)))))))

GET-NEW-STATES

CG-USER(152): (get-new-states '(1 2 3 4 5 0))

((1 2 0 4 5 3) (1 2 3 4 0 5))

CG-USER(153): (get-new-states '(1 2 3 4 0 5))

((1 0 3 4 2 5) (1 2 3 0 4 5) (1 2 3 4 5 0))

CG-USER(154): (get-new-states '(1 2 3 0 4 5))

((0 2 3 1 4 5) (1 2 3 4 0 5))

CG-USER(155): (get-new-states '(1 2 0 3 4 5))

((1 0 2 3 4 5) (1 2 5 3 4 0))

CG-USER(156): (get-new-states '(1 0 2 3 4 5))

((1 4 2 3 0 5) (0 1 2 3 4 5) (1 2 0 3 4 5))

CG-USER(157): (get-new-states '(0 1 2 3 4 5))

((1 0 2 3 4 5) (3 1 2 0 4 5))

------
lenkite
I wish an experienced LISPer would explain why should one use Common Lisp over
a language like Golang. Golang now has
[https://github.com/glycerine/zygomys](https://github.com/glycerine/zygomys)
for scripting. For that matter, why would one choose Common Lisp over GNU
guile ? (guile now supports fibers). What does Common Lisp offer for the
working programmer that is an advantage over other languages ?

~~~
SomeHacker44
Given a reasonable choice, I would almost never use a language like Golang
that doesn't enforce memory safety (at least, by default). Null pointers, ugh.

~~~
jerf
Most of the traditional definitions of "memory safety" are not violated by
having null pointers, as long as they just crash when used incorrectly. nils
in Go don't let you start accessing things you shouldn't or anything. Golang
is memory safe by most definitions. (Possibly not by a definition that
includes concurrent memory safety. I expect in 20 or 30 years the term "memory
safe" will indeed involve that. But at the moment, it doesn't, because almost
no language has that right now.)

This doesn't invalidate your underlying point that you want to use a language
without implicit nulls... it's just the wrong terminology.

~~~
Zak
I'd put that one under type safety, and it definitely seems bizarre to me to
make a new language that claims to have strong, static typing and allow
arbitrary types, or pointers to arbitrary types to be null.

~~~
jerf
Go's nil is statically-typed. The nil keyword is polymorphic (as numbers in
the source code are) but individual nils that occur at runtime in Go are
actually typed. You can actually put methods on them and they execute just
fine:

    
    
         type S struct{}
    
         func (s *S) Test() {
             if s == nil {
                 fmt.Println("Nil pointer")
             } else {
                 fmt.Println("Not nil pointer")
             }
         }
    
         func main () {
             var p *S
             p.Test()
         }
    

That will print "Nil pointer", not crash.

While I'm actually still in agreement that I don't love a language with nil
pointers, it is _less bad_ in Go because they are less pointy and stabby. It's
not like C where they are automatically a crashing offense; they are valid
values treated in sensible ways in a lot more places than in C, because in Go
they still have their type associated with them. But I'd still like to be able
to declare a non-nillable pointer type.

Please do note carefully the difference between _less bad_ and _not bad_.

~~~
Zak
The type of s/p there can't be guaranteed to be (S not nil) at compile time,
which is a bizarre decision in an otherwise-statically-typed language where
the type system is designed to provide runtime type safety. You still have to
do a null check at runtime if you want to be safe here

While it's nicer that you can perform the check inside Test() instead of
before the call, I don't understand why the type system doesn't just prohibit
this and make you use a union type if you want (S or nil) given that a lot
more situations call for (S not nil) than (S or nil).

