Just for the future reference in terms of conducting surveys and helping aggregate the results, please consider not using open fields on topics that would benefit on predefined sets and one open field called "Other".
Now there are lists with almost 400 answers with most of the answers being practically the same ("personal stuff", "personal projects", "personal things"...). It does not make it easy to digest the information.
They can be evaluated, it's just going to be difficult to do it as a quantitative analysis.
Which is actually kind of fine with me. After a long long period of people only being interested in asking questions when the answer can be graphed, it's nice to see some individuals' actual feelings and opinions showing through in the results. For example, "all tasks that do not require close OS functionality" was a gem of a response that you'd never see in a survey that consisted solely of checkboxes and radio buttons.
That was written by someone with (at the time) some experience in web development and zero in Lisp.
The request "Update on October 6, 2017. N.B.: Please stop submitting this to Hacker News!" should be interpreted in its strongest form: i.e. including comments.
The commentary on adding OO to Lisp, I feel, is still very illuminating. As for "not reposting to HN", I take that as "don't clutter up the front page with something that's been posted multiple times already and has been discussed to death." Posting it in a comment for those that haven't seen it is nowhere near comparable.
Making a viable object-oriented programming system for others to use is not a trivial task in any language.
No object system for Scheme that people actually use had been written by a sophomore as homework and gone into production in that state. (Linux started by a school kid tinkering with kernel programming too; but it would be a strawman to say that a bright undergrad can make a serious Unix clone in a few weeks that Amazon can put into the cloud and sell services on.)
The Common Lisp object system took many people years of work, and integrates deeply into the language, such that every object type has a class and can participate meaningfully in the object system without being wrapped in a class.
> Due to the difficulty of making C object oriented, only two serious attempts at the problem have made any traction: C++ and Objective-C.
Those are examples of having enough traction to actually get people to switch from C to a new language.
Ad hoc object systems have been implemented in C programs umpteen times, and a number of such things are available, or have been historically available, as formal libraries for use in C programs.
These all have "traction" in their "respective" projects and ecosystems; there is a lot of OOP action within C.
> Ad hoc object systems have been implemented in C programs umpteen times, and a number of such things are available, or have been historically available, as formal libraries for use in C programs.
I've seen surveys that have open fields like that before but they usual use some keyword analysis to distil the results down (though I've always been sceptical how well their NLPs interpret messages like "I always use for personal projects" and "I never use for personal projects" as polar opposites despite the similar wording).
Anyhow, in this instance you're right that there isn't even a need for open fields, there's enough examples online already of IT being separated into distinct sectors for field selection on forms.
But what really grated me the most about the results was that there didn't even seem to be any deduping of the results (or if there was, it was case sensitive):
- CL is mostly used by hobbyists. (Not a very big surprise.)
- There do seem to be several users in research computing. (As a computational biologist, I find this interesting and encouraging.)
- The user demographics skew towards younger adults (<45 yrs). (That's interesting because they weren't around yet during Lisp's heyday, so the language seems to retain enough appeal to still attract new users.)
- User's top 5 countries of origin: USA (30%), Germany (10%), UK (5.4%), Japan (5%), Canada (4.3%). (Not quite as anglophone-leaning as I'd expected; there's actually a very wide spread of countries represented.)
However, I don't know how this survey was advertised, so the results may just be sampling bias.
> The user demographics skew towards younger adults
I'd be careful interpreting numbers like those. This isn't measuring the age demographics of CL users, per se. It's measuring the age demographics of people who responded to the survey. ~25% of that group self-reported as not actually being (current) lisp users.
I'm not calling attention to a sampling bias problem, I'm calling attention to a data reporting problem.
Including people who don't actively use lisp in the sample is entirely valid, and capturing that information about them would facilitate some interesting analyses. For example, we could look for demographic differences among professional lispers, hobbyist lispers, and curious onlookers. Or see if there are any industry trends.
It's just that this Google doc reports these data in a way that's too coarse-grained to support that kind of analysis, regardless of any bias concerns.
>However, I don't know how this survey was advertised, so the results may just be sampling bias.
I created this survey. I originally posted it to the CL subreddit and the CL IRC channel, so somewhat limited communication channels. Maybe there are other, better places to post it?
That channel however is plagued by spam, robots and trolls, i.e. very low signal/noise ratio. I got the impression that many users/developers stick to mailing lists of the various projects/vendors.
With the decline in Usenet traffic, that's much less of a problem nowadays. I haven't seen any spam in comp.lang.lisp for the last 2 years at least. It's pretty much all signal, and mostly high quality too.
You must have some kind of spam filter. Of the 6 (six!) postings to comp.lang.lisp over the last week, half of them were some political anti-cryptocurrency campaing in Italian. But yes, a few years ago it was much worse.
There's a list of Common Lisp resources on Xach's blog [1] that includes communities, which remains relevant despite being an old post.
Also, contacting one of the people associated with a blog listed on Planet Lisp [2] would ensure that it appears there and might be seen by a wide yet relevant audience.
Same. And PG isn't the only one. Plus, there are a plethora of books being published on CL, and enough libraries I'm running into paradox of choice in some domains.
I only had deeper interactions / usage with two Lisps so far: Racket and Clojure.
CL must have some unique appeal that I'm missing. It's community seems to praise it's properties, but is rather quiet otherwise: Interesting talks, projects and companies are be eluding me, especially when compared to the above two Lisps.
The big appeal for me is that Lisp is just weird enough to be fun, and dynamic enough to be expressive with rapid prototyping, but also has mechanisms to write more-structured programs and has quite a lot of batteries included, even if they are somewhat oddball or not necessarily portable across implementations. SBCL with Qlot feels almost like Python to me in terms of how quickly I can bang out a simple but working program. But unlike Python I get to use macros and powerful iteration constructs like DO.
Well, I have a cynical take about the unique appeal of Common Lisp, but even cynicism aside Common Lisp is not going to lose to Racket in the "interesting companies" department, I think. Google Flights is still powered by Common Lisp. Clasp is somewhat interesting (and there is a Google Tech Talk about it, too). And instead of learning "How to Design Programs" from people with unclear experience in designing interesting programs, you can read a book full of small interesting programs written by someone with pretty clear track record of doing interesting things (https://github.com/norvig/paip-lisp).
The Lisps core appeal is that it's an extremely flexible and dynamic language family. They got an unparalleled macro system that lets you effectively design your own DSLs trivially for any scenario you may encounter.
It's also the reason I could never really enjoy CL (or lisps in general): everybody basically ends up using their own dialect of Lisp with their own idiosyncrasies. Some people love the "loop" macro and use it everywhere, some others thing it's ugly and use the equally powerful but syntactically very different "do" construct instead. You can look at some lisp code and have no idea of what it does if you don't expand a few layers of macros first.
That can be true of any language of course, you can abuse overloading, references and macros in C++ if you want, but Lisp really pushes it to the limit in my experience.
Beyond that there's also the problem that the ecosystem is not quite as developed as other more mainstream scripting languages. It doesn't help that the community is split across half a dozen lisp/scheme implementations with often incompatible packages. Do you want to use SBCL? Chicken Scheme? Racket? Guile? Emacs lisp? CLISP? ECL?
> You can look at some lisp code and have no idea of what it does if you don't expand a few layers of macros first.
I've not once expanded a macro in order to see what it does. The only reason I can think of that one would do that is to see how it works, but one also has to look at e.g. the definition of a function to see how that function works, and that should almost never be important. How are macros different? Just like functions, one often has to read the documentation to know how to use a macro, but I'm not sure how being a macro makes (loop for i from min to max do ...) harder to read than a function would be.
Functions can be opaque of course, but macros are worse because anything goes. I think the standard loop macro is a good example of this:
(loop repeat 10
for x = (random 100)
if (evenp x)
collect x into evens
else
collect x into odds
finally (return (values evens odds)))
This macro is actually fairly well designed, so you can guess what all of this does just by interpreting the names (assuming that you understand English well at least) but it's barely Lisp. Just figuring out what parts of this call are keywords and what part are just normal symbols is hard to figure out.
(return ...) looks like a function call, but I don't think it is(?). Is collect a loop-ism or can I replace it by any function name? I think it's the former. Is "into" just here to make grammatical sense or are there other keywords I can use here? If `evens` and `odds` already exist as variable names outside of the loop, will they be used or is it a new local binding? If it is a local binding, how do I tell it to use some existing variable name instead?
Basically it's like printf format strings, it's a language within a language, and idiomatic Common Lisp is often full of that stuff in my experience.
> Basically it's like printf format strings, it's a language within a language...
That's to be expected with a DSL, isn't it? It's almost the definition.
But I think you're right. The point of a DSL is to change the language to something that you find more useful for what you're trying to do. The downside is that you've changed the language, and now people don't know what to expect unless they're very familiar with your DSL.
I think that this opinion is shallow. LOOP and DO are both standard operators, like while and for in C. To paraphrase: "Some people love the 'while' operator and use it everywhere, some others think it's ugly and use the equally powerfully but syntactically very different 'for' construct instead". You could make a case that some CL features are underappreciated, some are overused, and some are used chaotically by different programmers, but this example is not a good one.
If you use the term "scripting language" as an indication, that Common Lisp is interpreted (it is often used in such context) - that is not true - language can't be interpreted, its implementation could - most Common Lisp implementations feature compilers to binary. The standard even provides you with functions compile and compile-file.
Regarding communities: you've mentioned three (or four) different programming languages. Only SBCL, CLISP and ECL are common lisp implementations and they share the same community - because they implement the same standard. It is as if you had said, that there are separate cython and python communities - each implementation has its merits, but users of both are usually part of the same python community. Similar comparison would be between clang and gcc programmers. Many many Common Lisp systems work well on different implementations of that programming language (some with compatibility layers, some are simply portable programs).
If you're just into functional programming and expressiveness, Clojure blows CL out of the water. Scheme also feels more cohesive, at least R(4,5)RS which is what I know.
The appeal of Common Lisp (to me) are CLOS, the condition/restart system, commercial portable GUI toolkits and specially the low level capabilities. Compared to it, Clojure just feels like a verbose APL.
Depending on the camp you are, Dylan, Factor and Julia are better Lisps than Scheme and Clojure, even if they are not s-expression based.
CL is more of an "industrial strength" Lisp. It compiles to the metal [0] so no VM is needed which makes it very fast and also appropriate for embedded applications (e.g. home automation on an RPi or Odroid). It has excellent numerical functions so it's nice for scientific computing (I use it for research others might use Matlab or Julia for), and it contains CLOS, which is probably the most powerful O-O system ever built.
If you need to write a Very Large Lisp program for an industrial application with a lot of moving parts that has to run fast, you probably want Common Lisp.
[0] Racket is now compiled to the metal now too with the recent Chez compiler integration.
I've tinkered with CL for numerical analysis, but always have had trouble picking good libraries to help. Do you have any recommendations for good libraries for scientific computing (especially some that will run in Windows)?
I've done a mixture of Scheme, Common Lisp and Clojure for fun. I've skimmed the Racket docs, but never took the plunge, in part because the license weirds me out a bit. Scheme always struck me as the better designed language, but Common Lisp tends to be more pragmatic. The latest Scheme reports only made the problem worse by further fragmenting the community.
The main problem I tended to have when starting projects in CL/Scheme was library support. Sure, I could wrap whatever libraries I needed in SWIG or the implementation's FFI, but that was work taken out of my all-too-small pool of time to work on something that wasn't the problem that interested me.
Clojure solves this problem by being hosted while also making a lot of the language changes I once dreamed of making to Scheme and Common Lisp.
Versus the other two, I'd say it's much less of a functional programming language; you have arrays, mutation, and powerful loop syntax (that expands to gotos!). My experience (writing CL at work and for personal projects) is that CL is the perfected form of Python, whereas when I used Racket in the past it felt more like a cousin of ML.
Common Lisp has been a major driver for me since 1982, but I also enjoy Racket, Clojure, and Haskell a lot. The Common Lisp community may be small, but I like the energy and enthusiasm!
Programming language selection however really does not matter that much. I have also been very happy working on projects using Java, Python, JavaScript, and Ruby.
I would never try to talk anyone out of using whatever programming language is their favorite.
I'm solving advent of code puzzles in Julia (first) and Common Lisp (second). So far I like it quite a lot and I'm surprised that even my naive CL code is comparable with Julia when it comes to efficiency (0.004s Julia vs. 0.009 CL for day 2).
Common Lisp not only explicitly has the notion of compilation as a part of the language definition and standard library, but the language is/was also traditionally seen as ripe for native compilation. Efficient and serious compilation of Lisp dates back to at least the late 70s.
I don't mean the syntax, or the concept of macros (though I'm sure my understanding of macros is incomplete) but what I find is lacking in the documentation is how one actually might use lisp.
I read stories about "connecting to" a "running lisp" on a space probe and debugging in real time. Does that mean some lisp implementations listen on a tcp port? How does one actually connect to or disconnect from a repl? Is it just that when NASA launched their probe, someone went in on ssh and moved the process to the background with C-z?
How does one deploy a lisp application? Can I compile my code into an executable with, say, sbcl which is what everyone seems to use? Or am I forced to rsync all my source code to my server and get e.g. systemd to manually invoke an entry point?
I'm new to Lisp, having started SICP last month, but I can answer some.
The space probes are probably just a standard serial port (RS-232 style UART), with some radio protocol that has good error correction/stability. In amateur radio, FT-8 is a slow, reliable, long distance serial protocol often used for hobbyist DX (long distance goal) communication. So likely, yes, they have a minimal shell or REPL-style debugger, where they can at least query variables, and change the machine state. Most aerospace devices use single-user Real Time Operating Systems, which have guaranteed timing on programs running, but to a technician end-user, the feeling is similar to an old Unix system, with similar tool names.
You can deploy via compilation, with SBCL, or LLVM, etc. But I've mostly seen Lisp (well, I'm looking at Schemes, specifically) extending a compiled app. It's been pretty trivial connecting Racket to my compiled C functions, and I'll try Guile later, and for me it's mostly been a rapid-development tool to work with my WIP C library.
It's common to use slime with emacs, but vim and atom work too. Slime includes a lisp program called swank which sets up a simple server that clients like emacs can open a socket to. In Common Lisp, "compile", "eval", "load", "break", etc. are built-in functions. Lisp programs are 'alive' and can be constructed or debugged and updated by compiling and executing bit by bit without having to suspend or restart the process, using the socket to communicate how to grow. Some examples are in this several part series you can take 10 mins to browse through: https://malisper.me/debugging-lisp-part-1-recompilation/ Going beyond that into say developing a full application with version pinning of dependencies and tests is documented in books/in pieces on the web (CL cookbook has a lot).
But manuals tell a lot too. Under SBCL's Saving a Core Image, you can see a standalone executable can be made with save-lisp-and-die. But you can also load things with --script if you want a python or node like experience.
I've read the SBCL manual before, several times. It's not suitable for learning Lisp; it's written for people who already know Lisp but need an implementation-specific question answered.
Let me illustrate:
Suppose I want to compile my lisp code into an executable for easy deployment. My first step is opening the SBCL manual and reading the entire section on the compiler. There's nothing in there about how to actually invoke the compiler. Maybe there's a command line option. Read section 3 and find the "saving a core image" section. It has lots of verbiage about saving state to disk so that you can restart the program in the same state.
But I don't want to restart in whatever garbled development state I'm currently in. I want the program to start in the initial state and progress normally, the way a program in just about any other language would naturally execute. I want execution to begin at the entry point (does Lisp even have "entry points"? There's another 5 hours of wasted time trying to figure that one out) and progress naturally like it does in literally any other language I can think of. By saving the current state how do I know I'm not introducing bugs due to some variable holding inadvertent state when I save-and-die?
Okay so now I'm down the rabbit hole of stackoverflow and personal websites from random PhD computer science students at Carnegie Mellon from 2001 and about now is when I usually get frustrated, say "fuck it", and move on to a language like C# that actually has good documentation with copious examples (not to mention a library for just about everything), has an execution model that's actually easy to understand, and move on with my life.
I say this as an aerospace engineer: I'm a smart guy but Lisp must be beyond my reach as a mere mortal without a computer science degree. I went through most of the Gigamonkeys book and while I can write a mean LOOP macro I can't actually do anything useful with lisp. The documentation is too confusing and too fragmented.
I want to like Lisp but it fights me every step of the way.
You’re complicating to too much. You write a makefile to load your lisp code (which usually means loading your ASDF system), and dump the image (e.g., save-lisp-and-die). Development and deployment are separate in pretty much any language.
Here is a real example from a real commercial project:
Everything you’ve seemed to use are completely free and open source solutions. Common Lisp has at least two major commercial options with excellent documentation which you’re looking for: LispWorks and Allegro CL.
I guess I don't know what to say other than if you really want to learn Lisp, you have to meet it on its own terms. It's old, its heritage is older and always offered a different approach to the batch style of Fortran, it's not going to change for you.
I hate this kind of wording because it makes it seem that Lisp is mysterious, or super difficult, or requires a ton of unlearning, or has no good (and free) learning material (you knock it but I enjoy Steele's 30 year old cltl2 mirrored on a CMU page), or is only for impractical purposes and CS-guilded programmers. I don't believe any of that, there are plenty of examples to the contrary. In contrast your own difficulties are puzzling. I hesitate to suggest reading, watching, or doing anything else, though things come to mind, simply to avoid wasting your time or money further if you took me up on any of it, as it might all be useless.
>It's old, its heritage is older and always offered a different approach to the batch style of Fortran, it's not going to change for you.
I'm not asking for Lisp to change. I'm explaining why Lisp is hard to learn.
>I hate this kind of wording because it makes it seem that Lisp is mysterious [...] or requires a ton of unlearning
In my experience these things are 110% true. Even ASDF uses strange terminology completely divorced from modern usage. What are systems and modules, and how do they map to what every other language calls a package or a library? I have no idea. The "Getting Started with ASDF" page that was the top hit on Google works through an example where they define a Cow System that has legs, tail, head, etc. That's the usual example when talking about class inheritance... So are systems classes? What about CLOS?
How the fuck do I get packaging in lisp?
Again, here is where I usually give up.
>In contrast your own difficulties are puzzling.
Okay, well they're still the difficulties I'm hitting.
I see lots of puzzlement on HN and elsewhere as to why Lisp isn't more popular than it is, and I honestly believe this is partly why. I have a busy job and soon to be a second child; I could spend my time trawling through powerpoint slides from MIT courses that took place in 2008 trying to find the answers, or I could brave the extremely caustic world of stackoverflow (no thanks, I deal with enough condescension already), or I could just give up and pick a different language and get up to speed faster and with less frustration.
>I guess I don't know what to say other than if you really want to learn Lisp
I guess I did want to learn Lisp, until I actually started trying to use it. The language itself seems awesome but the ecosystem around it, including the onboarding experience for non-graybeards, is pretty bad.
It is not hard to learn in general, there are too many counterexamples of people of all sorts and skills learning it without these issues you are having, learning it as their first, learning it later in their careers... (CL is big, I'll give you that, but each piece can be chewed one at a time and does not seem to be individually that difficult.) So I can hypothesize why it's hard to learn for you. My first guess is still that you aren't meeting Lisp in its own terms and are trying to make Lisp fit your mental model of some other language and its ecosystem. This isn't going to work, and the failure mode (if I'm right) has nothing to do with Lisp but with biases in general heuristics of learning.
You don't need to "unlearn" the way you're used to doing things, but you do need to separate yourself from it for a bit until you actually grasp the Lisp (and its ecosystem's) way(s) and can then see the connections, tenuous and non-existent as some may be. I'll risk raising some of those connections below, but really, things need to be understood on their own terms first or you wind up with misconceptions. (I've seen it multiple times with Java/Python programmers getting confused at the other's "import" statement.)
> strange terminology
It's not Lisp's fault that it's old. Being old means it will have terminology that may be alien to what we have today with nothing today being a perfect fit, or alternatively sometimes it expresses mostly what we say today in a different way. (And when you talk about concepts, not just pure language features, you run into incommensurability. See https://dreamsongs.com/Files/Incommensurability.pdf for an example with Mixins.)
CLOS for example has these things called "slots" which are more or less "fields" or "class/instance variables" in later OOP languages. But it's best to think of them as CLOS slots, so that you don't bring along any (mis)conceptions from other languages. It's sometimes amusing how different other OOP systems are given CLOS was the first to be part of an ANSI standard.
> that took place in 2008
I rather like that I can often find things decades old about Lisp and they are still relevant. Systems are at least as early as the Lisp Machine (1979). Perhaps it's worth going to the original description there? I also sort of like this history diving, even if modern sources obsolete the history in every way that matters. But here is the Lisp Machine manual on the topic: https://hanshuebner.github.io/lmman/maksys.xml "The way it works is that you define a set of files to be a system, using the defsystem special form, described below."
Is that unclear? Systems are first and foremost sets of files. Systems also let you define relations between files, primarily which files depend on which other files, as further sentences reveal.
If you're talking about this page as the first result: https://common-lisp.net/~mmommer/asdf-howto.shtml I agree it's an awful guide. I've never seen it before, it's a shame it's the #1 result. You'd be best served by ignoring it. Systems have nothing to do with CLOS, I assume that guide started trying to use animal parts as a way to elucidate dependencies. (A tail doesn't actually depend on legs though?)
Lisp has great support for the batch style of Fortran.
I started in Lisp in around the year 2000. In 2002, I released a program called Meta-CVS: a wrapper version control system based on CVS storage, and using the cvs program under the hood. With Meta-CVS, you could store permissions, symbolic links and the directory structure itself as a versioned object. Plus do things like imports of code snapshots with automatic rename detection.
Meta-CVS uses Makefile to build. Every .fasl depeneds on the corresponding .lisp and is recompiled if it changes. The CLISP memory image depends on the .fasls and so on.
> But I don't want to restart in whatever garbled development state I'm currently in.
Right; the thing to is to start a completely new image, and the only thing you do in this image is load all of your compiled files, and then call the image-saving function.
This was pretty obvious to me, coming from a C background.
My first Lisp programs used Makefiles to do this stuff.
You don't want to sit there and making deployed executables manually out of your dirty hacking session, of course.
> I want execution to begin at the entry point
Common Lisp implementations typically offer some image saving function, which has an argument for specifying something to be evaluated when that image is restarted, or a function to be called or some such.
This general area is called "application delivery": you have to investigate the ways that your Lisp implementation offers application delivery. Saving an image might not be the only way; there may be a way to create an executable which isn't a saved image. In some Lisps, the hash-bang mechanism is supported, and that is appropriate in some situations. Some Lisps can produce shared library, even.
It's a web-browser heavily inspired by Emacs. It uses WebKitGTK+ as a backend, and they also have CL bindings for QtWebEngine, which uses code from Chromium, though I don't know if they have any plans to eventually support that as an alternate backend for Nyxt.
• 40% interact with the Common Lisp (CL) community on Reddit and 32% on IRC. Indeed, in my experience too https://www.reddit.com/r/lisp/ and Freenode #lisp channels have active and supportive CL communities.
• 89% use SBCL. This is not surprising. SBCL has been the most popular Common Lisp implementation for a long time.
• 48% are 32 years old or younger. This is going to help the CL community to stay active for, I believe, at least another 20 years and perhaps even beyond that if the community can attract more programmers to this language. It is a beautiful language that is a joy to program in, so I do wonder why it isn't more popular.
• 31% are from the US. Countries like China, India, Netherlands, Poland, etc. have less than 3% respondents to the survey.
Incidentally, a bunch of us from Freenode IRC are doing a Common Lisp Programming Challenge this month. The objective is to help beginners get started with learning the language while being a part of a community. You don't have to join Freenode IRC to join the challenge. If you are interested in participating in it, please visit https://github.com/spxy/clpc to participate in the challenge.
71 comments
[ 3.5 ms ] story [ 141 ms ] threadNow there are lists with almost 400 answers with most of the answers being practically the same ("personal stuff", "personal projects", "personal things"...). It does not make it easy to digest the information.
Which is actually kind of fine with me. After a long long period of people only being interested in asking questions when the answer can be graphed, it's nice to see some individuals' actual feelings and opinions showing through in the results. For example, "all tasks that do not require close OS functionality" was a gem of a response that you'd never see in a survey that consisted solely of checkboxes and radio buttons.
(for the lucky 10,000: http://www.winestockwebdesign.com/Essays/Lisp_Curse.html)
The request "Update on October 6, 2017. N.B.: Please stop submitting this to Hacker News!" should be interpreted in its strongest form: i.e. including comments.
> "Making Scheme object-oriented is a sophomore homework assignment."
Demonstrating basic OOP in C is likewise a suitable homework assignment.
http://rosettacode.org/wiki/Inheritance/Single/C
Making a viable object-oriented programming system for others to use is not a trivial task in any language.
No object system for Scheme that people actually use had been written by a sophomore as homework and gone into production in that state. (Linux started by a school kid tinkering with kernel programming too; but it would be a strawman to say that a bright undergrad can make a serious Unix clone in a few weeks that Amazon can put into the cloud and sell services on.)
The Common Lisp object system took many people years of work, and integrates deeply into the language, such that every object type has a class and can participate meaningfully in the object system without being wrapped in a class.
> Due to the difficulty of making C object oriented, only two serious attempts at the problem have made any traction: C++ and Objective-C.
Those are examples of having enough traction to actually get people to switch from C to a new language.
Ad hoc object systems have been implemented in C programs umpteen times, and a number of such things are available, or have been historically available, as formal libraries for use in C programs.
These all have "traction" in their "respective" projects and ecosystems; there is a lot of OOP action within C.
Including CLOS-like OO extensions for C.
Like Dynace:
https://github.com/blakemcbride/Dynace
Anyhow, in this instance you're right that there isn't even a need for open fields, there's enough examples online already of IT being separated into distinct sectors for field selection on forms.
But what really grated me the most about the results was that there didn't even seem to be any deduping of the results (or if there was, it was case sensitive):
And there was even an instance where prototyping appeared twice because one instance had \s afterwards!- CL is mostly used by hobbyists. (Not a very big surprise.)
- There do seem to be several users in research computing. (As a computational biologist, I find this interesting and encouraging.)
- The user demographics skew towards younger adults (<45 yrs). (That's interesting because they weren't around yet during Lisp's heyday, so the language seems to retain enough appeal to still attract new users.)
- User's top 5 countries of origin: USA (30%), Germany (10%), UK (5.4%), Japan (5%), Canada (4.3%). (Not quite as anglophone-leaning as I'd expected; there's actually a very wide spread of countries represented.)
However, I don't know how this survey was advertised, so the results may just be sampling bias.
I'd be careful interpreting numbers like those. This isn't measuring the age demographics of CL users, per se. It's measuring the age demographics of people who responded to the survey. ~25% of that group self-reported as not actually being (current) lisp users.
Including people who don't actively use lisp in the sample is entirely valid, and capturing that information about them would facilitate some interesting analyses. For example, we could look for demographic differences among professional lispers, hobbyist lispers, and curious onlookers. Or see if there are any industry trends.
It's just that this Google doc reports these data in a way that's too coarse-grained to support that kind of analysis, regardless of any bias concerns.
I created this survey. I originally posted it to the CL subreddit and the CL IRC channel, so somewhat limited communication channels. Maybe there are other, better places to post it?
Also, contacting one of the people associated with a blog listed on Planet Lisp [2] would ensure that it appears there and might be seen by a wide yet relevant audience.
[1] https://xach.livejournal.com/325276.html
[2] https://planet.lisp.org/
I think surveys like this are representative of dark matter programmers - Clojure over time changed from a hobby to work language.
CL must have some unique appeal that I'm missing. It's community seems to praise it's properties, but is rather quiet otherwise: Interesting talks, projects and companies are be eluding me, especially when compared to the above two Lisps.
It's a standard for the main Lisp language with multiple very different implementations, including commercial offerings.
For example at least two quantum computer companies use Common Lisp deep in their stuff.
Currently D-Wave is looking for a Lisp developer for their processor group:
https://jobs.lever.co/dwavesys/eca1f300-d90b-460f-9b7e-2660b...
CL most cited value: more featured repl, better live debugging
It's also the reason I could never really enjoy CL (or lisps in general): everybody basically ends up using their own dialect of Lisp with their own idiosyncrasies. Some people love the "loop" macro and use it everywhere, some others thing it's ugly and use the equally powerful but syntactically very different "do" construct instead. You can look at some lisp code and have no idea of what it does if you don't expand a few layers of macros first.
That can be true of any language of course, you can abuse overloading, references and macros in C++ if you want, but Lisp really pushes it to the limit in my experience.
Beyond that there's also the problem that the ecosystem is not quite as developed as other more mainstream scripting languages. It doesn't help that the community is split across half a dozen lisp/scheme implementations with often incompatible packages. Do you want to use SBCL? Chicken Scheme? Racket? Guile? Emacs lisp? CLISP? ECL?
I've not once expanded a macro in order to see what it does. The only reason I can think of that one would do that is to see how it works, but one also has to look at e.g. the definition of a function to see how that function works, and that should almost never be important. How are macros different? Just like functions, one often has to read the documentation to know how to use a macro, but I'm not sure how being a macro makes (loop for i from min to max do ...) harder to read than a function would be.
(return ...) looks like a function call, but I don't think it is(?). Is collect a loop-ism or can I replace it by any function name? I think it's the former. Is "into" just here to make grammatical sense or are there other keywords I can use here? If `evens` and `odds` already exist as variable names outside of the loop, will they be used or is it a new local binding? If it is a local binding, how do I tell it to use some existing variable name instead?
Basically it's like printf format strings, it's a language within a language, and idiomatic Common Lisp is often full of that stuff in my experience.
That's to be expected with a DSL, isn't it? It's almost the definition.
But I think you're right. The point of a DSL is to change the language to something that you find more useful for what you're trying to do. The downside is that you've changed the language, and now people don't know what to expect unless they're very familiar with your DSL.
If you use the term "scripting language" as an indication, that Common Lisp is interpreted (it is often used in such context) - that is not true - language can't be interpreted, its implementation could - most Common Lisp implementations feature compilers to binary. The standard even provides you with functions compile and compile-file.
Regarding communities: you've mentioned three (or four) different programming languages. Only SBCL, CLISP and ECL are common lisp implementations and they share the same community - because they implement the same standard. It is as if you had said, that there are separate cython and python communities - each implementation has its merits, but users of both are usually part of the same python community. Similar comparison would be between clang and gcc programmers. Many many Common Lisp systems work well on different implementations of that programming language (some with compatibility layers, some are simply portable programs).
If you're just into functional programming and expressiveness, Clojure blows CL out of the water. Scheme also feels more cohesive, at least R(4,5)RS which is what I know.
The appeal of Common Lisp (to me) are CLOS, the condition/restart system, commercial portable GUI toolkits and specially the low level capabilities. Compared to it, Clojure just feels like a verbose APL.
Depending on the camp you are, Dylan, Factor and Julia are better Lisps than Scheme and Clojure, even if they are not s-expression based.
If you need to write a Very Large Lisp program for an industrial application with a lot of moving parts that has to run fast, you probably want Common Lisp.
[0] Racket is now compiled to the metal now too with the recent Chez compiler integration.
Here's a library I trust for linear algebra that uses BLAS and LAPACK. I haven't tried it on Windows.
https://github.com/rigetti/magicl
And of course there's always Maxima, the clone of Macsyma which was the grandfather of Mathematica:
https://en.wikipedia.org/wiki/Maxima_(software)
The main problem I tended to have when starting projects in CL/Scheme was library support. Sure, I could wrap whatever libraries I needed in SWIG or the implementation's FFI, but that was work taken out of my all-too-small pool of time to work on something that wasn't the problem that interested me.
Clojure solves this problem by being hosted while also making a lot of the language changes I once dreamed of making to Scheme and Common Lisp.
Programming language selection however really does not matter that much. I have also been very happy working on projects using Java, Python, JavaScript, and Ruby.
I would never try to talk anyone out of using whatever programming language is their favorite.
I don't mean the syntax, or the concept of macros (though I'm sure my understanding of macros is incomplete) but what I find is lacking in the documentation is how one actually might use lisp.
I read stories about "connecting to" a "running lisp" on a space probe and debugging in real time. Does that mean some lisp implementations listen on a tcp port? How does one actually connect to or disconnect from a repl? Is it just that when NASA launched their probe, someone went in on ssh and moved the process to the background with C-z?
How does one deploy a lisp application? Can I compile my code into an executable with, say, sbcl which is what everyone seems to use? Or am I forced to rsync all my source code to my server and get e.g. systemd to manually invoke an entry point?
The space probes are probably just a standard serial port (RS-232 style UART), with some radio protocol that has good error correction/stability. In amateur radio, FT-8 is a slow, reliable, long distance serial protocol often used for hobbyist DX (long distance goal) communication. So likely, yes, they have a minimal shell or REPL-style debugger, where they can at least query variables, and change the machine state. Most aerospace devices use single-user Real Time Operating Systems, which have guaranteed timing on programs running, but to a technician end-user, the feeling is similar to an old Unix system, with similar tool names.
You can deploy via compilation, with SBCL, or LLVM, etc. But I've mostly seen Lisp (well, I'm looking at Schemes, specifically) extending a compiled app. It's been pretty trivial connecting Racket to my compiled C functions, and I'll try Guile later, and for me it's mostly been a rapid-development tool to work with my WIP C library.
Under the dev-tools/editor section you'll see slime mentioned. It too has a manual: https://www.common-lisp.net/project/slime/doc/html/
It's common to use slime with emacs, but vim and atom work too. Slime includes a lisp program called swank which sets up a simple server that clients like emacs can open a socket to. In Common Lisp, "compile", "eval", "load", "break", etc. are built-in functions. Lisp programs are 'alive' and can be constructed or debugged and updated by compiling and executing bit by bit without having to suspend or restart the process, using the socket to communicate how to grow. Some examples are in this several part series you can take 10 mins to browse through: https://malisper.me/debugging-lisp-part-1-recompilation/ Going beyond that into say developing a full application with version pinning of dependencies and tests is documented in books/in pieces on the web (CL cookbook has a lot).
But manuals tell a lot too. Under SBCL's Saving a Core Image, you can see a standalone executable can be made with save-lisp-and-die. But you can also load things with --script if you want a python or node like experience.
Let me illustrate:
Suppose I want to compile my lisp code into an executable for easy deployment. My first step is opening the SBCL manual and reading the entire section on the compiler. There's nothing in there about how to actually invoke the compiler. Maybe there's a command line option. Read section 3 and find the "saving a core image" section. It has lots of verbiage about saving state to disk so that you can restart the program in the same state.
But I don't want to restart in whatever garbled development state I'm currently in. I want the program to start in the initial state and progress normally, the way a program in just about any other language would naturally execute. I want execution to begin at the entry point (does Lisp even have "entry points"? There's another 5 hours of wasted time trying to figure that one out) and progress naturally like it does in literally any other language I can think of. By saving the current state how do I know I'm not introducing bugs due to some variable holding inadvertent state when I save-and-die?
Okay so now I'm down the rabbit hole of stackoverflow and personal websites from random PhD computer science students at Carnegie Mellon from 2001 and about now is when I usually get frustrated, say "fuck it", and move on to a language like C# that actually has good documentation with copious examples (not to mention a library for just about everything), has an execution model that's actually easy to understand, and move on with my life.
I say this as an aerospace engineer: I'm a smart guy but Lisp must be beyond my reach as a mere mortal without a computer science degree. I went through most of the Gigamonkeys book and while I can write a mean LOOP macro I can't actually do anything useful with lisp. The documentation is too confusing and too fragmented.
I want to like Lisp but it fights me every step of the way.
Here is a real example from a real commercial project:
Makefile: https://github.com/rigetti/quilc/blob/master/Makefile#L72
Build script: https://github.com/rigetti/quilc/blob/master/build-app.lisp
Everything you’ve seemed to use are completely free and open source solutions. Common Lisp has at least two major commercial options with excellent documentation which you’re looking for: LispWorks and Allegro CL.
I hate this kind of wording because it makes it seem that Lisp is mysterious, or super difficult, or requires a ton of unlearning, or has no good (and free) learning material (you knock it but I enjoy Steele's 30 year old cltl2 mirrored on a CMU page), or is only for impractical purposes and CS-guilded programmers. I don't believe any of that, there are plenty of examples to the contrary. In contrast your own difficulties are puzzling. I hesitate to suggest reading, watching, or doing anything else, though things come to mind, simply to avoid wasting your time or money further if you took me up on any of it, as it might all be useless.
I'm not asking for Lisp to change. I'm explaining why Lisp is hard to learn.
>I hate this kind of wording because it makes it seem that Lisp is mysterious [...] or requires a ton of unlearning
In my experience these things are 110% true. Even ASDF uses strange terminology completely divorced from modern usage. What are systems and modules, and how do they map to what every other language calls a package or a library? I have no idea. The "Getting Started with ASDF" page that was the top hit on Google works through an example where they define a Cow System that has legs, tail, head, etc. That's the usual example when talking about class inheritance... So are systems classes? What about CLOS?
How the fuck do I get packaging in lisp?
Again, here is where I usually give up.
>In contrast your own difficulties are puzzling.
Okay, well they're still the difficulties I'm hitting.
I see lots of puzzlement on HN and elsewhere as to why Lisp isn't more popular than it is, and I honestly believe this is partly why. I have a busy job and soon to be a second child; I could spend my time trawling through powerpoint slides from MIT courses that took place in 2008 trying to find the answers, or I could brave the extremely caustic world of stackoverflow (no thanks, I deal with enough condescension already), or I could just give up and pick a different language and get up to speed faster and with less frustration.
>I guess I don't know what to say other than if you really want to learn Lisp
I guess I did want to learn Lisp, until I actually started trying to use it. The language itself seems awesome but the ecosystem around it, including the onboarding experience for non-graybeards, is pretty bad.
It is not hard to learn in general, there are too many counterexamples of people of all sorts and skills learning it without these issues you are having, learning it as their first, learning it later in their careers... (CL is big, I'll give you that, but each piece can be chewed one at a time and does not seem to be individually that difficult.) So I can hypothesize why it's hard to learn for you. My first guess is still that you aren't meeting Lisp in its own terms and are trying to make Lisp fit your mental model of some other language and its ecosystem. This isn't going to work, and the failure mode (if I'm right) has nothing to do with Lisp but with biases in general heuristics of learning.
You don't need to "unlearn" the way you're used to doing things, but you do need to separate yourself from it for a bit until you actually grasp the Lisp (and its ecosystem's) way(s) and can then see the connections, tenuous and non-existent as some may be. I'll risk raising some of those connections below, but really, things need to be understood on their own terms first or you wind up with misconceptions. (I've seen it multiple times with Java/Python programmers getting confused at the other's "import" statement.)
> strange terminology
It's not Lisp's fault that it's old. Being old means it will have terminology that may be alien to what we have today with nothing today being a perfect fit, or alternatively sometimes it expresses mostly what we say today in a different way. (And when you talk about concepts, not just pure language features, you run into incommensurability. See https://dreamsongs.com/Files/Incommensurability.pdf for an example with Mixins.)
CLOS for example has these things called "slots" which are more or less "fields" or "class/instance variables" in later OOP languages. But it's best to think of them as CLOS slots, so that you don't bring along any (mis)conceptions from other languages. It's sometimes amusing how different other OOP systems are given CLOS was the first to be part of an ANSI standard.
> that took place in 2008
I rather like that I can often find things decades old about Lisp and they are still relevant. Systems are at least as early as the Lisp Machine (1979). Perhaps it's worth going to the original description there? I also sort of like this history diving, even if modern sources obsolete the history in every way that matters. But here is the Lisp Machine manual on the topic: https://hanshuebner.github.io/lmman/maksys.xml "The way it works is that you define a set of files to be a system, using the defsystem special form, described below."
Is that unclear? Systems are first and foremost sets of files. Systems also let you define relations between files, primarily which files depend on which other files, as further sentences reveal.
If you're talking about this page as the first result: https://common-lisp.net/~mmommer/asdf-howto.shtml I agree it's an awful guide. I've never seen it before, it's a shame it's the #1 result. You'd be best served by ignoring it. Systems have nothing to do with CLOS, I assume that guide started trying to use animal parts as a way to elucidate dependencies. (A tail doesn't actually depend on legs though?)
I don't recall how I learned systems, probably because a mix of ASDF's manual (https://common-lisp.net/projec...
I started in Lisp in around the year 2000. In 2002, I released a program called Meta-CVS: a wrapper version control system based on CVS storage, and using the cvs program under the hood. With Meta-CVS, you could store permissions, symbolic links and the directory structure itself as a versioned object. Plus do things like imports of code snapshots with automatic rename detection.
Meta-CVS uses Makefile to build. Every .fasl depeneds on the corresponding .lisp and is recompiled if it changes. The CLISP memory image depends on the .fasls and so on.
Using Lisp like C in this manner is just fine.
2) LOAD your code
3) specify a toplevel function (aka 'entry point') and let it be executable -> SAVE-LISP-AND-DIE
Result: a standalone executables which starts up with the toplevel function you have specified
Right; the thing to is to start a completely new image, and the only thing you do in this image is load all of your compiled files, and then call the image-saving function.
This was pretty obvious to me, coming from a C background.
My first Lisp programs used Makefiles to do this stuff.
You don't want to sit there and making deployed executables manually out of your dirty hacking session, of course.
> I want execution to begin at the entry point
Common Lisp implementations typically offer some image saving function, which has an argument for specifying something to be evaluated when that image is restarted, or a function to be called or some such.
This general area is called "application delivery": you have to investigate the ways that your Lisp implementation offers application delivery. Saving an image might not be the only way; there may be a way to create an executable which isn't a saved image. In some Lisps, the hash-bang mechanism is supported, and that is appropriate in some situations. Some Lisps can produce shared library, even.
https://github.com/atlas-engineer/nyxt
It's a web-browser heavily inspired by Emacs. It uses WebKitGTK+ as a backend, and they also have CL bindings for QtWebEngine, which uses code from Chromium, though I don't know if they have any plans to eventually support that as an alternate backend for Nyxt.
• 40% interact with the Common Lisp (CL) community on Reddit and 32% on IRC. Indeed, in my experience too https://www.reddit.com/r/lisp/ and Freenode #lisp channels have active and supportive CL communities.
• 89% use SBCL. This is not surprising. SBCL has been the most popular Common Lisp implementation for a long time.
• 48% are 32 years old or younger. This is going to help the CL community to stay active for, I believe, at least another 20 years and perhaps even beyond that if the community can attract more programmers to this language. It is a beautiful language that is a joy to program in, so I do wonder why it isn't more popular.
• 31% are from the US. Countries like China, India, Netherlands, Poland, etc. have less than 3% respondents to the survey.
Incidentally, a bunch of us from Freenode IRC are doing a Common Lisp Programming Challenge this month. The objective is to help beginners get started with learning the language while being a part of a community. You don't have to join Freenode IRC to join the challenge. If you are interested in participating in it, please visit https://github.com/spxy/clpc to participate in the challenge.