Live data from Hacker News

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

log.schemescape.com

171–180 of 346 posts

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

#171

Earlier quoted context omitted.

>Code evaluation, compilation I couldn’t debug the following in pycharm and add the missing function at runtime, or could i? def interactively_writing_code(): this_doesnt_exist_yet() interactively_writing_code() I don’t think i can patch a function at runtime without losing state either in python - the act of redefining the function causes the variables to be reset but in lisp the bindings are untouched.

I just did it - it works perfectly fine. Debug-run your code, an exception will be thrown at the call site, step up one frame from the exception (ie module level), define the missing function, call again and it succeeds - all without leaving the same repl instance. Don't believe me? Try it. I'll say it again: you guys are in plain denial not about python or lisp as languages but about how interpreters work . There's…

This works in compiled Lisp code.

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

#172
post #165

Earlier quoted context omitted.

I just did it - it works perfectly fine. Debug-run your code, an exception will be thrown at the call site, step up one frame from the exception (ie module level), define the missing function, call again and it succeeds - all without leaving the same repl instance. Don't believe me? Try it. I'll say it again: you guys are in plain denial not about python or lisp as languages but about how interpreters work . There's…

Calling again and continuing are not the same thing. Sure, with the above trivial example it is. But if the parent function has non idempotent code before calling the missing function (like doing some global change / side effects), then calling again will give a different result than just continuing from the current state. So is it possible to define the missing function and continue from the same state in Python? I…

>So is it possible to define the missing function and continue from the same state in Python? I don't think so, but I'm not a heavy Python user

