
Why I haven't jumped ship from Common Lisp to Racket just yet - networked
http://fare.livejournal.com/188429.html
======
flavio81
The author, a famous and well-liked lisper, is not consider ing portability
features. CL is an ANSI standard and code often runs with no changes in many
distinct CL implementations/compilers/interpreters.

Also, related to that point: There are many different CL implementations out
there that satisfy different use cases, like for example JVM deployment
(ABCL), embedded systems (ECL), speed(SBCL), fast compile times (Clozure),
pro-level support (LispWorks, ACL), etc. So the same code has _a huge_ amount
of options for deployment. It really makes Common Lisp be "write once, run
anywhere".

Then speed is also never mentioned. Lisp can be seriously fast; under SBCL it
is generally 0.3x to 1x C speed; LispWorks might be faster, and there's a PDF
out there called "How to make Lisp go faster than C", so that should give an
idea of Lisp speed potential.

CL wasn't created by philosophing about what a programming language should be
for many years; CL was basically created by merging Lisps that were already
proven in the industry (Maclisp, Zetalisp, etc), already proven to be good for
AI, heavy computation, symbolic computation, launching rockets, writing full
operating systems, etc.

CL is a "you want it, you got it" programming language. You want to circumvent
the garbage collector? need to use GOTOs for a particular function? want to
produce better assembly out? need side effects? Multiple inheritance? Want to
write an OS? CL will deliver the goods.

In short, i would guess that from a computer scientist or reseacher point of
view, Racket is certainly more atttactive, but for the engineer or start-up
owner that wants to have killer production systems done in short time, or to
create really complex, innovative systems that can be deployed to the real
world, Common Lisp ought to be the weapon of choice!

~~~
pjmlp
The biggest issue I see with Common Lisp is that the standard is stuck in
time, lacking stuff like database providers, a common FFI or threading.

It needs a review of the CL environments that survived to modern days and
adopt the common extensions.

~~~
jackdaniel
I think it is a pretty shallow view at standard. CL implementations grow and
have agreed interfaces (or portability layers). A few examples:

\- sockets via usocket

\- threading via bordeaux-threads

\- metaobject protocol via closer-mop

\- foreign function interface via cffi

all these are not mentioned in the standard at all, but are implemented and
used in production environment.

Having base standard and extensions which may be used portably (via
portability layers) is better situation than having no standard (for instance
python or ruby) and a reference implementation.

~~~
pjmlp
Which usually is what leads to _feature expressions_ spaghetti.

Also, it means that a Lisp newbie won't be aware of what are the best
libraries that are portable across Lisps for such features.

EDIT: typo correction (missing are)

