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