Live data from Hacker News

The Liberating Experience of Common Lisp

ds9soft.com

101–110 of 126 posts

Re: The Liberating Experience of Common Lisp

#101
post #98

Earlier quoted context omitted.

You don't need OO for state management. Plain data structures and functions work just fine. The core aspects of OO like inheritance are not that useful for most problems.

> You don't need OO for state management. Of course you don't, that's why I said OO is most likely the way to go. I also spoke of more than simple state management - If you're modeling a system having several interacting entities whose interactions may vary based off that entity's current state - isn't simple state management. You still don't have to go OO to solve that problem, it's just a very good choice in most c…

> not a core aspect of OO

One of the core aspects of OO is reuse of functionality, typically by inheritance or delegation. We can find one or both in most OO languages.

Re: The Liberating Experience of Common Lisp

#102
post #101
post #98

Earlier quoted context omitted.

> You don't need OO for state management. Of course you don't, that's why I said OO is most likely the way to go. I also spoke of more than simple state management - If you're modeling a system having several interacting entities whose interactions may vary based off that entity's current state - isn't simple state management. You still don't have to go OO to solve that problem, it's just a very good choice in most c…

> not a core aspect of OO One of the core aspects of OO is reuse of functionality, typically by inheritance or delegation. We can find one or both in most OO languages.

I wouldn't say reuse of functionality is a core aspect of OO, but I will say that's a core reason why OO was so heavily adopted in the 90s. It's mind-numbing to recall how much time and money was wasted on making things "reusable" only to never be reused.

Re: The Liberating Experience of Common Lisp

#103
post #101

Earlier quoted context omitted.

> not a core aspect of OO One of the core aspects of OO is reuse of functionality, typically by inheritance or delegation. We can find one or both in most OO languages.

I wouldn't say reuse of functionality is a core aspect of OO, but I will say that's a core reason why OO was so heavily adopted in the 90s. It's mind-numbing to recall how much time and money was wasted on making things "reusable" only to never be reused.

> I wouldn't say reuse of functionality is a core aspect of OO

You'll find it in practically every object-oriented language, starting with Simula. Later Smalltalk, Actors, CLOS, C++, Self, Java, Objective-C, Python, JavaScript, ...

> making things "reusable" only to never be reused.

It's similar mind-numbing how much has been reused.

Re: The Liberating Experience of Common Lisp

#104
post #68

Earlier quoted context omitted.

This is a good perspective. I did work in lisp, including production systems (albeit small systems), for many years and authored many open source projects in CL. I'd say the biggest hurdle was the community. There was a strange balance between getting contributors and people going off and rewriting the thing you're working on becuase they can do it better/make it faster/etc. It definitely skews towards people going l…

That's true of any language or project to be fair. Big egos are everywhere in software development.

I'm saying, based on my observation, it's more pronounced in CL's culture, not that it doesn't happen in other languages.

Re: The Liberating Experience of Common Lisp

#105
post #61

Earlier quoted context omitted.

> Three things are killer features for me with the slime+emacs running sbcl. First is that you can see the underlying source for anything down to the lisp implementation, e.g. the definition of 'macrolet'. If you’re working on a project (on its code), then you can (obviously) see its code as well. Statically typed languages make exploring the code a lot easier, especially with an IDE which leverages the type informat…

I was likely not clear in my explanation. These three things are all done from the REPL. I don't have any experience doing C or C++ from a REPL. I disagree that "Statically typed languages make exploring the code a lot easier." I'm not aware of an equivalent in C or C++ to the "esc-." method of going directly to the source. The keystroke combination to find the definition of a function or symbol using slime and emacs…

> Once tripped, you can expand each element in the stack to see and inspect the variables local to that function.

When a breakpoint is tripped, with most modern IDEs and languages, you can see the local stack, global state (and pretty much all state), and this state is presented in a UI with dropdowns, etc. Debuggers in modern IDEs also let you evaluate an expression in place, where the breakpoint was tripped, so you can further dig into the local state with a debugger. This sort of works like a REPL (but you're "sort of" limited to a single expression -- but that's something you can still circumvent with an immediately-called lambda).

>You can then edit the source for that function, compile only that function in place, then resume execution.

This is supported by some languages, but admittedly support for this varies widely, and sometimes can be weak or finicky. For example, the JVM family of languages have a feature called HotSwap. This feature is quite old: https://www.jrebel.com/blog/java-hotswap-guide -- it was introduced in 2002 with the Java 1.4 JVM. I use it even today, with personal projects, where I update the code of a running server live (without restarting the server).

HotSwap unfortunately sometimes is broken with certain major JVM frameworks, but for my personal projects, I've always made sure to only use libraries that work well with HotSwap, since I consider live code patching of a running server to be an absolutely important feature.

>the "esc-." method of going directly to the source