~~~
jackdaniel
Feature expressions shouldn't be used in normal applications, only in
portability libraries. To use threads on any implementation which supports
them (given it's supported by the recommended portability layer):

> (ql:quickload 'bordeaux-threads)

> (bt:make-thread (lambda () (sleep 1) (print "hijack")))

that's all, no feature expressions whatsoever. Quicklisp is a system manager
(something similar to npm in sense that it helps you to download
dependencies).

Regarding best libraries: isn't that true for any language? Newbie doesn't
know good libraries, because he is a newbie. He has to learn which libraries
are good and which are bad.

edit: and by each supported implementation I mean in fact all active complete
Common Lisp implementations: ArmedBear, Allegro, clisp, Clozure, Corman,
Embeddable, Man-Kai, LispWorks, Steel-Bank and Scieener.

~~~
moomin
I think the point is you can't really have it both ways. CL prides itself on
its extensive and portable standard library, but has huge gaps by the
standards of modern languages.

~~~
flavio81
> but has huge gaps by the standards of modern language

Please detail, because i'm sure that the Lisp community would love to fill
those gaps. After all, Lisp is addictive to the point of resembling a hard
drug.

~~~
moomin
Well, start with the stuff that OP's just been arguing doesn't need a standard
implementation. :)

------
mjmein
Racket is a really exciting language, especially with its focus on building
small languages to solve problems.

However, where it fails for me is in its lack of interactive development. When
I investigated it, there seemed to be no way to actually connect a repl to a
running program.

Unlike with common lisp or clojure, with racket if you make changes to your
code you have to restart the REPL, which destroys your state.

This was a big disappointment to me, because even python with ipython and
autoreload allows for more interactive development.

I suspect that this decision was made because of racket's start as a teaching
language, because it is simpler, but way less powerful.

~~~
maxiepoo
I believe this is a design decision, because relying on some enormous implicit
repl state and updating the code in place is a good way to get yourself into
states that are impossible to reach in an actual running program. Racket is a
functional language and it is their belief that you should just make
predictable ways to startup your interactive development than rely on the
entire state of some repl image.

~~~
mikelevins
You're right; it's a conscious decision. I had a little discussion with Eli
Barzilay and Matthew Flatt about some related matters a little while back. It
was a nice discussion, but image-based or live programming is just not
something they found particularly compelling.

It pretty much keeps me from using Racket, and a bunch of other things that
are otherwise very nice. Given a choice, I will always choose the tools that
support me in building things by modifying programs as they run. I'm just
happier and more productive that way.

So one of my axes of optimization is selecting projects that enable me to work
that way.

~~~
maxiepoo
Ah yes, I remember seeing an interaction that was probably yours, tried to
find it for my comment, but never did.

~~~
elibarzilay
I don't know what this refers to, but it doesn't ring a bell. The most I might
have said is that the community in general is not too interested; but
personally, this kind of dynamic interaction is something that I very much
appreciate. In fact, when I implemented xrepl (which is now the default when
you start racket) being able to modify code inside modules was one of the main
goals. The only reason I didn't do something like that for Emacs is that my
own use of CL/Scheme variants in Emacs was always very simple, but I actively
encouraged people to do something similar for Emacs -- and Geiser/Racket-mode
are two serious Emacs packages that actually do that kind of interactive use.

~~~
mikelevins
I asked you guys about image-saving because I was considering using Racket to
build a new version of bard, and I thought I might like to both use image-
saving during development and piggyback on a Racket implementation of it for
use in bard's runtime. As I recall, you guys wanted to know what I found
compelling about image-saving, but you didn't find it as compelling as I did.

I still might build a bard on Racket, but if so, I'll most likely build my own
VM and implement my own image-saving solution for it.

Assuming, of course, that there are enough hours in the day, and enough years
in a life.

------
jlarocco
I use Common Lisp quite a bit, and I'm just not interested in switching to
another Lisp. I've looked at most of them, and haven't seen anything
compelling. CL still wins on everything that I care about (performance,
portability, libraries, ease of use, books/documentation, etc.).

Even the article's list of areas where Racket is "vastly superior" is
questionable, IME. Granted, the author wrote ASDF, so he has a very different
perspective than I do on the module system, but in practice nothing on that
list has been a problem for me, and a few of them I'd actually consider to be
anti-features (like a built-in GUI library).

~~~
criddell
What domains are you using CL in? The last time I used a Lisp was inside
AutoCAD and it was a lot of fun.

~~~
jlarocco
At work I mainly write C++, but I have a little library in CL that I've been
working on for a while that can call our REST API, access and filter our log
files, connect to our test infrastructure, and some other miscellaneous stuff.
It started because I wanted to call our product's REST API from inside Emacs
(in the Slime REPL) to make debugging and testing easier, but over time it's
grown to about 1500 lines of CL to automate common tasks.

Outside of work it's my go-to language for learning new stuff. I use it for a
bunch of little programming projects that I put on Github
([https://github.com/jl2?tab=repositories](https://github.com/jl2?tab=repositories)).
They're mostly just playing around with whatever topic I'm interested in at a
given time. Lots of animations and (simple) computer graphics, some simple
games, one or two libraries for the Raspberry Pi, etc. Nothing too exciting.

I want to start contributing to some of the open source libraries and projects
(like stumpwm and sbcl) that I use a lot, but so far the few commits I've made
to other projects have been really small bug fixes or trivial documentation
fixes.

~~~
ClFromEmacs
Do you run items in CL that return to an emacs buffer? Like say, slime-
eval/run? Or are these just run in the repl itself and displayed there? Been
toying with making some async stuff run via swank/slime and then display in
emacs in a custom mode and buffer.

------
peatmoss
I really like this article, because it manages to be a love letter to both
Racket and Common Lisp.

------
farray
Interestingly, I just added a section on Gerbil, the Lisp dialect I have
adopted instead of PLT, for many personal reasons.

~~~
bad_login
What is your setup working with gerbil compared to emacs/slime?

~~~
farray
My current setup does not compare favorably with Emacs/slime at this point. I
use screen, I call a build script in one shell REPL, I use gerbil-mode in
Emacs in the other, reload'ing things that I rebuild, or restarting the M-x
run-scheme when too much has changed, copy-pasting from a gerbil-scratch.ss
file, or repeatedly loading a .ss file with on-going tests. This is less than
satisfactory. We hope to improve the situation this year so we can use geiser
or slime or something similar.

------
bjoli
One thing that makes racket shine is it's macro facilities. Syntax case is
nice and all that, but Jesus Christ in a chicken basket I wish scheme would
have standardised on syntax-parse.

Syntax case vs. syntax parse isn't and will never be close to a fair
comparison. Not only is it more powerful, it also provides the users of your
macros with proper error messages. It blows both unhygienic and other hygienic
macro systems out of the water for anything more complex than very basic
macros.

~~~
agumonkey
Here's the doc for the curious [http://docs.racket-lang.org/syntax/stxparse-
intro.html](http://docs.racket-lang.org/syntax/stxparse-intro.html)

Interesting system indeed

------
i_feel_great
That Racket module functionality where you can add unit tests right with your
code ("module+"), but will get stripped when compiled - that thing is quite
magical. Is there another system that has this?

~~~
thescribe
I don't think it is an official part of the language but the Pragmatic
Programmers Elixir book does this in one of their examples code sections.

~~~
bglusman
It is an official part of the language, and is automatically part of the
compiled docs, which are also an official part of the language!
[https://elixir-lang.org/getting-started/mix-otp/docs-
tests-a...](https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-
with.html#doctests)

------
laxentasken
If you do work in CL for a living, may I ask what kind of applications and
which area? The reason for my question is that CL (and racket) seems like a
very good idea to put some time into but the market for such jobs is dead
where I live (sweden). Or those jobs might be held by lispers on a lifetime
...

~~~
aerique
I don't work in CL for a living but it is my main go-to language (also at
work). It is worth it to put some time into even though there's not a big
market asking for CL directly.

------
myth_drannon
For anyone interested in Racket, excellent book/online tutorials
[http://beautifulracket.com/](http://beautifulracket.com/)

------
zerr
Anyone using Racket in the wild? (Besides the Racket team)

~~~
_delirium
Hacker News runs on Racket. :-)

~~~
flavio81
wasn't HN in Arc?

~~~
farray
And what is Arc in?

~~~
flavio81
The CPython JIT/compiler is written in C. Does this mean that a Python program
is then a C program?

Arc is not Racket.

~~~
_delirium
I suppose the original poster could clarify whether they were interested
primarily in examples of the Scheme-derivative language "Racket" being used in
production, or in the system/VM/runtime "Racket" being used in production.
Since Racket (the system) now makes it very easy to define new languages on
top of it with the #lang keyword, it might be nice to get more clearly
distinct terms for these. The way the Java world uses JVM vs. Java, e.g. you'd
say that a Clojure app runs "on the JVM", but it's not in Java.

------
lottin
> trivial utilities for interactive use from the shell command-line with an
> "instantaneous" feel

Last time I checked CL images were huge though. Something like 24MB for a
"hello world" executable, even bigger with some compilers.

~~~
aerique
You are correct, but why is this a problem in the case mentioned by the
author?

    
    
        $ cat > hello-world.lisp
        (defun main () (format t "Hello, World!~%"))
        $ sbcl 
        * (load "hello-world.lisp")
        T
        * (save-lisp-and-die "hello-world" :toplevel #'main :executable t)
        [undoing binding stack and other enclosing state... done]
        [defragmenting immobile space... 1110+19908+28500+22601 objects... done]
        [saving current Lisp image into hello-world:
        writing 4816 bytes from the read-only space at 0x20000000
        writing 2320 bytes from the static space at 0x20100000
        writing 2383872 bytes from the immobile space at 0x20300000
        writing 15190112 bytes from the immobile space at 0x21b00000
        writing 39911424 bytes from the dynamic space at 0x1000000000
        done]
        $ ./hello-world 
        Hello, World!
        $ ls -lh hello-world
        -rwxr-xr-x 1 user user 56M Aug 23 10:23 hello-world

~~~
lottin
It's not necessarily a problem, but personally for small utilities I much
prefer something that supports #!-style scripts, like Guile or Racket, or that
can be compiled into small, efficient executables. Let's say it's a matter of
personal preference.

~~~
juki
You can use CL for #!-scripts too. SBCL has a `--script` option for running
scripts. You'll probably want to create a core with whatever libraries you
need for scrips, so that the start-up time will be fast. The core will be big,
but it can be shared for all scripts, so that's not much of a problem.

~~~
ebzzry
I wrote a short introduction to a more portable Common Lisp scripting
system—made by Fare, himself—at [https://ebzzry.io/en/script-
lisp/](https://ebzzry.io/en/script-lisp/)

