[HN Gopher] Why Lisp?
       ___________________________________________________________________
        
       Why Lisp?
        
       Author : susam
       Score  : 164 points
       Date   : 2021-11-12 17:29 UTC (5 hours ago)
        
 (HTM) web link (atlas.engineer)
 (TXT) w3m dump (atlas.engineer)
        
       | jmugan wrote:
       | Lisp code I write today may run 10 years from now, but would I be
       | able to read it a month from now? Maybe I just never got familiar
       | enough with it, but code I wrote for my AI class was meaningless
       | to me 6 months later.
        
         | Jtsummers wrote:
         | That's a general problem, not a _Lisp_ problem. Code will
         | always be harder to read later, especially code from when
         | someone was new to the language (I wouldn 't want be able to
         | read most of my grad school AI class code from 15 years ago
         | either). But that's not unique to Lisp code. My Java, Python,
         | C, C++, Smalltalk, SML, Scheme, Prolog code from other courses
         | in college would almost all be pretty incomprehensible
         | (depending on the scope of the particular project it was
         | composed for, and how far into my academic career it was
         | written). If you're a moderately experienced programmer and you
         | spend more than a few weeks learning Lisp, you should be able
         | to write code that's perfectly understandable months later.
        
         | lispm wrote:
         | One better be able to read old code. For example the first
         | lines of the SBCL Lisp implementation were written around 1980,
         | when it was called Spice Lisp. The version from 1984 looks
         | readable:
         | http://www.softwarepreservation.org/projects/LISP/cmu/Spice_...
        
       | jmkr wrote:
       | Having never used Common Lisp, it's one of the languages I wish
       | I've used for a long time.
       | 
       | However, working with Clojure and Scheme, I understand the power
       | of repl driven development that is difficult to explain outside
       | the experience of it.
        
         | Qem wrote:
         | That happens with languages in the Smalltalk family too, like
         | Pharo. It's hard to convey the convenience of the Transcript
         | window and the while environment without actually showing ir
         | experiencing it.
        
         | capableweb wrote:
         | > I understand the power of repl driven development that is
         | difficult to explain outside the experience of it.
         | 
         | I've been having trouble with this as well. I think we'd do
         | best in removing "REPL" from any explainations, and instead use
         | the words "Interactive Development", "Dynamic Development",
         | "Hot Reload on Steroids" or something similar, as when I use
         | terms like that, people understand it's nothing like the
         | "repls" ("shells" really) other languages provides.
        
           | lispm wrote:
           | The REPL is the nucleus of interactivity in Lisp.
           | 
           | The first Lisp, called LISP I and its successors, from John
           | McCarthy and his team had a remarkable collection of
           | innovative technology:
           | 
           | * a reader for symbolic expressions. These are nested lists
           | of symbols and other data objects like numbers and strings
           | 
           | * a printer for symbolic expressions.
           | 
           | * an evaluator for symbolic expressions. Each symbolic
           | expression evaluates to a value. Side effects to the running
           | Lisp could be added variables, data or function definitions.
           | 
           | * an automatic garbage collector taking care of freeing no
           | longer used memory
           | 
           | * piece-by-piece allocation of data
           | 
           | * a form of programming with functions, also using recursion
           | 
           | * a way for Lisp to store and restore the main memory heap
           | to/from external storage
           | 
           | * Lisp compiler written in Lisp, which generates assembler,
           | and an assembler which creates code into the runtime -> the
           | first interactive incremental to memory compiler
           | 
           | * a way to program with Lisp code generated by Lisp macros
           | 
           | It had a batch REPL. This Read-Eval-Print-Loop would read a
           | file of expressions, expression by expression, evaluate them
           | and print each return value into a file. It used the above
           | functions READ, EVAL and PRINT.
           | 
           | Lisp was starting up and restoring a default image as the
           | heap. It would then execute the file via the batch REPL and
           | save a new, changed image as the new default image. Next time
           | Lisp starts, it would then restore the latest image.
           | 
           | A next step in the evolution was then to connect a terminal
           | and let the user enter a Lisp expression. Lisp reads it,
           | evaluates it and prints the value back. Side effects again
           | might change the running Lisp. The REPL then waits for the
           | next terminal input. Code could also be loaded from files.
           | 
           | That way the REPL was not some interface which the debugger
           | brings up on request. It was the main interface for the
           | programmer to build up large Lisp systems piece by piece.
           | 
           | We are talking about the early 60s here.
           | 
           | In the coming decades the idea of a REPL morphed into
           | extensive interactive resident development environments like
           | Interlisp <http://interlisp.org>. Interlisp combined the REPL
           | with managed source code, structure editing for code and
           | data, automatic error correction of code, undo of evaluation
           | effects, a virtual machine, ... and a lot more. Here Lisp,
           | the IDE and the programs under development were running in
           | one Lisp runtime. We are talking about the early 70s.
           | 
           | Interlisp moved at Xerox PARC onto their new graphical
           | workstations. Thus the REPL-based development environment
           | moved to graphical user interfaces. The Interlisp team got an
           | ACM Award for their pioneering work.
           | 
           | The MIT AI Lab took that idea to their graphical Lisp
           | Machines.
           | 
           | Today in 2021 Lisp programmers often use SBCL as the
           | implementation, GNU Emacs and SLIME (or similar) as their
           | development environment. It's still usual to develop a
           | running program, having potential multiple REPLs into the
           | program, using Emacs/SLIME to send code for remote evaluation
           | to the running Lisp.
           | 
           | GNU Emacs itself is a Lisp program, too - with its own
           | integrated Lisp and the development tools for it. GNU Emacs
           | has its own REPL, called IELM, the interaction mode for Emacs
           | Lisp.
           | 
           | Even in Lisp not all development interactions goes through a
           | REPL, but there are still a few very powerful ones, like
           | those of Allegro CL, LispWorks, McCLIM, Interlisp (recently
           | open sourced) or the Lisp Listener from Symbolics Genera.
           | Typical is the rich interactive error handling in multilevel
           | break loops with restarts and the ability to continue from
           | errors. The above also support image-based development and
           | integrate Lisp, IDE and the software under development in one
           | program.
        
           | vindarel wrote:
           | or, as I've been suggested, "image-based development" (even
           | though a CL implementation must not be image-based, but most
           | are).
        
         | threatofrain wrote:
         | But repl workflows are not special to Clojure and Scheme.
         | People in JS set breakpoints in their IDE, pause at a point in
         | their script to interactively explore program state all the
         | time.
         | 
         | Is this not the same?
        
           | _peeley wrote:
           | Not really. With Clojure you don't even have to leave your
           | editor (I use Emacs with the fantastic CIDER package). You
           | can put your cursor over an S-expression, hit two keys, and
           | evaluate and see the results of the S-expression directly
           | within the text buffer. The feedback loop is so quick it's
           | basically instant - even tabbing over to a browser or
           | terminal window feels lethargic in comparison.
           | 
           | I haven't used Common Lisp much, but I've seen a few really
           | impressive demos of debugging in its available REPLs. This is
           | a longer one, but a good tour of SLIME (also an Emacs
           | package): https://youtu.be/_B_4vhsmRRI
        
             | user3939382 wrote:
             | In PhpStorm I hit a hotkey to set a break point, then a
             | hotkey to make the API call to that code and immediately
             | get an xdebug breakdown of the entire state of the program
             | at that point. It's almost instantaneous and I don't have
             | to switch windows. I would say that's pretty close,
             | although the upfront learning and config to get that
             | working means it is higher overhead overall.
        
               | phyrex wrote:
               | It really isn't and I suggest you give clojure an honest
               | try to see why. It's really hard to explain.
        
               | slifin wrote:
               | For context I use phpstorm and Clojure
               | 
               | Here is a video I recorded which hopefully demonstrates
               | just how much faster you can go in Clojure
               | 
               | https://youtu.be/L0af0bc5Jec
               | 
               | Like I think a parent comment said it's hard to explain
               | but once you get it, it's fun malable and exploratory
               | 
               | Intellji also has a debugger that works with Clojure for
               | when it's appropriate
               | 
               | In php you can't redefine a function at runtime without
               | something like runkit, in Clojure you can fix your
               | systems at runtime
        
           | gotts wrote:
           | >Is this not the same?
           | 
           | not even close, no
        
           | joshlemer wrote:
           | I'm also curious, I think what it comes down to is that
           | Clojure lets you change the code of a running application,
           | rather than reload it.
        
             | jimbob45 wrote:
             | You can do that with C# in Visual Studio though.
        
               | Nihilartikel wrote:
               | The greater Clojure hot-reload super power comes from
               | embracing the idiomatic division of state and function
               | though. Hot reload in C# will have probably have to re-
               | instantiate classes or restart the app. In clj, if your
               | application state is kept in a global atom a'la (defonce
               | app-state (atom {})) Then redefining your functions won't
               | touch your data.
               | 
               | The only reason to do a full restart would be if you
               | changed the data structure expected by the functions in a
               | way that's not semantically backwards compatible.
               | 
               | Big-whoop on a stateless webserver, maybe, but on the
               | front end using ClojureScript for an SPA it is nothing
               | short of magical and has ruined any other browser dev
               | work flow for me.
        
           | mumblemumble wrote:
           | It is not quite the same. I'd argue that, while browser
           | environments are very good, they're trying to solve a
           | slightly different problem, and the overlap in capabilities
           | is less than complete. Lispers sometimes say that the browser
           | devtools experience is about halfway toward the power of a
           | good Lisp environment, but I would argue that the converse is
           | also true.
        
           | patrec wrote:
           | Mikel Evins has written two articles you might find
           | interesting:
           | 
           | https://mikelevins.github.io/posts/2020-12-18-repl-driven/
           | 
           | https://mikelevins.github.io/posts/2020-02-03-programming-
           | as...
        
           | hencq wrote:
           | Part of it is cultural I think. In Clojure you'll often find
           | yourself building your app incrementally, sending individual
           | functions to the repl from your editor. I don't think there's
           | any reason why you couldn't do that in Javascript.
           | 
           | Common Lisp takes this to another level though with stuff
           | like restarts. Where the app will throw an exception during
           | development (perhaps because a function isn't implemented
           | yet) and instead of crashing you'll end up in the repl where
           | you can make some fixes and keep running the app.
        
             | Nihilartikel wrote:
             | After my Clojure conversion and baptism, I've taken to
             | writing Python apps in a similar style using Jupyter
             | notebooks, and find it to be a tolerable middle ground.
             | Especially if the Python is functional style with good
             | referential transparency.
             | 
             | I.e. in each notebook cell, prototype and exercise your
             | function in isolation. Then copy them over the real py
             | module.
             | 
             | Still, I miss the elegant data literals in Clojure whenever
             | I'm slogging through some literal Dataclass objects for
             | testing..
        
               | dunham wrote:
               | I used to do this in Jupyter, but switched to vscode. If
               | you have comments that look like:                   # %%
               | 
               | It will treat the following chunk of code like like a
               | Jupyter cell and provide inline ui to run it. It's almost
               | the same thing as a notebook, but no markdown and your
               | file is just a plain python script.
        
               | Nihilartikel wrote:
               | Nice! I've seen a mention of that here and there, but
               | haven't given it a proper shot yet.
        
             | susam wrote:
             | There is a nice little story in the book _Practical Common
             | Lisp_ (Peter Seibel, 2005). Quoting it below:
             | 
             | An even more impressive instance of remote debugging
             | occurred on NASA's 1998 Deep Space 1 mission. A half year
             | after the space craft launched, a bit of Lisp code was
             | going to control the spacecraft for two days while
             | conducting a sequence of experiments. Unfortunately, a
             | subtle race condition in the code had escaped detection
             | during ground testing and was already in space. When the
             | bug manifested in the wild--100 million miles away from
             | Earth--the team was able to diagnose and fix the running
             | code, allowing the experiments to complete. One of the
             | programmers described it as follows:
             | 
             |  _Debugging a program running on a $100M piece of hardware
             | that is 100 million miles away is an interesting
             | experience. Having a read-eval-print loop running on the
             | spacecraft proved invaluable in finding and fixing the
             | problem._
        
               | e12e wrote:
               | > 100 million miles
               | 
               | That looks like about 9 light minutes away, so about 18
               | minute latency?
               | 
               | It might be super epic, but doesn't sound super _nice_ :)
        
               | CodeGlitch wrote:
               | I've heard this before and it does sound like the most
               | epic hack in the history of programming.
        
               | Qem wrote:
               | Recently there was a bit of a fuss when people discovered
               | the Mars Ingenuity helicopter runs python3. Now I wonder,
               | if its software ever crashes, will people be able to just
               | launch the python REPL and debug It?
        
         | throwaway894345 wrote:
         | > However, working with Clojure and Scheme, I understand the
         | power of repl driven development that is difficult to explain
         | outside the experience of it.
         | 
         | The only lisp I've dabbled with was Racket and I found the repl
         | driven development to be a frustrating necessity. I would spend
         | a lot of time trying to figure out the actual type of the thing
         | that I a given function (even a stdlib function) needed, and
         | futzing around in the repl seemed to be the fastest way to do
         | it, but it was still quite slow.
         | 
         | It reminded me a lot of my extensive experience with Python
         | where things that are easy in, say, Go, are quite hard. People
         | rave about their repl, but it feels like they're comparing it
         | to a script iteration loop rather than static analysis tooling.
         | 
         | That said, I completely buy the argument that Python's REPL is
         | particularly bad and that there are other use cases where REPL-
         | driven development shines. My mind is open, but these are the
         | sorts of experiences the pro-REPL folk should be prepared to
         | engage with in their evangelism. :)
        
           | pdonis wrote:
           | _> my extensive experience with Python where things that are
           | easy in, say, Go, are quite hard_
           | 
           | Can you give some examples? This is not something I've
           | encountered (although I have much more experience with Python
           | than with Go so there is probably plenty in Go that I have
           | not encountered).
           | 
           |  _> the argument that Python 's REPL is particularly bad_
           | 
           | What argument is this? This is also not something I've
           | encountered. I use Python's REPL all the time and it greatly
           | speeds up development for me.
        
             | vindarel wrote:
             | Yes, Python's REPL speeds up development, but Lisp's REPL
             | (we should say image-based development model) is even more
             | interactive! We never wait for a server to restart, our
             | test data is live on the REPL, we compile our code
             | function-by-function with a keystroke and we get instant
             | warnings and errors, when there is an error we get an
             | interactive debugger that pops up and allows us to inspect
             | the stack, go to the buggy line, recompile, come back to
             | the REPL, resume the execution from the point we want,
             | objects are updated when a class definition changes and we
             | can even control that... it's crazy. From time to time it
             | becomes a mess and I restart the Lisp image, but it's about
             | every two weeks :p I tried to explain more here:
             | https://lisp-journey.gitlab.io/pythonvslisp/
             | 
             | Note that I'm not a 10x master, I use CL for mundane, real-
             | world tasks (access to an FTP, parsing XML, DB access,
             | showing products on a website, sending email with
             | sendgrid...), my programs had 1 trivial bug, I am more
             | productive and I have more fun... Just to say it has its
             | uses, even today, even with "all the libs" of Python (and
             | btw, see py4cl).
        
               | pdonis wrote:
               | _> We never wait for a server to restart_
               | 
               | I'm not sure I understand. When I run Python's REPL, I'm
               | running the interpreter on my local machine; I'm not
               | talking to any server. The same would be true if I run
               | the Lisp interpreter, but I don't see how that is any
               | advantage for Lisp over Python.
        
               | vindarel wrote:
               | indeed, I was thinking web development for that example,
               | but I'm talking to my local development server, not a
               | remote one (although it's trivially possible with a swank
               | connection). I often have to wait for Django in a non-
               | trivial app. I often set a ipython breakpoint, try things
               | out, continue, and iterate.
               | 
               | Anyways, do you develop your app when you are in the
               | REPL? Or do you try things out in the REPL and write back
               | what you found out in the files? If you found how to send
               | changes from your editor to the REPL, then good, but it's
               | not built-in, and it will lack the other things I
               | mentioned.
        
               | pdonis wrote:
               | _> Lisp 's REPL (we should say image-based development
               | model)_
               | 
               | This looks like something specific to your particular
               | development workflow for one particular type of
               | application (a web server). REPLs (for both Lisp and
               | Python) are much, much, much more general than that.
        
           | p_l wrote:
           | Scheme is remarkably less interactive than Common Lisp,
           | though specifics depend on dialect of Scheme.
           | 
           | Common Lisp is remarkably more geared towards interactive
           | use, but while it does make it easy most of the time to be
           | used with just minimal REPL - as in literal (loop (print
           | (eval (read)))) - it's best to use integrated, enhanced
           | environments like SLIME/SLY/SLIMV/etc or one of the IDEs
           | (LispWorks, AllegroCL, Clozure CL IDE)
        
           | mateo411 wrote:
           | Why do you think the Python REPL is particular bad? What
           | would you do to improve it? I think it works pretty well, but
           | maybe I'm just used to it.
        
             | throwaway894345 wrote:
             | Last I checked you couldn't await inside a REPL and various
             | other idiosyncrasies. Lots of small paper cuts.
        
           | ReleaseCandidat wrote:
           | > People rave about their repl, but it feels like they're
           | comparing it to a script iteration loop rather than static
           | analysis tooling.
           | 
           | You do know that statically typed languages have REPLs too?
           | Like the ML family, including Haskell.
           | 
           | And when using something like a Jupyter notebook with a
           | kernel for your compiled language
           | https://github.com/gopherdata/gophernotes you can do similar
           | interactive programming.
           | 
           | REPLs are about trying out ideas or changes.
           | 
           | Lisp REPLs take that a step further, as you interact with and
           | in your whole actually running program.
        
             | CodeGlitch wrote:
             | > Lisp REPLs take that a step further, as you interact with
             | and in your whole actually running program
             | 
             | With python, I can add a signal callback which calls the
             | inbuilt breakpoint() function. This means I can send my
             | application a given signal, let's say SIGTERM, and it'll
             | drop into they python debugger whereby I can then drop
             | further into the python REPL.
             | 
             | Does Lisp provide more than that out of interest?
             | 
             | Edit: ah I see hot reloading is a thing. Not explored that
             | in python.
        
               | patrec wrote:
               | It's like CSI vs Dr House. Debugging in python is
               | forensic; you can figure out why your program died, but
               | you can't really fix it. In common lisp, debugging can be
               | curative as well as forensic. If you hit a problem like
               | you call foo from bar, but foo isn't defined you can just
               | write an implementation in your editor, send it to the
               | running lisp and continue with the current execution. If
               | a class is missing something, you can change the
               | definition and not onl y have it take effect for all live
               | instances, but you can also say how to transform the
               | existing instances in your program. Have a look at the
               | example given in the "docs":
               | http://clhs.lisp.se/Body/f_upda_1.htm; you should get the
               | gist even without knowing lisp.
               | 
               | I'm overgeneralizing (I've had remote repls in production
               | python application and used them to hotfix things), but
               | only a little. You will appreciate the difference if you
               | work with long running computations, where you don't want
               | to have to start over from scratch if something went
               | wrong right at the end.
        
               | brabel wrote:
               | Yes, it was mentioned in the post: you normally get
               | prompted not just when there's a breakpoint, but when
               | your code calls something that doesn't yet exist, for
               | example, or try to access a non-defined variable [1]...
               | you have the option to "fix" the issue and continue from
               | the same point, continue with a different value, or just
               | let it crash... and there's stuff like profiling and de-
               | compiling [2] which are all available directly from the
               | REPL as well.
               | 
               | [1] https://lispcookbook.github.io/cl-
               | cookbook/debugging.html
               | 
               | [2] https://lispcookbook.github.io/cl-
               | cookbook/performance.html
        
               | ekidd wrote:
               | Many early Common Lisp systems had impressive error
               | handling. Certain exceptions would automatically break to
               | an interactive Lisp window.
               | 
               | But Common Lisp also has a fancy system for recovering
               | from exceptions. So after you replaced the broken
               | function, you'd often see a list of "restart" points from
               | where you could retry a failed operation.
               | 
               | So even if you failed in the middle of a complex
               | operation, you could test out a fix without needing to
               | abandon the entire operation in progress.
               | 
               | I'm not entirely certain if this was as useful as it
               | sounds, in practice, but it was certainly very
               | impressive.
        
               | retzkek wrote:
               | There was a book published just last year about the CL
               | condition system for anyone who wants to better
               | understand it (disclaimer: it's sitting on my desk but I
               | haven't read it yet):
               | https://link.springer.com/book/10.1007/978-1-4842-6134-7
        
             | throwaway894345 wrote:
             | > You do know that statically typed languages have REPLs
             | too? Like the ML family, including Haskell.
             | 
             | I do, but that I don't see how that relates to the bit of
             | my post which you've quoted. I certainly didn't claim or
             | imply that REPL and static type systems were mutually
             | exclusive, only that REPLs are a poor substitute for many
             | static analysis tasks.
             | 
             | > And when using something like a Jupyter notebook with a
             | kernel for your compiled language
             | https://github.com/gopherdata/gophernotes you can do
             | similar interactive programming.
             | 
             | Yeah, I'm aware. I operate a large JupyterHub cluster
             | (among many other things) at work. :)
             | 
             | > Lisp REPLs take that a step further, as you interact with
             | and in your whole actually running program.
             | 
             | That sounds nice, but it's too abstract to persuade IMHO.
             | Personally, it seems like REPLs can make certain feedback
             | loops a bit faster, and to that extent they seem like a
             | modest quality of life improvement; however, considering
             | how lisp folks positively rave about them, I assume I'm
             | missing something.
        
               | ReleaseCandidat wrote:
               | > that REPLs are a poor substitute for many static
               | analysis tasks.
               | 
               | Maybe I should have asked you what you use the REPLs of
               | statically typed languages for.
               | 
               | I actually never used REPLs for that (neither in Python,
               | CL, Clojurescript nor Elixir).
               | 
               | > That sounds nice, but it's too abstract to persuade
               | IMHO.
               | 
               | Of course it is. I also didn't get it until I've tried it
               | myself. That actually has been the main cause why I tried
               | (Common) Lisp at all (well I had been using Emacs Lisp
               | before, but that doesn't really count ;).
        
               | FPGAhacker wrote:
               | I use repls a lot, both when I used clojure and now when
               | I mainly use python. The reason for me is language
               | exploration. I write my program and don't always know how
               | to do something and the internet is ambiguous.
               | 
               | With a nice repl I can rapidly iterate trying different
               | things and doing micro in-situ experiments to explore and
               | understand how the language (or library more frequently)
               | works.
               | 
               | It's very edifying.
        
               | dunefox wrote:
               | > I assume I'm missing something.
               | 
               | You are indeed, Rackets REPL is very barebones. Use
               | Common Lisp with either SLime or Sly and Emacs.
        
               | igouy wrote:
               | > You are indeed...
               | 
               | How puzzling that you do not spell-out exactly what you
               | believe they are missing.
        
               | dunefox wrote:
               | It should be obvious? He uses Racket, Racket has a very
               | simple REPL, as opposed to CL which allows him to use the
               | features he has heard mentioned about Lisp.
               | Interactivity, short feedback loop, etc. This has been
               | written thousands of times on here, I don't intend to
               | repeat it here.
        
           | didibus wrote:
           | > I would spend a lot of time trying to figure out the actual
           | type of the thing that I a given function
           | 
           | That's just because your were a noob. You hadn't learned and
           | internalized the standard library yet, and you hadn't learned
           | to understand flow and structure of types and functions and
           | variables.
           | 
           | I too when I started with Lisp had the same struggles, but
           | they go away with expertise.
           | 
           | That's why you'll hear people talk about "training wheels",
           | when you program in a statically typed language with an
           | extensive IDE doing a lot of static analysis for you, you
           | basically operate constantly with training wheels on. You
           | never really learn what class does what, what methods they
           | have, what types things are, you rely heavily on your IDE.
           | 
           | For example, ask an experienced Java developer to write some
           | Java in notepad? They don't know what to import, where to
           | find anything, completely lost, productivity hits zero.
           | 
           | And I'm not degrading Java devs or that setup. What happens
           | in Lisp is that you have to learn your language, you can't
           | rely on an IDE or the compiler. In theory you could also
           | learn Java to that level, stop using an IDE and you'll be
           | forced to really know the language as well.
           | 
           | Here's the kicker? Once you learn the language to that level,
           | your productivity in it skyrockets! But until you do, its a
           | slow crawl.
           | 
           | And it's only ounce you've got that experience that the
           | ability to change the program as it is running through a REPL
           | really brings about speed, you don't use it to figure basic
           | things like types and what standard functions exists, but to
           | tackle real business logic or explore libraries and 3rd party
           | APIs to get a grasp on those quickly.
           | 
           | Take this from someone who went from strongly typed Java,
           | C++, C#, ActionScript 3 to a Lisp. I'm now way more
           | productive in Lisp.
           | 
           | P.S.: Also, you'll have static analysis in Lisp as well,
           | depending on which one and your setup. In Clojure, I have
           | static analysis, an IDE, a connected REPL, and use all three
           | actively.
        
             | JetSetWilly wrote:
             | A typical standard lib may have thousands upon thousands of
             | functions with many less commonly used arguments and
             | options. If you are saying "memorise the lot" is the only
             | route to productivity on lisp then I'm out, because that's
             | unrealistic. And let's not get into libraries outside of
             | the standard lib, am I expected to memorise XML parsers,
             | graphics APIs, and so on as well?
             | 
             | If you are saying "memorise what you commonly use" then
             | that's fine, except that any typical program usually
             | involves a lot of "lesser used" stuff as well.
        
               | lispm wrote:
               | You don't have to. Lisp development environments remember
               | all what one loads into them: the definitions, their
               | source location, their arguments, their documentation,
               | who calls whom, the data types, ... One can ask Lisp
               | about all that then.
        
             | deergomoo wrote:
             | Come on now, this is a silly take with more than a little
             | elitism.
             | 
             | An IDE (for a sufficiently static language) eliminates so
             | much unnecessary mental load that is otherwise wasted on
             | avoiding inevitable human errors--typos, type mismatches,
             | forgotten cases.
             | 
             | I don't want what is essentially trivia swimming around in
             | my head any more than I want to find out about the
             | inevitable errors I've made when I come to compile or run
             | my program.
             | 
             | I want to know that no such issues exist well before then,
             | so I can focus on making sure my program actually behaves
             | correctly.
        
             | rmbyrro wrote:
             | This was unnecessary, mate
        
       | drmeister wrote:
       | I like the term "Eternal Language" - programming languages where
       | if you write code now - you will be able to compile and use that
       | code ten years from now (a software lifecycle eternity). Common
       | Lisp, C, C++, Fortran, (edit: Java) are close to eternal
       | languages. After losing a huge amount of Python 2 code (I wasn't
       | going to rewrite it) I implemented Clasp, a Common Lisp
       | implementation that interoperates with C++
       | (https://github.com/clasp-developers/clasp.git) so that I can
       | write code that will hopefully live longer.
       | 
       | I am one of the few software developers with code that I wrote 27
       | years ago that is still in active use by thousands of
       | computational chemistry researchers (Leap, a frontend for the
       | computational chemistry molecular dynamics package AMBER,
       | implemented in C).
        
         | xapata wrote:
         | How do you lose Python 2 code? The old interpreter still works.
        
           | p_l wrote:
           | But is no longer viable option for new work, and in this case
           | a lot of the code IIRC was libraries for writing programs.
        
         | happy-dude wrote:
         | Interestingly, Perl doesn't get a lot of love on HackerNews but
         | I would classify it in the family of "eternal languages."
        
         | nikki93 wrote:
         | One of the newer (newer than C, C++, Common Lisp, ...)
         | languages I feel comfortable about regarding this is Go.
         | Definitely feels like I can write a simple Go program to
         | generate a static website for example and it'll probably still
         | work in that same state for a while.
        
           | exdsq wrote:
           | It's hard to say with any 1.x versions what'll happen come
           | 2.x
        
         | tzs wrote:
         | I think that to earn the title "Eternal Language" that should
         | have to work in both directions.
         | 
         | If I am an expert in language X and take a solar powered laptop
         | and go spend 10 years living as a hermit in some isolated place
         | while working on some big X program, with no communication with
         | the outside world other than idle non-technical chat with the
         | people of the village I go to monthly to buy supplies, if X is
         | an Eternal Language then
         | 
         | 1. My code that I wrote as a hermit should build and run on the
         | outside world's systems,
         | 
         | 2. I should still be an expert in the language X, only needing
         | to learn library changes, fashion changes (such as coding style
         | changes), and tooling changes to be ready to take a job as an X
         | programmer at the same level as I had before I became a hermit.
        
         | georgeecollins wrote:
         | I hope that Rust joins the pantheon of eternal languages. I
         | feel like it has a lot of the advantages of a language like C,
         | but is just more modern and well thought through.
         | 
         | Also, you did not mention Java. I have very old Java code that
         | still works fine.
        
           | xapata wrote:
           | Java is younger than Python.
        
             | p_l wrote:
             | But Java 1.0 code is still (mostly) compile-able on recent
             | Java versions, not so much with Python where I'd worry
             | about going back 5 years.
        
           | oblio wrote:
           | Java is probably the biggest "eternal" language we have these
           | days. Probably tied with C and C++.
           | 
           | There's <<so much>> Java code churned out that it's
           | unbelievable. Business systems have a ton more code than
           | infrastructure systems.
        
             | [deleted]
        
           | uoaei wrote:
           | I'd give it another 2-5 years before the syntax settles. Some
           | serious improvements have recently been pushed out and I
           | wouldn't be surprised if further improvements are on the
           | horizon.
        
           | ahohokla wrote:
           | I'd like it to be so, but i dont have faith for it. rust
           | doesnt have a standard like lisp/c/c++ and it stands to those
           | languages for their eternality, and at least with lisp and C
           | their relative simplicity makes all the difference for
           | something like that. they feel like, despite how opposite
           | they are, discoveries rather than inventions when compared to
           | something so complex like rust and c++
        
         | Ginden wrote:
         | > programming languages where if you write code now - you will
         | be able to compile and use that code ten years from now (a
         | software lifecycle eternity)
         | 
         | Fun fact: code written in JavaScript in 1995 will work in 2021,
         | after 26 years.
         | 
         | If you are talking about "good practices" - few weeks ago I
         | worked with C code from 2001 and it was just awful. Yes, it
         | _compiles_ - but it wouldn 't pass any modern code review.
        
           | koonsolo wrote:
           | Maybe the C code was just badly written
        
             | dankoncs wrote:
             | Yep.
             | 
             | Use some of the -W* flags (-Wall -Wpedantic -Wconversion,
             | ...) and specify the standard -std=c90.
             | 
             | Avoid undefined behaviors:
             | https://en.cppreference.com/w/c/language/behavior
             | 
             | (Also use cppcheck, valgrind, gdb, astyle, make, ...)
             | 
             | Done.
             | 
             | Fun fact: JS and C are both standardized by ISO.
        
           | rmbyrro wrote:
           | Out of curiosity: would the 1995 JS code pass any modern code
           | review?
        
             | casion wrote:
             | JS from 2003 passed code review for me a few months ago...
             | so, yes... maybe.
        
               | dankoncs wrote:
               | Sorry, casion, but this seems to be all anecdotal. I can
               | give you examples of very old C programs that still work
               | and pass the compiler.
               | 
               | In fact, the code from "The C Programming Language" still
               | works fine.
        
         | Turing_Machine wrote:
         | JavaScript probably qualifies, too. It's not going anywhere for
         | a very long time, if ever. Same with COBOL. COBOL will have to
         | be killed with fire.
         | 
         | I'm assuming here that "eternal language" doesn't necessarily
         | mean "good language". :-)
        
         | duped wrote:
         | C/C++ languages are stable, but building actual software with
         | them is extremely cumbersome on future systems. It is unlikely
         | to "just work" because of how we have inverted the dependency
         | structure of the vast majority of C/C++ programs.
        
           | forrestthewoods wrote:
           | Ehhh. Integrating an old C++ library into a new project may
           | be difficult due to build systems or not useful due to
           | dependencies.
           | 
           | However if you want to take an old C++ game written in 2004
           | and ship it on modern platforms and consoles you only need to
           | update a very small amount of platform specific code.
           | 
           | Updating a 20 year old C++ project is probably easier than
           | updating a 3 year old web app.
        
             | deergomoo wrote:
             | Tbf if you're just looking to run an app on newer platforms
             | you'd likely not need to do _anything_ with the web app.
             | They have a lot of issues but once stuff works it's usually
             | a very long time before it doesn't.
             | 
             | It would probably still be harder to add a new dependency
             | to a 3 year old web app than it would be to integrate a
             | 20yo C++ project though, I agree with you there.
        
             | duped wrote:
             | imo that would be a "forever program" not really a "forever
             | language." The lack of standard packaging and terrible
             | paradigm of shared dependencies has made C/C++ incredibly
             | fragile and non-portable when you need something from years
             | ago to compile today.
        
         | chillpenguin wrote:
         | In the realm of spoken languages, they say for a language to
         | become immortal, it has to die. Latin is the classic example of
         | this. Languages that continue to evolve will continue to
         | "break" so to speak.
         | 
         | In this vein, Standard ML (SML) is truly immortal, because the
         | standard is set and it is "finished".
         | 
         | Just a fun thought!
        
           | pjmlp wrote:
           | Well, the Vatican keeps updating it. :)
           | 
           | https://www.vatican.va/roman_curia/institutions_connected/la.
           | ..
        
             | p_l wrote:
             | Until "modern classics" education became a thing, Latin was
             | arguably a still living language, if in limited use (mainly
             | among the clergy, certain professions and educated circles,
             | and effectively official language of certain countries).
             | 
             | Then ~17th century modern classics turned latin education
             | into navel gazing on the topic of bunch of roman
             | republic/empire era works, and disregarded actually using
             | it.
        
       | idoh wrote:
       | Quick question while we are all talking about lisps - any
       | recommendations for a scheme-based web development repl? I've
       | tried Racket and their framework, and while the documentation is
       | great the one thing I really miss is that you have to do restarts
       | every time you make an update.
        
       | pphysch wrote:
       | "Why $lang?"
       | 
       |  _Provides zero snippets of $lang, just feel-good marketing
       | blurbs_
       | 
       | In fact, you have to scroll to the bottom of the third "read
       | more" link to see any $lang in action.
       | 
       | Hmm. Okay.
        
         | baby wrote:
         | If you'd see snippets you probably would run away at the sight
         | of all these parenthesis
        
         | avmich wrote:
         | We're talking about programming a lot on HN, and Lisp is one of
         | more familiar things in programming, so sometimes assumptions
         | are too high, I guess.
        
           | pphysch wrote:
           | > Lisp is one of more familiar things in programming
           | 
           | Simply not true in practice.
           | 
           | https://insights.stackoverflow.com/survey/2021#section-
           | most-...
           | 
           | edit: fixed link, header was pointing at wrong section
        
             | Mikeb85 wrote:
             | Clojure is top of that list and Common Lisp is just below
             | Go. Not sure what your point is...
             | 
             | Even if people don't touch Lisp they know it's that strange
             | language with all the parentheses...
        
               | oblio wrote:
               | Are you sure you're looking at the main list, for all
               | respondents?
               | 
               | After counting a bit, Clojure seems to be in 31st place
               | and Common Lisp isn't even on the list.
               | 
               | Clojure is lower than even languages which are not
               | considered popular, for example Powershell or Dart.
               | 
               | https://insights.stackoverflow.com/survey/2021#section-
               | most-...
               | 
               | Maybe your browser didn't jump to the correct section of
               | the survey?
        
               | Mikeb85 wrote:
               | He changed the link since I made my comment. See his
               | edit. Originally he was pointing to developer pay by
               | language, which Clojure tops and Lisp is fairly high on.
        
               | pphysch wrote:
               | Yeah if you click the header hypertext (not link icon) in
               | my corrected link, it misdirects to another section.
               | Sorry about that.
        
               | asdfuiopasdf wrote:
               | Clojure is no where near top, nor near go?
               | Go  9.55%       ... about a dozen entries ...
               | Clojure 1.88%       Elixir  1.74%       LISP  1.33%
        
             | vindarel wrote:
             | Here Lisp is #30 higher than Haskell, Julia, Clojure, D,
             | Ada, Scala, Erlang, Elixir, F#, OCaml...
             | https://www.tiobe.com/tiobe-index/ (yes that index measures
             | nothing meaningful but maybe at least a "familiar thing")
             | (edit) and just below Rust which is #29 ahah)
        
             | medo-bear wrote:
             | i think the parent is well aware of the unpopularity of
             | lisp. yet that does nothing to disprove that lisp is one of
             | the most 'familiar things in programming'. almost all
             | programmers who have attended some academic course on
             | programming languages know about lisp
        
               | oblio wrote:
               | Not really, unless you go to a very small subset of top
               | notch universities, in some geographies.
        
               | pphysch wrote:
               | Perhaps true for past generations.
               | 
               | Even MIT recently rewrote SICP in Javascript for its
               | undergrads, IIRC.
        
               | randomifcpfan wrote:
               | MIT also switched from Scheme to Python for undergraduate
               | CS programming courses. They did it for the libraries and
               | ease of use.
        
               | p_l wrote:
               | And because the goal of 6.01 was different from 6.001,
               | which was the biggest thing in the change. A graduate of
               | 6.001 was supposed to be on path to understand
               | computation et al - a graduate of 6.01 is given enough
               | skills to apply a bit of programming necessary for his
               | next courses but isn't expected to actually _grok_
               | programming, just string enough libraries together.
        
         | reikonomusha wrote:
         | This sort of criticism is bar-none the most typical negative
         | criticism any time someone describes a benefit of a language,
         | especially an unfamiliar one like Lisp.
         | 
         | You give code, "this is way too detailed, what's the essence?"
         | or "how is a for-loop macro special at all? we have for-loops
         | already"
         | 
         | You give small simple snippets, "not real world!"
         | 
         | You don't give code, "not enough detail, just feel-good
         | marketing!"
         | 
         | You give pseudocode, "well I want to see the real thing!"
         | 
         | The concepts presented in the article are _hardly about code_
         | anyway! They're about a development workflow and a language
         | environment supporting it. How should the author demonstrate
         | interactive development through a paragraph of text, besides
         | just describing it? You really need a live demo to see how
         | everything moves around, not a code snippet.
         | 
         | My suggestion to you as a critic is to actually _ask_ , in good
         | faith, for something _substantive_ you want to see. For
         | instance, "I wish $AUTHOR showed us what they mean about
         | removing a class slot." Then the author, or others, would be
         | happy to respond to you.
        
           | pphysch wrote:
           | No need for the barrage of logical fallacies (slippery slope,
           | strawman). I think this $lang ad would be useful if it showed
           | what it was advertising.
        
       | ctdonath wrote:
       | Any hope of the Lisp community pulling a Swift and replacing the
       | language with a drop-in-compatible new one built ground-up with
       | lessons and sensibilities learned over decades?
        
         | mtreis86 wrote:
         | https://github.com/robert-strandh/SICL
        
       | jstx1 wrote:
       | Is that it? Future-proof and REPL?
       | 
       | R code from the 90s still runs today on the latest versions and
       | everyone uses a REPL to write their code. I don't see a lot of
       | people jumping into R any time soon, quite the opposite in fact.
        
         | pharmakom wrote:
         | R is not trivially parsable and manipulated, since the code is
         | not just a list. I think that's the real magic of lisp.
        
           | duped wrote:
           | I think homiconicity is the magic of LISP. Ease-of-parsing is
           | not a quality worth optimizing for in a language
        
           | [deleted]
        
           | programLyrique wrote:
           | Accessing the code part and modifying during execution is
           | actually rather easy in R. Functions such as substitute or
           | quote are commonly used and a language expression in R is a
           | list that you can edit and evaluate back.
           | 
           | The internals itself in R actually sound quite lispy: both
           | values and codes are SEXP (S-expressions).
           | 
           | R is inspired by Scheme and Common Lisp; it has first-class
           | functions, multiple dispatch.
           | 
           | https://www.stat.auckland.ac.nz/~ihaka/downloads/Interface98.
           | ..
           | 
           | "This decision, more than anything else, has driven the
           | direction that R development has taken. As noted above, there
           | are quite strong similarities between Scheme and S, and the
           | adoption of the S syntax for our interpreter produced
           | something which "felt" remarkably close to S."
        
           | jstx1 wrote:
           | Maybe that could have been mentioned in a "why lisp" article.
        
           | asdfuiopasdf wrote:
           | Doesn't seem like it will prevent you from doing Language
           | Oriented Programming, or advanced embedded Domain Specific
           | Languages. Perhaps it's less ergonomic, I am not an R user.
           | 
           | http://adv-r.had.co.nz/dsl.html
        
       | tytrdev wrote:
       | https://news.ycombinator.com/item?id=29166818
        
       | kazinator wrote:
       | Lisp is very good even if you write all your code into text files
       | and invoke a build command before running it, which you do in a
       | completely fresh image.
       | 
       | If my only way of debugging were to upload the compiled image
       | onto an embedded target and observe the effects of print
       | statements a serial log, I would still overwhelmingly want to be
       | using Lisp.
        
       | qnsi wrote:
       | They seem to offer open source (I think) product Nyxt browser[0].
       | They offer some interesting features. One is Lossless tree
       | history, I can see it being very useful!
       | 
       | https://nyxt.atlas.engineer/
       | 
       | Edit: Right now it is sponsored by EU grant! Maybe finally EU can
       | do something useful
        
         | xcambar wrote:
         | I assume you think GDPR is useless?
        
       | tomcam wrote:
       | Modern systems are so reliant on extensive third party library
       | support for things like database, web, network, and graphics
       | library support I'm not sure the futureproofing argument matters.
        
         | reikonomusha wrote:
         | I definitely think it matters. You're right, the environment
         | changes. It's certainly an exercise in software engineering to
         | modularize your application to have portable and non-portable
         | parts. I like Lisp had treated this subject well; there are
         | _tons_ of libraries in Lisp that have been untouched for over a
         | decade but still work fine.
        
       | Kessler83 wrote:
       | To see the REPL and debugger advantages of Common Lisp over other
       | Lisps, Python, Haskell etc., you really should try for yourself
       | in SLIME or SLY (a SLIME fork) imo.
       | 
       | But anyway, let's say I made an error somewhere and the program
       | halts, putting me in the debugger. I can then examine each frame
       | preceding the error. I can see every value going into my
       | functions and jump around in the code generating those values. I
       | change the code, while the debugger is still running, recompile
       | it into the halted program and then pick a frame point right
       | before the error occurred, to test if my changed code solves the
       | problem. If it doesn't, I'll examine some more, perhaps start a
       | second instance of the REPL to experiment a bit, then try another
       | change in my code. All the while, _I_ _don 't_ _lose_ _state_.
       | Once the problem is solved, my program will continue where it was
       | as if the problem never happened.
       | 
       | For something like game programming, where you may be deep in the
       | game and have encountered some rare combination of circumstances,
       | this is simply invaluable.
        
         | westoncb wrote:
         | I hear this talked about quite a bit, but it still doesn't
         | quite make sense to me why it's such a big deal: I know this
         | situation where debugging-fix attempt loop is far more
         | efficient if you don't lose state, but it's nowhere near a
         | pervasive situation: when it comes up, I can generally write
         | something quickly to re-create the necessary parts of the state
         | automatically.
         | 
         | If I was doing that every day, or even every week, I could see
         | it being a huge advantage to incorporate a solution in the
         | language--but at least for me it just doesn't appear to be an
         | obstacle that often (incidentally my background was initially
         | in game programming, too).
        
           | edgyquant wrote:
           | I wonder what it is that prevents e.g. python from having a
           | similar "persistent state in development" tool/repl? I've
           | never really used lisp other than a MAL I did a few years ago
           | for kicks so I'm not well versed in its dev tooling.
        
         | dgan wrote:
         | Ha! Very interesting, Thanks for feedback. The number of times
         | I restarted a game after 1 line change + recompilation..
        
         | the-alchemist wrote:
         | You can actually do something similar (much more limited, it
         | sounds like) on Java, of all things.
         | 
         | https://devblogs.microsoft.com/java/hot-code-replacement-for...
         | 
         | As long as it doesn't change the class signature, you can
         | happily edit-save-replace code, and it jumps to the top of the
         | method you're editing. It's basically instant, so you don't
         | suffer the javac and JVM startup cost.
         | 
         | I don't think I can do the same in more dynamic languages, like
         | Ruby or Python. Or, maybe, my IDEs don't support it (IntelliJ
         | suite).
        
         | jonathankoren wrote:
         | REPLs are great, and I always prefer a language with one than
         | one that doesn't, but being able to patch a running system is
         | Lisp's killer feature in my opinion. I've never seen another
         | language that support that.
         | 
         | I had a bug in a long running program that would only show up
         | after like six hours. I couldn't replicate it in isolation
         | because it had something to do with how state was being
         | maintained. I set a conditional breakpoint right before the
         | crash, inspected the stack, patch the function, and then had it
         | pick back up by reevaluating the current function call.
         | 
         | Damn thing just worked. It was amazing, and saved me so much
         | time.
        
           | db65edfc7996 wrote:
           | Python programmer not accustomed to a "real" REPL. My closest
           | experience would be Jupyter notebooks, where dangling state
           | is more a liability than an asset.
           | 
           | > ...inspected the stack, patch the function, and then had it
           | pick back up...
           | 
           | After you edit the live state of the program, how do you
           | translate that into code sitting in source control? Do you
           | save this blob of memory and pass that down through
           | generations?
        
             | jonathankoren wrote:
             | 1. Stop the system.
             | 
             | 2. Modify the source code containing the function.
             | 
             | 2a. Save the file.
             | 
             | 3. Copy function definition to the debugger's repl, and
             | evaluate it.
             | 
             | 4. Resume the system from frame that calls the function.
             | 
             | But yes, you must be diligent about making sure the source
             | files contain the code that is actually running, but that's
             | not much different than artifact tracking.
        
             | lispm wrote:
             | Usually one wants to make the change persistent in the
             | sources.
             | 
             | Step a): One just evaluates from the sources, while
             | changing them. Once done -> save sources.
             | 
             | Step b): Create a patch file, which changes the image. Such
             | a patch file can be loaded while starting an image, until
             | one decides to save a new image with the changes already
             | loaded.
             | 
             | For example there is a new release for the commercial
             | LispWorks IDE once every one or two years. Users usually
             | get only patch files for bug fixes during the one or two
             | years maintenance. Thus I have a directory for patches to
             | LispWorks, which are loaded when I start the base image.
        
           | bobnamob wrote:
           | This is one of the fundamental features of the BEAM (the
           | Erlang/Elixir virtual machine) as well.
        
           | jdougan wrote:
           | Almost all Smalltalks, especially the image based ones
           | support dynamic run-time patches.
        
           | exdsq wrote:
           | I believe .NET 6 allows hot reloading, and Erlang already has
           | that feature too
        
       ___________________________________________________________________
       (page generated 2021-11-12 23:00 UTC)