To be honest, I'm not entirely sure what you mean here. When I'm working on a project (as in, I have an IDE open for it, and I'm writing the code for it), all the code is right there. When I use a debugger, I can see the stack of all the ancestral functions, and with a single click I can go to the definition of any function. Static typing basically makes the "Go to definition" more precise, as it always jumps to the place in the code (file & line) where any particular function or value is defined. With dynamically typed languages, an IDE can sometimes show you multiple option when there's multiple functions with the same name defined in different places.

>These three things are all done from the REPL. I don't have any experience doing C or C++ from a REPL.

Most of the features I've described above work with C and C++ IDEs (like CLion, Visual Studio, etc), except for the live code hot swapping -- I've only used live code patching with JVM HotSwap with Java, Kotlin, etc.

Re: The Liberating Experience of Common Lisp

#106
post #97

I'm a big fan of lisps, and haven't played sufficiently with rust to have an opinion -- but I will note that the benefits of a sophisticated type system is qualitatively different from, say, the statically-typed environment of C or Objective-C. The comparison I make when thinking about CL is something like Haskell or Elm, which /do/ have that feel of "if it compiles, it works". Without that, I do have the feeling of…

The sense of security is provided by a good test suite (which you still need) plus SBCL type annotations.

I've never managed to achieve that (the comparable sense of security), which may be on me.

Out of interest, have you worked in one of these typed languages -- Haskell, Elm, maybe OCaml (haven't tried it), Idris, Rust? I think they feel very different in this axis compared to C/C++/Objective-C/Java. Not necessarily better (I am still reminded of the term "bondage-and-discipline language" from the Jargon File[1]), but different.

[1]: http://www.catb.org/jargon/html/B/bondage-and-discipline-lan...

Re: The Liberating Experience of Common Lisp

#107
post #85

Earlier quoted context omitted.

Another thing is, that despite Genera having been gone from the real world for over 30 years, it is still nonfree, and most of the interesting software that ran on it hasn't been publically archived either. That has made it essentially worthless to most people who would otherwise be interested in it. On the contrary, the MIT Lisp Machine system from which Genera was derived is completely free, as well as the LMI syst…

> Another thing is, that despite Genera having been gone from the real world for over 30 years, it is still nonfree Eh. That's a non-starter. The code may be closed, the concepts aren't. We've been reinventing the wheel for ages, and the Genera developer experience apparently isn't novel enough to be worthy of being reinvented.

My point is that for people who wish to experience a Lisp Machine system for what it is, and explore its unique concepts, they have free systems they could be looking to rather than a dead proprietary one.

Re: The Liberating Experience of Common Lisp

#108
post #61

Earlier quoted context omitted.

I was likely not clear in my explanation. These three things are all done from the REPL. I don't have any experience doing C or C++ from a REPL. I disagree that "Statically typed languages make exploring the code a lot easier." I'm not aware of an equivalent in C or C++ to the "esc-." method of going directly to the source. The keystroke combination to find the definition of a function or symbol using slime and emacs…

> Once tripped, you can expand each element in the stack to see and inspect the variables local to that function. When a breakpoint is tripped, with most modern IDEs and languages, you can see the local stack, global state (and pretty much all state), and this state is presented in a UI with dropdowns, etc. Debuggers in modern IDEs also let you evaluate an expression in place, where the breakpoint was tripped, so you…

> Most of the features I've described above work with C and C++ IDEs

In Common Lisp you won't need an IDE and you won't need to instrument the application with a debugger, because much of the features are built into the language runtime.

For example Common Lisp has an error handling system with resumeable exceptions.

Another example is the object system where the objects are updated on changes. For example I can load a new class description and the existing objects are changed to the new description: new slots, fewer slots, new superclass, removed superclass, ... This makes hot loading much more useful. Additional many calls to global functions are late bound, which again makes hot loading more useful.

A typical runtime also includes a code loader, a compiler and/or an interpreter, which makes updating code easy. All without an IDE or a foreign debugger.

This also means that when for example the resident compiler is called, the compiler is a part of the runtime. An error under compilation, will show me the compiler in the stack trace and the compiler itself can be live edited/updated, while I'm in a compilation error.

The effect is then, that by default programs are running inside a runtime, which always provides the features of interpretation, compilation, code loading, repls, debug repls, runtime type checks, OOP updates, ... One would need to do something to turn those things off.

In a typical C/C++ program, the compiler, debugger, IDE, linker, ... are not a part of the program's runtime.

Re: The Liberating Experience of Common Lisp

#109
post #108

Earlier quoted context omitted.

> Once tripped, you can expand each element in the stack to see and inspect the variables local to that function. When a breakpoint is tripped, with most modern IDEs and languages, you can see the local stack, global state (and pretty much all state), and this state is presented in a UI with dropdowns, etc. Debuggers in modern IDEs also let you evaluate an expression in place, where the breakpoint was tripped, so you…

> Most of the features I've described above work with C and C++ IDEs In Common Lisp you won't need an IDE and you won't need to instrument the application with a debugger, because much of the features are built into the language runtime. For example Common Lisp has an error handling system with resumeable exceptions. Another example is the object system where the objects are updated on changes. For example I can load…

All of this late binding, and needing a runtime, seems to suggest even a JIT LISP implementation (e.g. SBCL) might not be able to achieve performance similar to a "zero-cost abstraction" language like Rust. When you're in debug mode (e.g. with C++ or Rust or a JVM language), there's a bunch of debug info added to the binary plus various optimizations are turned off. I'm sure some optimizations that C++ / Rust / LLVM use involve entire eliding classes and other abstractions, so that an "O3" release-mode binary doesn't even contain any cruft. There's an argument to be made for this approach, at least for software that's run on customers' computer. For server side software, I can see why having always-available debuggability is useful.

Re: The Liberating Experience of Common Lisp

#110
post #62
post #41

It really echoes my first memories of personal computers. You powered it on, and it landed you in a BASIC environment. Apple IIs, C64’s and Ataris all had a full-screen editor environment where you could type code, run it, pause it, inspect variables, and continue running. It wasn’t LISP, sadly, but it was great as an introduction and moving to “more professional” environments and tools took away a great deal of free…

I’m slowly working in something like portacle+multimedia: so you can turn on the computer, emacs starts, an you go doing a little game… I think deep inside the 8-bit retro people miss that, not the slow-low-resolution computers, but the experience of actually “making” something.

Only those who knew something can miss it.
Post reply on HN