[HN Gopher] Lisping at JPL Revisited ___________________________________________________________________ Lisping at JPL Revisited Author : lisper Score : 157 points Date : 2023-01-28 13:18 UTC (9 hours ago) (HTM) web link (blog.rongarret.info) (TXT) w3m dump (blog.rongarret.info) | oso2k wrote: | Been almost 15 years since I was at the Lab but I don't recall | Lisp being at all popular. And I started there as a Perl & PHP | developer before transitioning into Java. | hvs wrote: | The original article was written about 20 years ago and he says | that by 1999 lisp was already falling out of favor (if it had | ever been _in_ favor). So, 15 years ago (2008?) would 've been | almost a decade after that. | bifftastic wrote: | I wasn't aware of this: Clozure Associates is no | longer a going concern, and the volunteer effort to port CCL to | the M1 appears to have stalled. | | Sad news if true (and I have no reason to doubt it). I had kind | of assumed that an M1 version of CCL would appear as a matter of | course. | lisper wrote: | > I have no reason to doubt it | | Point your browser at clozure.com if you want confirmation. | (There's a reason I didn't include that link in the post.) | phoe-krk wrote: | AFAIK the task is looking for volunteers (who have the | necessary low-level knowledge) and/or funding. The mailing list | at openmcl-devel@clozure.com has some threads related to it - | see https://lists.clozure.com/pipermail/openmcl-devel/ | [deleted] | fithisux wrote: | For me this is the year of Lisp. Julia and R for warm up, and | then Common-Lisp. | | R7-Large Schemes do not seem to me ready (apart from Racket which | is not R7-Large). Look the beautiful Handbook of Julia. R is full | of documentation. | | Common Lisp is steadily improving. | | Schemes need something similar. | 082349872349872 wrote: | _Bb_ looks suspiciously like an identity monad comprehension :) | bsima wrote: | I was thinking similarly, reminds me of `do` notation in | Haskell. Which is great, Haskell and Lisp are my two favorite | languages :) | revskill wrote: | Is a do notation same as chain of responsibility GoF pattern? | agumonkey wrote: | i wonder what's the difference between CoF and a sequence | of conditionals (except maybe being reified at the | application layer and potentially adjusted without changing | source, a bit like a macro) | Twisol wrote: | Not exactly (although maybe you could implement that | pattern with the right choice of monad). | do x <- [1, 2, 3] y <- [4, 5, 6] | return (x + y) -- [5, 6, 7, 6, 7, 8, 7, 8, 9] | | Here we have a series of assignments followed by an | expression computing a result. You can't tell directly, but | this is using do-notation in the List monad -- an | assignment `x <- [...]` picks a value from the list, then | continues. In fact, this code is run once for every | possible choice from the given lists, and all of the | results are aggregated into a list. | | The earlier commenter referred to the Identity monad, which | would look like: do x <- 3 | y <- 5 return (x + y) -- 8 | | No special lists this time -- what you put on the right is | what gets stored in the variable on the left. This is what | you're used to in any imperative language. | | I suspect `bb` is a little more special, because Ron | mentioned it has similarities to LOOP. I'd guess it | supports recursive definitions somehow, but it's not clear | what the difference actually is. | revskill wrote: | Curious to know how to implement Do pattern in an OOP | language consistently. | dragonwriter wrote: | Do isn't a pattern, its a notation for monad operations. | Any pattern implementable in it can be reproduced in any | language where there are objects which support monad | operations by using those operations directly. Some | languages (e.g., Scala and its comprehensions, which use | monad operations rather than imperative operations over | collections the way Python does) also have a do-notation- | like syntax sugar, as well. | Twisol wrote: | Good question. "Do notation" is sometimes referred to as | "the programmable semicolon", because how you go from one | statement to the next depends on which monad you're in. | (In the List example, the assignment `x <- [1, 2, 3]` | forked execution three ways before proceeding to the next | assignment.) | | In Java, the semicolon is pretty much fixed; you can't | change the relationship between statements in any | meaningful way. So you have to play tricks. You can | implement the List example in a crafty but leaky way: | do(() -> { var x = choose(1, 2, 3); | var y = choose(4, 5, 6); return x + y; | }); | | When `choose` is called for the first time, it remembers | which choice it returns to you. When you `return` from | the block, your result is stored, and then the function | is re-executed -- except this time, `choose` will now | return a different value (the next one). You can | implement this in a rather small handful of lines, but | it's very tight and clever code, and not at all obvious | how it works at first glance. | | There's another way to do this, with chained `flatMap` | calls, like: list(1, 2, 3).flatMap(x -> | list(4, 5, 6).flatMap(y -> list(x + y))); | | ...but that's so different from "normal" use of a | language like Java that readers and writers alike are | likely to balk to some extent. | rightbyte wrote: | 'do' in Haskell is like PROGN right? | | I guess in a OOP langague like C++ it would be something | like: | | foo1(); foo2(); return foo3(); | | ? | agumonkey wrote: | progn has a fixed meaning in how to sequence sub | expressions | | do, afaik, just flips the written expression and use | actual bind functions depending on the typeclass at point | thom wrote: | Monads and 'do' and stuff are just a form of abstract | control structure. They're hiding information about the | actual nature of a computation, making it look like a bit | of imperative code, but in the background they could be | doing anything. To be honest, despite the mystique, this | isn't so different to virtual calls in an OO language, or | just having objects hide their internals. Can you create | an algorithm accepting the same steps but performing some | magic in the background, around and in between every | step? You have decorators, iterators, visitors, all that | sort of stuff, so the answer is probably yes. Monads | happen to be a very simple way to do this, and so you end | up with entire ecosystems and fundamental ways of | thinking built on that pattern. | WalterBright wrote: | > It is super-simple to customize Lisp to suit your personal | tastes, and so everyone does, and so you end up with a fragmented | ecosystem of little sub-languages, not all of which (to put it | mildly) are particularly well designed. | | This happens with any language that has macros, and why I have | strongly resisted adding macros to the D language. | gamache wrote: | I can offer a counterexample: the Elixir community, despite | having a (very good) macro facility at our fingertips, is | largely free of macro-mania as you describe it. | | Culturally, most folks use macros to import a few things into | the caller namespace, or to wrap functions somehow (e.g., add | timing metrics to every function in a module), and virtually | all the functionality should reside in regular functions in | regular modules, rather than having the macro inject a bunch of | code that doesn't exist in a testable form. | | I'm not sure why we have it so good. Dreams can come true I | guess. But I bet a community of low-level systems programmers | might not be so well behaved :D | mwcampbell wrote: | > Different people like different things, and that's OK. Drink | whatever is the best fit for your palate, and code in whatever is | the best fit for your brain. | | Doesn't this ignore the need to work together and build on each | other's work? To me, that's not about companies being able to | treat programmers as interchangeable, but about us collectively | building higher, i.e. building towers of Babel rather than | suffering from the curse of that story. | 082349872349872 wrote: | Take four: what, specifically, about ergolib should prevent | anyone from building on top of something written with it? | | [Edit: A programmer should be able to Reverse Polish Notate, | nested-paren a tree, reduce some arrays, make references in | nested scopes, evaluate without mutation, send a message, spin | up a fail-fast supervision tree, produce finite answers from | infinite graphs, synchronously react, rendezvous with logic | variables, combine the above. "Specialization is for insects."] | jvanderbot wrote: | Maintainability. If you're the only person who can edit the | library, you've just created a bus factor that would be | unacceptable to most project managers. | [deleted] | Twisol wrote: | As a complement to my other reply to you, I'll note that I | developed a simulation system in Java (a very common | language), and strove to keep it small, avoid complexity, | and generally make it approachable -- but for a long time I | remained the only one who understood how the system worked, | because you simply had to understand the business domain in | order to understand why things worked the way they did. | | This is my personal opinion, but I think that domain | expertise is a much stronger component of bus factor than | language choice is. You can write unmaintainable code in | any language. But good code often still has prerequisites | to understanding. Meanwhile, if you have the domain | expertise, you can get quite far in understanding semi-bad | code just by pattern matching on manifestations of your | domain. | [deleted] | ravi-delia wrote: | I mean, that specific library isn't really all that hard to | work with. It's not doing anything completely crazy, just | somewhat unusual. But in general I think it's probably | better to keep the crazy custom environment to personal | projects- at least for awful utility macro libraries like | mine. | jvanderbot wrote: | Narrowing down on a single library is one thing. Maybe | case by case it's ok. In general if someone showed up and | said "I will prototype everything in lisp and you can | take it from there" I'd say they are a bit egotistical | and not being much of a help to the org. Prototypes are | 1% of the work. | | And I say this as someone whose full time job _was_ to do | research prototypes of robotics libraries for a while. | mwcampbell wrote: | The fact that you adapted the famous Heinlein quote for | programming just goes to show me a problem with that quote. | Recall that the original quote mentioned programming itself | as one of the many things that a human should know how to do. | But your adaptation illustrates that programming alone is | deep enough to merit its own specializations. So just as, | IMO, specialization is not just for insects but also for | humans living in a functioning, populous civilization, | specialization is also fine and expected for programmers, | particularly since our numbers have grown over the decades. | And to bring this back to my original point, yes, this means | that we shouldn't all be writing lowest-common-denominator | code in mainstream languages. But I still think it's a good | idea to avoid needless fragmentation. | 082349872349872 wrote: | Fair enough; I think I'm describing the horizontal bar of | the "T" and you're pointing out the vertical, and we differ | on the amount of fragmentation ergolib represents. (Despite | not using CL on the daily, upon perusing ergolib's source I | found it a relatively straightforward mod-con library, so I | don't think it _necessarily_ fragments) | | (But I was pretty serious about that list: I would hope a | programmer just out of school would have heard of all of | them, and expect anyone experienced to have done most of | them, if not necessarily in the languages that make each | one easy. Similarly, from Heinlein's original list, I | currently lack only practical experience in planning | invasions [though I have theoretic hex-board experience], | butchering hogs [though I have a friend who has offered to | teach me], and dying gallantly [though I have "I am just | going outside and may be some time" as an example to follow | should the occasion arise]) | sph wrote: | I'm waiting for WebAssembly components to be standardised then | I don't care anymore. The idea is to create "libraries" written | in any language that can be used by any other language, with | WASM being the low level ABI. | | When that happens, I can go all in with Lisp because I care | about _my_ personal productivity (I have always been a lone | wolf programmer) yet still being able to use code written by | anyone in their comfy language. | | As I get older, I find I just want to mold and bend the | computer to my every will, and Lisp is the tool to do so. That | the resulting code is hard to understand for a junior engineer | is not my concern. | | But one thing is for sure: I want to be able to create any | abstraction, and I am done writing glue code, writing yet | another PostgreSQL library for yet another language. How many | date/time libraries have been written since the invention of | UNIX? Imagine the amount of wasted time, money and effort. Then | multiply by the number of languages that have been invented | because the syntax of the previous one is too inflexible. | | I stand by the Lindy effect: the longer something has been | around, the longer it will survive. | | Looking forward to Wasm Components to use a language from 1960 | to its full potential. Then the goal is to have a WASM-native | Lisp that can dynamically load any other WASM library, and I | don't have to write yet another date/time library ever again | nor care about junior engineers getting confused by crazy | macros in my code. | | (I have been suffering from the Lisp curse for 6 months and | counting. Please send help.) | johnbernier wrote: | The JVM lets you program in whatever you want to and then use | code written in whatever comfy language (Java, C/C++ via | native interop, Kotlin, etc) or a Lisp dialect (Clojure). I | frequently use Java and Clojure together in the same project | to great satisfaction, but I know what you mean anyways. We | need WASM to get around the web question. I just hope it can | fulfill the promise you have set upon it. | rosebay wrote: | [dead] | SkyMarshal wrote: | I sympathize, but if you're working for a company then | somebody is either going to need to be able to read and | understand your Lisp code, or the WASM it generates, in order | to maintain it after you move on to some other company. | turtleyacht wrote: | sph probably has a clause in there to own the code. A | traveling salesman among a graph of corporate nodes. Their | own tools, always honed; their own solutions, always at | hand. | WalterBright wrote: | > How many date/time libraries have been written since the | invention of UNIX? | | Indeed. This service (especially the time zones) should be | part of the standard operating system API. | sph wrote: | What I mean is that I should be able to use TensorFlow, or | a Ruby library or Qt6 from any other platform and language, | without someone having to write bindings to it or porting | it wholesale. We've been wasting _thousands_ of man years | just rewriting the same code everywhere, with the quality | of implementation being dependent on how popular the | language is. So you get the best libraries on Java, and | smaller ecosystems never reach critical mass because there | 's no good libraries. This is unsustainable. | | I really am hyped for WASM components. | jcelerier wrote: | exactly, in the author's vision the individual matters more | than the group ; I couldn't disagree more with this. | Twisol wrote: | Take one: We need people moving together just as much as we | need scouts who can push ahead and find the best paths for the | rest of us. | | Take two: Working in the best fit for your brain is not | incompatible with working with others -- enough companies are | Java shops, why can't there be CL shops? (There are assuredly | _Clojure_ shops at the very least.) | | Take three: Not everything has to be about work. Programming is | a skill, not an occupation; there are lots of ways to apply | programming as a skill that don't require you to build large | edifices in teams. | jvanderbot wrote: | And how nice when those scouts lay groundwork that is useful | for others, rather than creating something only they can use? | | Yes, you may think better in lisp than c++, but that doesn't | help your team when you created something and moved right | along. Better to speak the same language. | fithisux wrote: | So we are doing now what the others do? It defies any | reason. | AnimalMuppet wrote: | _If you are part of a team_ , then yes, do what others | do. And no, it doesn't defy reason. Code is written once, | but it's maintained for a long time. | | Or it's thrown away. But if it's thrown away because | nobody else on the team knows that language, that's | pretty wasteful. And if you make someone on the team | learn a new language just to maintain that one program | that's _also_ wasteful. The person who insisted on using | _their_ language is optimizing for their own programming, | but actually slowing down the team as a whole. We have | words for that kind of behavior; they aren 't | compliments. | | Now, in any given instance, it could be that the program | is much easier to write in one language, and more | difficult (or even impossible) to write in others. But | even in that case, if you're in an organization, you need | to get buy-in from the team or management or both, rather | than just doing your own thing because you can make it | work. Otherwise, your program may work, but it's an | orphan. You need the organization to be willing to | maintain your special program, or it dies. | Twisol wrote: | I was referring to the discipline as a whole, not scouting | at the granularity of a single team. Also refer to take | three: working in an industrial team is not a prerequisite | for an application of programming to be valid. | | But to your very specific point: I have in the past | developed prototypes in Rust whilst on a Java-only team. | It's actually a good thing: these prototypes were meant to | be thrown away, so working in a different language (and one | that helped me model things effectively) meant we were | forced to throw it away then write it right in Java once we | knew what we were doing. | | (We did the same thing for another feature, but it was | someone else and they preferred Python. Again, we were able | to prototype more rapidly and then implement a solid | solution in Java once we knew how things should shake out.) | tlavoie wrote: | Another thing that is good to encourage is portable data. | It's good for its own reasons, and it makes that sort of | exploratory environment much more flexible. | | I've reimplemented a few side projects more than once, | using common data back-ends because I can. I find it | helps for say, messing with a new programming language, | because I can apply it to a task I'm already familiar | with. | spfzero wrote: | Sometimes hard to predict whether something that works well | for you would, or would not, work well for others, and | whether others could, or could not use it. | yakubin wrote: | Better for the others, but is it better for the scouts? Too | often individuals are treated as drones obliged to work for | a collective, which feels entitled to the work of the | drones. From your perspective, they're not a good team | mate. From their perspective, they're not part of your | team. | jvanderbot wrote: | I think this example is being carried to extremes | unproductively. | | All being equal, it's better to have a team writing code | that is useful to the system or project or whatever ASAP. | | If an individual insists on prototyping in a language | that nobody else can use, then they should either carry | that prototype into the team's ecosystem, or start | prototyping in that ecosystem and learn to be productive | that way. | | If option A, let's hope that "write twice" is fast enough | that they are productive. If option B, they may take a | productivity hit but will probably catch up. | | The third option of "I'll do lisp you do <teams | ecosystem>" is not very pro-social. Come integration and | debugging and maintenance time, that Lisp-er is not in a | position to help. That's an undue burden in the rest of | the team. | yakubin wrote: | I think you're excessively hung up on the example of | everything happening within a single team inside a single | company or some such thing, when the author of the | submission wrote about making a choice for themselves. | You don't start coding in Lisp out of nowhere when | working in a Java shop on a CRUD app. But if you're | charting your own course, it's great to be able to choose | whatever suits you best. | | I can't count the number of times someone published their | open source project and inevitably people in the comments | started questioning their language choices, because they | wouldn't be able to use it in their "team", and how that | choice is ultimately harmful for "the community". Now, | you're not doing that exact thing here. I'm just thinking | about how all that focus on "the team" and "the | community" often goes too far. | | Personally, I'm not going to do anything in Common Lisp, | but I'm always happy seeing other people doing their | projects in that language (and many others). | jvanderbot wrote: | > I think you're excessively hung up on the example of | everything happening within a single team inside a single | company or some such thing, when the author of the | submission wrote about making a choice for themselves. | | That's fair. | | > I can't count the number of times someone published | their open source project and inevitably people in the | comments started questioning their language choices, | because they wouldn't be able to use it in their "team", | and how that choice is ultimately harmful for "the | community". | | Yep - not paying means not entitled to anything. I agree | there. | brudgers wrote: | When collaborating by the mechanisms you describe is not a | priority, it is reasonably sound engineering practice to ignore | those mechanisms. | | Though there are tradeoffs (and assuming 10x programmers exist) | a ten-ex programmer can replace a team of ten one-ex | programmers and eliminate mechanisms facilitating intra-team | efficiency from the process. | | Anyway, to me the Tower of Babel is a metaphor of collective | action...building construction requires teamwork. Icarus is | better for lone wolves. | sampo wrote: | > even inspiring some people to plagiarize it | | That's not what plagiarizing means. Plagiarizing means to pass | off as one's own. The website only copied the essay, without | trying to pass it off as their own. They also linked to the | original. | | What they did is maybe a pirate copy? | WalterBright wrote: | > In every other language I have to think about whether to write | op(arg1, arg2 ... argn) or arg1.op(arg2, ... argn) or "arg1 op | arg2" | | In D these are interchangeable: op(arg1, arg2 ... argn) or | arg1.op(arg2, ... argn) which is called Universal Function Call | Syntax. It works very nicely. It enables a Left to Right reading | of stacked function calls: | | a(b(c(d(1)))) becomes 1.d.c.b.a() which is a lot more readable. | sokoloff wrote: | If d takes two args, is there an inverted syntax as in "(1, | 2).d.c.b.a" or must you do d(1, 2).c.b.a or something else? | lisper wrote: | Author here. AMA. | eliben wrote: | Thanks for writing this followup, Ron. | | This paragraph really resonated with me: | | > All this is a reflection of the so-called Lisp curse, the | fundamental problem with Lisp -- its great strength is | simultaneously its great weakness. It is super-simple to | customize Lisp to suit your personal tastes, and so everyone | does, and so you end up with a fragmented ecosystem of little | sub-languages, not all of which (to put it mildly) are | particularly well designed. | | I have a career-long love and admiration for Lisp, but I've | never used it for "real" things because of this precise reason. | I wanted my code to be understandable and modifiable by others | who are already familiar with the programming language I'm | using. With Lisp, it's almost guaranteed that any sufficiently | large program will be written in its own dialect no one but the | author knows. | vindarel wrote: | nah, disagree, how do you come to the conclusion it is | "almost guaranteed" without having tried it for "real" | things? (no mean for ad-hominem, I'd like to read details) | | It's also a great language where you can adapt anything, any | library, to your needs, bypass its shortcomings, etc. | | What is the ecosystem of fragmented sub-languages? I don't | know any in CL. (ergolib isn't a crazy sub-language either, | it's just a library with helper functions and macros). We | have solid libraries like Serapeum, supporting all existing | implementations. Not sub-languages. | | I agree in the weakness that it's too easy to fix a library | and not contribute the fix back. Individuals and companies | are guilty here. I wish I saw more companies contributing to | the open-source libs they use. But other persons send great | contributions. It's a small world, so we easily see the good | and the ugly. | eliben wrote: | I believe the OP's ergolib provides an example. From https: | //github.com/rongarret/ergolib/blob/master/core/bindin..., | the examples show code like: ;;; (bb | ;;; x 1 ;;; :db (y z) (foo) ;;; :mv (a b | c) (bar) ;;; (do-something) ;;; :with open- | file f "foo" ;;; (do-something-else)) | | And the code this replaces. This seems to me hard to | understand without first digging into ergolib and grokking | what bb means. It's just one simple example. | | I forget now where it was, but there's a famous Lisp quote | which goes something like (paraphrased from poor memory): | in Lisp you don't just solve problem X, you first grow a | new programming language designed for solving X-like | problems and then simply solve X with that. | | This has its charms, for sure. But it makes the code harder | to understand for folks not familiar with your "language | designed for solving X-like problems" | vindarel wrote: | It's a little helper, so as in any language we have to | check the doc and an example. Just like how to use a rest | api, or a high level function that does a lot of stuff | under the hood. Once you know it's a binding macro it's | even easy to guess. I don't find it difficult, it is | similar to many similar macros out there. | | so yeah, I don't find the example extraordinary enough to | speak about sub-languages. Plus, as another comment said | very well, the most important is domain knowledge to | understand the code. And the quote is right but we can | also use Lisp like a dumb language and get shit done! | proamdev123 wrote: | You seem to imply in TFA that you believe Clozure Common Lisp | specifically is the best Lisp distribution. (Please correct me | if I'm misinterpreting your stance here.) | | What about CCL makes you describe it as a "technological | marvel"? What advantages have you gotten from CCL that can't be | obtained from other Lisp distributions? | | I'm asking as someone curious about Lisps and who always | thought that the various Lisp distributions were roughly | equivalent -- so I'm sincerely curious, not doubting you. | tosh wrote: | What are you using Lisp for lately? | lisper wrote: | I'm not doing a lot of coding nowadays. But for the past five | years or so I have had a consulting gig helping to maintain | and extend a tool for VLSI chip design written in Common | Lisp. Unfortunately, I can't say anything more about that at | the moment. | | Before that I wrote an e-commerce system that I used to run | my company, Spark Innovations. It used Stripe for billing, | Easypost for shipping, and Hunchentoot as the web server. I | also wrote a spam filter that is still in production on my | personal web server. | vindarel wrote: | I find those exaggerated: | | > I don't really program in Common Lisp any more. I program in a | little custom language that I have incrementally built on top of | Common Lisp over the years | | so yeah, that's CL. ergolib is a CL library, like any other, with | a cool macro to learn, if you want. | | > A CL programmer looking at my code would probably go, "WAT?" | | it's OK :] There are still defun and opening parens. | | > a fragmented ecosystem of little sub-languages | | but what sub-languages are we talking about? I only see a library | with helper functions and macros. That's Common Lisp, not a | derivative. You can pick any other library of the ecosystem, it's | compatible, like Serapeum, another common library with many | useful stuff baked-in, compatible with all CL implementations. I | don't call that a fragmented ecosystem. Only some authors have | their fav' utility and that's ok. | | Last words re implementations, for new readers: SBCL is thriving, | LispWorks and ACL deliver, ABCL and ECL are active, CLASP (CL on | LLVM) is financed and active, GNU CL got a new release, someone | in Japan started a new implementation in C, someone else on | Savannah another one in C again... And CCL is not thriving | unfortunately :( There is room for contributors (there's some | backing, contact the CL Foundation). ___________________________________________________________________ (page generated 2023-01-28 23:00 UTC)