Live data from Hacker News

It's 2023, so of course I'm learning Common Lisp

log.schemescape.com

51–60 of 346 posts

Re: It's 2023, so of course I'm learning Common Lisp

#51
post #41
post #35

Earlier quoted context omitted.

People say this a lot, but they fail to take into account that you can debug your server live as it continues to handle normal traffic. Even if you don’t deploy changes via the REPL, merely debugging the problem in a REPL without restarting anything is a huge win.

Lots of languages that are not lisp have this ability.

Which?

Re: It's 2023, so of course I'm learning Common Lisp

#52
post #4

The scoop: Scheme and Janet are great, but the author wants a more standalone language. What makes the difference is the breakloop, a full-blown REPL that opens when an error in a program occurs. Not a stacktrace, not a debugger; just build from the point where it's currently broken.

That sounds intriguing as a Clojure dev but what happens in the following case (not very lispy code but it's just to show what I don't get): (do-it (do-it first)) What if (do-it first) works fine, but it's the call to (do-it (do-it first)) that fails? I get control right where it's broken, so I can fix the do-it defun . Great, I like that. But by fixing it, this means I changed the result of (do-it first). So the poi…

you didn't necessarily change the result of (do-it first), you may have, but that just means you introduced another error.

i think the approach here is to accept that you fixed the bug for the second call, but you will still have to go back and retest the first call.

Re: It's 2023, so of course I'm learning Common Lisp

#53
post #52

Earlier quoted context omitted.

That sounds intriguing as a Clojure dev but what happens in the following case (not very lispy code but it's just to show what I don't get): (do-it (do-it first)) What if (do-it first) works fine, but it's the call to (do-it (do-it first)) that fails? I get control right where it's broken, so I can fix the do-it defun . Great, I like that. But by fixing it, this means I changed the result of (do-it first). So the poi…

you didn't necessarily change the result of (do-it first), you may have, but that just means you introduced another error. i think the approach here is to accept that you fixed the bug for the second call, but you will still have to go back and retest the first call.

> you didn't necessarily change the result of (do-it first)

You're right.

> i think the approach here is to accept that you fixed the bug for the second call, but you will still have to go back and retest the first call.

Gotcha. It looks like a very useful feature. I may actually just try it to try to understand how it works: especially since TFA says the CL integration with Emacs is good (I happen to be an Emacs user).

Re: It's 2023, so of course I'm learning Common Lisp

#54
post #24

Earlier quoted context omitted.

Performance, approachability Someone's going to argue with me. Fair enough. Provide your explanation.

this is an age old argument, but given the popularity of other slower languages, i'd rather think that approachability is the more critical issue.

It’s the issue. The ever popular syntax issue continues to haunt it.

CL has had no real “unknown unknowns” for a very long time. While folks who newly discover it feel they found the gold idol in the jungle cave, the cave is, in truth, well explored, mapped, and documented but the idol is left behind.

All excuses to not use CL have long been, or have had the opportunity to be, addressed. Today, it’s fast enough, small enough, empowered through utilities and libraries enough, has different build and deployment scenarios to work with a vast array of applications. And yet here we are...still.

ABCL runs on the JVM, which runs everywhere on everything. Clojure, first class system on top of the JVM, but no real adoption. Some, to be sure, likely (I have no data) more than CL itself. But it’s still an blip on the radar.

Meanwhile, a bunch of hackers threw together a language sharing many aspects of the core feature set made popular in Lisp and Scheme runtime environments, made it look like an Algol step child with curly braces and everything, and since then an entire ecosystem of software has been written (and rewritten) into this system and it’s runtime is the focus of some of the largest companies in the history of civilization.

Raise your hand if you think that if the creators of JavaScript went with an S-expression syntax instead of a C/Java derivative, we’d be running a VBA clone in our browsers (but nowhere else)?

Because at this juncture, THE thing that distinguishes CL and other Lisps from where we are today, is the syntax. Every other charm these systems enjoyed have been cherry picked away.

Advocates say the syntax is not an issue. It’s a feature m, not a bug. But the “wisdom of the crowds” has spoken, and they stay away.

Re: It's 2023, so of course I'm learning Common Lisp

#55
post #4

The scoop: Scheme and Janet are great, but the author wants a more standalone language. What makes the difference is the breakloop, a full-blown REPL that opens when an error in a program occurs. Not a stacktrace, not a debugger; just build from the point where it's currently broken.