This is a pointless debate - someone has to catch the exception, save caller registers, handle the exception (if there's a handler) or reraise. Either you have to do it (by putting a try except there) or your runtime has to be always defensively saving registers or something. Lisp isn't magic, it's just a point on trade-off curve and I have without a shadow of a doubt proven that that point is very close to python (wrt the repl). So okay maybe clisp has made some design decisions that make it a hair more effective at resuming than python. Cool I guess I'll just ignore all the other python features where there's parity or advantage because of this one thing /s.

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

#173
post #171

Earlier quoted context omitted.

I just did it - it works perfectly fine. Debug-run your code, an exception will be thrown at the call site, step up one frame from the exception (ie module level), define the missing function, call again and it succeeds - all without leaving the same repl instance. Don't believe me? Try it. I'll say it again: you guys are in plain denial not about python or lisp as languages but about how interpreters work . There's…

This works in compiled Lisp code.

It works in code compiled from c++ too: define and associate a signal handler for sigkill, call a function whose symbol can't be runtime resolved by the linker, sigkill is sent and caught, define your function (in your asm dejure), patch the GOT to point from the original symbol to wherever the bytearray is with your asm, and voila.

I'll say it again: what exactly do you think your magical lisp is doing that defies the laws of physics/computing?

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

#174

Earlier quoted context omitted.

>Code evaluation, compilation I couldn’t debug the following in pycharm and add the missing function at runtime, or could i? def interactively_writing_code(): this_doesnt_exist_yet() interactively_writing_code() I don’t think i can patch a function at runtime without losing state either in python - the act of redefining the function causes the variables to be reset but in lisp the bindings are untouched.

I just did it - it works perfectly fine. Debug-run your code, an exception will be thrown at the call site, step up one frame from the exception (ie module level), define the missing function, call again and it succeeds - all without leaving the same repl instance. Don't believe me? Try it. I'll say it again: you guys are in plain denial not about python or lisp as languages but about how interpreters work . There's…

What's being asked is, after defining the missing function, whether it's possible to clear the exception and continue the execution without having to restart from the beginning. This is very useful when you hit an exception after 10 minutes of execution. (This is a real usecase which would have saved me untold hours.)

I hope it's possible somehow, but if you just load pdb (e.g. with %pdb in ipython), pdb is entered in post-mortem mode, from which it's impossible to modify code/data and resume execution. Setting a breakpoint (or pdb.set_trace()) would requiring knowing about the bug ahead of time. Does it only work when interrupting with a remote debugger rather than on exception?

However, it wouldn't be possible if the interpreter unwinds the stack looking for exception handlers before finding that there is none? In other languages/VMs such as SBCL the runtime can look up the stack for handlers, and invoke the debugger before destructively unwinding.

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

#175
post #168

Earlier quoted context omitted.

>Note that we are not in some debug mode, to get this functionality. Jesus Christ I swear it's like you ascribe mysterious powers to the parens. Do you think the parens give you the ability to travel through time or reverse the pc or what? Okay it's not in a debug mode but it's in a "debug mode". Like seriously tell me how you think this works if it's not effectively catching/trapping some sigkill or something that's…

Common Lisp programs run by default in a way that calls to undefined functions are detected. Here the Lisp simply tries to look up the function object from the symbol. There is no function, so it signals a condition (aka exception). The default exception handler gets called (without unwinding the stack). This handler prints the restarts and calls another REPL. I define the function -> the symbol now has a function de…

>Common Lisp programs run by default in a way that calls to undefined functions are detected.

Cool so what you're telling me is that by default every single function call incurs the unavoidable overhead of indirecting through some lookup for a function bound to a symbol. And you're proud of this?

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

#177

Earlier quoted context omitted.

>Can you connect to a running server or other running application, inspect live in memory data, change live in memory data, redefine functions and classes and have those changes take immediate effect without restarting the server or app? The answer to all of these things, at least in python, is emphatically yes. I do this absolutely all the time. You can debug from one process to another if you've loaded the right ho…

The answer to all these things should be "just doesn't work in practise", not for real programs anyways. Unlike Lisp, Python doesn't lean itself well to this mode of development. Primitive CLI-like tinkering, figuring out language features, calc-like usage - maybe. But not a single time in 15 years of doing Python across the industry I saw anybody using these features for serious program development, or live coding,…

Am I some kind of a python unicorn? I do those things with python just about every time I write new python code.

The thing Common Lisp does that python doesn't (so far) is outputting well-performing code.

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

#178
post #171

Earlier quoted context omitted.

This works in compiled Lisp code.

It works in code compiled from c++ too: define and associate a signal handler for sigkill, call a function whose symbol can't be runtime resolved by the linker, sigkill is sent and caught, define your function (in your asm dejure), patch the GOT to point from the original symbol to wherever the bytearray is with your asm, and voila. I'll say it again: what exactly do you think your magical lisp is doing that defies t…

> It works in code compiled from c++ too: define and associate a signal handler for sigkill, call a function whose symbol can't be runtime resolved by the linker, sigkill is sent and caught, define your function (in your asm dejure), patch the GOT to point from the original symbol to wherever the bytearray is with your asm, and voila.

I don't need to do anything like that in Lisp. I just define the function and RESUME THE COMPUTATION WHERE IT STANDS in my read eval print loop. << important parts in uppercase.

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

#179

Earlier quoted context omitted.

I just did it - it works perfectly fine. Debug-run your code, an exception will be thrown at the call site, step up one frame from the exception (ie module level), define the missing function, call again and it succeeds - all without leaving the same repl instance. Don't believe me? Try it. I'll say it again: you guys are in plain denial not about python or lisp as languages but about how interpreters work . There's…

What's being asked is, after defining the missing function, whether it's possible to clear the exception and continue the execution without having to restart from the beginning. This is very useful when you hit an exception after 10 minutes of execution. (This is a real usecase which would have saved me untold hours.) I hope it's possible somehow, but if you just load pdb (e.g. with %pdb in ipython), pdb is entered i…

The other guy up above claims this is a feature unique to calling functions, rather than all error states, and that the lisp runtime specifically guards against this. If that's the case then my answer is very simple: it would be trivial to guard function calls (all function calls) to achieve the exact same functionality in python. I'm in bed but it would literally take me 5 minutes (I would hook eval of the CALL_FUNCTION opcode). Now it would be asinine because it's a six-sigma event that I call a function that isn't defined. On the other hand, setting a breakpoint and redefining functions as you go works perfectly well and is the common case and simultaneously the kind of "repl driven development" discussed all up and down this thread.

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

#180
post #79

Earlier quoted context omitted.

Quicklisp doesn’t use TLS or signatures? How have I not heard this before? That would be unbelievably irresponsible. Has this really not been addressed by the CL community? Edit: here’s the issue: https://github.com/quicklisp/quicklisp-client/issues/167 Thanks for bringing this up!

The reason for this is quite simple: portability. Quicklisp also uses plain TAR files to distribute dists. Why? Because quicklisp has a built-in TAR extractor written in 100% standard/portable CL. This allows Quicklisp to run on just about everything, from your computer to real LispMs and operating systems like Mezzano. TLS comes up every time someone discusses Quicklisp, but nobody bothers to go ahead and actually i…

This does keep coming up, and it's a few years old now. I think Quicklisp can easily still support https while supporting the older packages that are tar+http, which could easily be mirrored in a git repo. Quicklisp has unfortunately taken over the entire ecosystem, making it hard to use anything else, and you often need to depend on it to use a lot of tools in the ecosystem. It sort of reminds me of Systemd in that way.

I agree on the version pinning being a worse situation, and also not having something like "node_modules" for lisp. I haven't tried CLPM since a while back, it was kind of hard to setup back then.

I have a little package manager thing, cl-micropm, that just uses Quicklisp to fetch everything via docker (should probably support podman too), and an .envrc file to tell ASDF to look in the project directory (a project-local node_modules-like folder called "lisp-systems") for systems. That way I can pin my deps manually by picking the commits + git submodule in lisp-systems/, and it's isolated to my local project. I looked into using the Docker container to rewrite the requests to use https, bypassing whatever Quicklisp is doing, but I never got around to that.

I'm looking to switch it to something even simpler/explicit though, cl-pm, that'll only optionally need/use Quicklisp via podman _only_ to figure out what the dependencies are, and then just have a function that uses wget/curl/git-pull to conveniently explicitly pull them in on request. That way you can decide to add a git mirror for an old http library, or pin a specific version, etc. It's slightly more manual than Quicklisp or CLPM, not a big deal, but very easy for anyone with just a little bit of lisp knowledge to understand the whole thing in under an hour.

Post reply on HN