[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)