Live data from Hacker News

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

log.schemescape.com

181–190 of 346 posts

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

#181

Earlier quoted context omitted.

Of course people "realise" this. But those REPLs are not actually REPLs. They are interactive language prompts. They aren't actually REPLs. As the joke goes, Python doesn't have a REPL: it lacks READ, EVAL, PRINT and LOOP. Being able to type in code and have it evaluated one line at a time isn't a REPL.

i have no idea what subtle or nuanced distinction you're trying to strike so what exactly do you imagine is the difference between a lisp repl and a python repl? Edit: people that aren't familiar with python (or how interpreters work in general) don't seem to understand that being able to poke and prod the runtime is entirely a function of the runtime, not the language. In cpython you can absolutely do anything you w…

Restarting from the debugger keeps state without third party Python hacks that you mention. In this example Python increments x twice, Lisp just once:

  >>> x = 0
  >>> def f():
  ...     global x # yuck!
  ...     x += 1
  ... 
  >>> def g(y):
  ...     h()
  ... 
  >>> 
  >>> g(f())
  Traceback (most recent call last):
    File "", line 1, in 
    File "", line 2, in g
  NameError: name 'h' is not defined
  >>> 
  >>> def h(): pass
  ... 
  >>> g(f())
  >>> 
  >>> x
  2

Versus:

  * (setf x 0)
  * (defun f() (incf x))
  * (defun g(y) (h))
  * (g(f))

  debugger invoked on a UNDEFINED-FUNCTION in thread
  #:
    The function COMMON-LISP-USER::H is undefined.

  Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

  restarts (invokable by number or by possibly-abbreviated name):
    0: [CONTINUE      ] Retry calling H.
    1: [USE-VALUE     ] Call specified function.
    2: [RETURN-VALUE  ] Return specified values.
    3: [RETURN-NOTHING] Return zero values.
    4: [ABORT         ] Exit debugger, returning to top level.

  ("undefined function")
  0] (defun h() nil)
  ; No debug variables for current frame: using EVAL instead of EVAL-IN-FRAME.
  H
  0] 0
  NIL
  * x
  1

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

#182
post #178

Earlier quoted context omitted.

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 RESUM…

Do you think the magic fairies are doing it for you? Your interpreter/runtime is still doing it whether you're aware of it or not.

My point is very simple: I can do it too, in any language I want, and so there's nothing special about lisp.

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

#183
post #168

Earlier quoted context omitted.

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?

Compared to Python, Common Lisp hardly has any performance issues.

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

#184
post #165

Earlier quoted context omitted.

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…

I'll take this as an answer to my sibling comment that the answer is "No". I'm really sad CPython can't do that, but maybe some other Python can. It shouldn't necessarily be any slower for the interpreter to figure out where to jump to before saving the execution trace and jumping.

It's not "pointless", I was tearing out my hair and losing days because I couldn't do this in CPython. Yes, I'd much rather use Python than Common Lisp regardless.

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

#185

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…

Love your site's CGA vibes.

Maybe I'm missing something. What about the site is giving CGA vibes?

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

#186
post #168

Earlier quoted context omitted.

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?

I thought you know Lisp? Now you are surprised that Lisp often looks up functions via symbols -> aka "late binding"? How can that be? That's one of the basic Lisp features.

Next you can find out what optimizing compilers do to avoid it, where possible or where wanted.

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

#187

Earlier quoted context omitted.

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_FUNC…

Thank you, you're very helpful despite this raging flame war. I'm glad to hear you can hook opcodes like that, then you really can do anything. And I really need to give "set a defensive breakpoint and then step through the function" an honest go. Now that you say it, I realise I haven't.

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

#188
post #178

Earlier quoted context omitted.

> 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 RESUM…

Do you think the magic fairies are doing it for you? Your interpreter/runtime is still doing it whether you're aware of it or not. My point is very simple: I can do it too, in any language I want, and so there's nothing special about lisp.

> My point is very simple: I can do it too, in any language I want, and so there's nothing special about lisp.

The big difference is: "I can do it too" means YOU need to do it. Lisp does it for me already, I have not to do anything. I don't want to know what you claim you can do with C++, show me where C++ does it for you.

Telling me "I can do it too" is not a good answer. Show me where the language implementation (!) does it for you.

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

#189
post #159
post #156

Earlier quoted context omitted.

How does it look like in Python? In Lisp: CL-USER 43 > (+ 1 (foo 20)) Error: Undefined operator FOO in form (FOO 20). 1 (continue) Try invoking FOO again. 2 Return some values from the form (FOO 20). 3 Try invoking something other than FOO with the same arguments. 4 Set the symbol-function of FOO to another function. 5 Set the macro-function of FOO to another function. 6 (abort) Return to top loop level 0. Type :b fo…

Hmm, what advantage does Lisp offer here over Python? >>> 1 + foo(20) Traceback (most recent call last): File " ", line 1, in NameError: name 'foo' is not defined >>> def foo(a): ... return a + 21 File " ", line 2 return a + 21 ^ IndentationError: expected an indented block >>> def foo(a): ... return a + 21 ... >>> 1 + foo(20) 42 >>> Mind the hilarious indentation error, as I had not touched the old-school REPL in ag…

I have been playing again with CL recently and am doing some trivial web-scraping of an old internet forum. I don't use a REPL directly, but just have a bunch of code snippets in a lisp file that I tell my editor to evaluate (similar to Jupyter?). I haven't bothered doing any exception (condition) handling, and so this morning I found this in a new window:

   Condition USOCKET:TIMEOUT-ERROR was signalled.
      [Condition of type USOCKET:TIMEOUT-ERROR]

   Restarts:
    0: [RETRY-REQUEST] Retry the same request.
    1: [RETRY-INSECURE] Retry the same request without checking for SSL certificate validity.
    2: [RETRY] Retry SLIME interactive evaluation request.
    3: [*ABORT] Return to SLIME's top level.
    4: [ABORT] abort thread (#)
plus the backtrace. This is in a loop that's already crawled a load of webpages and has some accumulated some state. I don't want a full redo (2), so I just press 0. The request succeeds this time and it continues as if nothing happened.

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

#190
post #183

Earlier quoted context omitted.

>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?

Compared to Python, Common Lisp hardly has any performance issues.

Okay well when pytorch, tensorflow, pandas, Django, flask, numpy, networks, script, xgboost, matplotlib, spacy, scrapy, selenium get ported to lisp, I'll consider switching (only consider though since the are probably at least another 20 python python packages that I couldn't do my job without).
Post reply on HN