That sounds intriguing as a Clojure dev but what happens in the following case (not very lispy code but it's just to show what I don't get): (do-it (do-it first)) What if (do-it first) works fine, but it's the call to (do-it (do-it first)) that fails? I get control right where it's broken, so I can fix the do-it defun . Great, I like that. But by fixing it, this means I changed the result of (do-it first). So the poi…

Please excuse the really contrived example, but you can do this in Gambit:

    ~ cat do-it.scm
  (define (do-it x)
    (if (> x 0)
        x
        'error))
  
  (define (do-it-fixed x)
    (if (and (number? x) (> x 0))
        x
        'error))
  ~ gsi do-it.scm -
  > (do-it (do-it 0))
  *** ERROR IN do-it, "do-it.scm"@2.7 -- (Argument 2) REAL expected
  (> 'error 0)
  1> ,b
  0  do-it                   "do-it.scm"@2:7         (> x 0)
  1  (interaction)           (stdin)@1:1             (do-it (do-it 0))
  2  ##main                  
  1> ,e
  x = 'error
  1> (set! do-it do-it-fixed) 
  1> ,(c x)
  error
  > (do-it (do-it 0))
  error
Per the Gambit docs[1], "The nested REPL’s continuation and evaluation environment are the same as the point where the evaluation was stopped.". The call to ,(c x) is really just calling the reified continuation c with argument x.

[1]: https://gambitscheme.org/latest/manual/#Debugging

Re: It's 2023, so of course I'm learning Common Lisp

#56
There are plenty of old business systems which are critical, can't be removed or turned off, and use LISP, COBOL, etc. Meanwhile, nothing important uses Clojure or other trendy flash-in-the-pan language. If you want an interesting project, sure, use Clojure or something. If you want money, learn COBOL.

Re: It's 2023, so of course I'm learning Common Lisp

#57
post #41
post #35

Earlier quoted context omitted.

People say this a lot, but they fail to take into account that you can debug your server live as it continues to handle normal traffic. Even if you don’t deploy changes via the REPL, merely debugging the problem in a REPL without restarting anything is a huge win.

Lots of languages that are not lisp have this ability.

I don’t think that they do. I know that Erlang has something similar; you can reload a module and it will gradually replace the old code as processes are replaced. In principle you could debug a single thread in a C (or C++) program without stopping the others, and some IDEs will let you edit the code and recompile while the program is running (they patch out the old function definition so that it jumps to the new one instead), but good luck doing that in production.

But don’t forget that in Common Lisp, you can redefine classes at run time as well as functions. All existing instances of the class will be updated to the new definition, and you can provide the code that decides how the old fields are translated into the new ones if the default behavior is insufficient. Good luck doing that in C or C++.

My favorite story involved a race condition that was discovered in the code running on a satellite, after it had been launched. The software on the satellite was mostly written in Common Lisp (there was a C component as well), so they opened a connection to the satellite, started the REPL, debugged the problem, and uploaded replacement code (which obviously added a lock or something) to the satellite all through that same REPL. While the satellite was a hundred million miles away from Earth, and while it kept performing it’s other duties. You can’t do that on a system which merely dumps core any time something unexpected happens.

Re: It's 2023, so of course I'm learning Common Lisp

#59
post #48

Wow, wasn't expecting to see my post on here! Eventually, I want to write a follow-up, but I'm still a beginner. Here's what I've liked about Common Lisp so far: * The condition system is neat and I've never used anything like it -- you can easily control code from afar with restarts * REPL-driven programming is handy in situations where you don't quite know what will happen and don't want to lose context -- for exam…

For static builds, if you're willing to run a slightly older version of sbcl daewok's work on building and linking sbcl in a musl environment might be solution you're looking for. I've tried to port his patches to more recent versions but there are segfaults due to changes in upstream. https://www.timmons.dev/posts/static-executables-with-sbcl.h... https://www.timmons.dev/posts/static-executables-with-sbcl-v...

Yes, I did see that, but I was scared off by having to apply patches :)

Re: It's 2023, so of course I'm learning Common Lisp

#60
post #25

I use Clojure at work but wow do I miss just about everything about Common Lisp whenever I have to debug anything or want performant code. Being able to be in nested errors and click at any part of the stack to inspect lexical bindings is extremely useful, and more importantly, clicking on an object then pushing M- to copy it to my REPL is much nicer than what Clojure offers (tap>, which I consider a glorified pretty…

You should look at flowstorm for Clojure. It lets you step through and back from a function and you can send maps to the repl with their functions.
Post reply on HN