Live data from Hacker News

Understanding the Power of Lisp (2020)

joshbradley.me

41–50 of 140 posts

Re: Understanding the Power of Lisp (2020)

#41
post #38

Earlier quoted context omitted.

When I first started writing asm code, it was accepted to write self-modifying code (programmatically create new code, then jmp to it.) Then I discovered and was told it was a bad idea. So that's how I view Lisp macros - creating code on the fly and executing it. When I was studying this issue, I came across femtolisp, which is a standalone Lisp by the author of Julia, Jeff Bezanson. Julia has metaprogramming so I wa…

> So that's how I view Lisp macros - creating code on the fly and executing it. This is an incorrect assumption. In compiled Lisps[0], macros are a compile-time construct, which manipulate the data structures that represent your code[1]. All manipulation occurs at compile-time. In interpreted Lisps, macro evaluation is temporally intertwined with program execution, but the two phases are logically distinct. [0]: Comp…

Thank you for taking the time to answer! At compile time vs at runtime is an important distinction that I need to think about. I'll start the video from the beginning because I'm curious about Clojure and most things Rich Hickey does, since I liked is Simple Made Easy video so much.

Re: Understanding the Power of Lisp (2020)

#42
post #21

A fun exercise when reading posts like those is to mentally compare to TCL. It is somewhat uglier - TCL's lists are multi-valued; and newlines are signficicant, introducing difference between "script" and "command". Still, the basic eval command looks remarkably similar in lisp vs TCL.

> Still, the basic eval command looks remarkably similar in lisp vs TCL.

The primary difference is whether arguments are evaluated before (Scheme/Lisp) or after (Tcl) being sent to the function/command.

The deferred evaluation is what allows you to do things that you need macros for in other languages. (ie. you need deferred evaluation or macros to implement short-circuit operators, for example)

However, early Lisps had FEXPRs which also deferred evaluation. The late John Shutt built and entire Lisp called "Kernel" around the idea:

http://web.cs.wpi.edu/~jshutt/kernel.html

I strongly recommend a read through his PhD thesis: https://www.wpi.edu/Pubs/ETD/Available/etd-090110-124904/

Unfortunately, his implementation isn't anywhere near as good as his conception. Other people have implemented it better.

http://axisofeval.blogspot.com/search/label/kernel http://axisofeval.blogspot.com/2011/09/kernel-underground.ht...

The Oh Unix shell grabs some of the core Kernel concepts and runs with them in a useful package: https://github.com/michaelmacinnis/oh

Re: Understanding the Power of Lisp (2020)

#43
post #34

I have the same response to this as I do to every other lisp article. It’s cool, but how have you personally leveraged this advantage that everyone talks about? What big lisp project has the author contributed to, such that they have enough data to sing it’s praises?

I follow that up with knowledge of a large project that was started in Lisp (actually Scheme) that had to be converted to C# because the difficulty of finding experienced Scheme developers for the years of maintenance that would be expected was far more than the cost of converting to a language that's more "usable."

Still remember all the meetings that generally always included someone complaining "what the $#&^%! were they thinking and why didn't their Management stop it before it got this far."

Re: Understanding the Power of Lisp (2020)

#44
post #24
post #2

The thing is that trying to understand "the power of Lisp" via the toy interpreter from The Roots of Lisp[0] is like trying to understand "the beauty of the sea" after seeing a single five-minute YouTube video explaining it. It will give you the basic idea, but it won't tell you about macros, reader macros, compiler macros, and having the whole language always available to build your abstractions on; it won't tell yo…

I've learned Clojure. Tried and failed to see this unique power of macros. Truly asking for help: can you help explain what can I do with macros that I cannot do with functions? Or, maybe, cannot do with high quality or low complexity using functions?

Well, for Clojure ...

Spend 5 minutes playing with -> [0]. Appreciate how pretty it makes the code and how nice it is for laying out sequential operations. What a fun operator. Then try to implement it yourself as a function.

When you discover that you can't, you will have discovered the unique power of macros (note the docs link to source code so you can see the readable 8-line macro implementation). You've also learned a very practical skill, which is how to write threading macros that handle your special edge case fail conditions. It comes in handy from time to time.

[0] https://clojure.github.io/clojure/clojure.core-api.html#cloj...

Re: Understanding the Power of Lisp (2020)

#45
post #34

I have the same response to this as I do to every other lisp article. It’s cool, but how have you personally leveraged this advantage that everyone talks about? What big lisp project has the author contributed to, such that they have enough data to sing it’s praises?

I follow that up with knowledge of a large project that was started in Lisp (actually Scheme) that had to be converted to C# because the difficulty of finding experienced Scheme developers for the years of maintenance that would be expected was far more than the cost of converting to a language that's more "usable." Still remember all the meetings that generally always included someone complaining "what the $#&^%! we…

I know a startup that hired a Marxist-collective group of programmers. I was told this story years ago, and they were acquired, so I’ll just name the firm - “White Ops”. This story is so absurd that I’m naming the firm in hopes someone can verify the accuracy of this, although I trust the person that told me the tale.

The programmers were based in Canada and only wrote in Haskell. The CTO of White Ops had apparently hired them previously as contractors at a prior company without issue.

In hindsight, it turned out the purpose of Haskell was specifically because it was very difficult to hire anyone to replace them, and they wrote in a strange manner that left even experienced Haskell developers confused, especially without their customized IDE extensions.

After a couple rounds of funding, the Marxists went on strike and demanded huge amounts of equity from White Ops to continue working. Ultimately the company wound up rewriting everything in a more popular language than acquiesce to their demands. I heard the Marxist group also had tons of drama because the leader made everyone live onsite in shared housing.

Re: Understanding the Power of Lisp (2020)

#46
post #40
post #37

Earlier quoted context omitted.

Here's a simple example you can't write in most languages. (first-working (get-it-from-the-cache) (get-it-from-the-database) (get-it-from-an-external-api) (compute-it-the-slow-way) default-value) Note each of those functions could throw an exception. You want to ignore it (or you could log it) and move on to the next.

Maybe I am missing something. Here's how I might write something equivalent in Python: for f in GetFromCache, GetFromDatabase, GetFromAPI, Compute: try: return f() except Exception as ex: log(ex) return default_value (You'd probably define a custom exception class for your application that represents the kinds of errors you can tolerate, so you don't end up swallowing programming errors, but you get the idea.)

Mmm. You've given a code snippet while Zak had a single macro call. Let's make your code into a function with signature:

    def atdt_exception_suppression(*list_of_fns):
        ...
What you've done is leverage the fact that functions are first class objects in Python (ie, can be passed as arguments) to achieve the same result as a macro. Which is cool, it works. Probably slightly better than a macro for this use case because we get a neat function boundary.

But macros are a powerful option because it doesn't matter if functions are first class or not. If you are using a language where functions aren't first class objects, a macro system would let Zak implement anyway.

So you are correctly identifying that Python can implement this in an alternate way as a function, but a macro system is sufficient to do this and a whole batch of other tricks even if first class functions aren't available as a feature.

Re: Understanding the Power of Lisp (2020)

#47
post #40
post #37

Earlier quoted context omitted.

Here's a simple example you can't write in most languages. (first-working (get-it-from-the-cache) (get-it-from-the-database) (get-it-from-an-external-api) (compute-it-the-slow-way) default-value) Note each of those functions could throw an exception. You want to ignore it (or you could log it) and move on to the next.

Maybe I am missing something. Here's how I might write something equivalent in Python: for f in GetFromCache, GetFromDatabase, GetFromAPI, Compute: try: return f() except Exception as ex: log(ex) return default_value (You'd probably define a custom exception class for your application that represents the kinds of errors you can tolerate, so you don't end up swallowing programming errors, but you get the idea.)

You’re running through a list of functions, the lisp example has a list of _function calls_ (which are not evaluated until necessary). Consider how your approach would have to change if each of those functions takes different parameters.

Re: Understanding the Power of Lisp (2020)

#48
post #45

Earlier quoted context omitted.

I follow that up with knowledge of a large project that was started in Lisp (actually Scheme) that had to be converted to C# because the difficulty of finding experienced Scheme developers for the years of maintenance that would be expected was far more than the cost of converting to a language that's more "usable." Still remember all the meetings that generally always included someone complaining "what the $#&^%! we…

I know a startup that hired a Marxist-collective group of programmers. I was told this story years ago, and they were acquired, so I’ll just name the firm - “White Ops”. This story is so absurd that I’m naming the firm in hopes someone can verify the accuracy of this, although I trust the person that told me the tale. The programmers were based in Canada and only wrote in Haskell. The CTO of White Ops had apparently…

I loved every word of that!

Re: Understanding the Power of Lisp (2020)

#49
post #24
post #2

The thing is that trying to understand "the power of Lisp" via the toy interpreter from The Roots of Lisp[0] is like trying to understand "the beauty of the sea" after seeing a single five-minute YouTube video explaining it. It will give you the basic idea, but it won't tell you about macros, reader macros, compiler macros, and having the whole language always available to build your abstractions on; it won't tell yo…

I've learned Clojure. Tried and failed to see this unique power of macros. Truly asking for help: can you help explain what can I do with macros that I cannot do with functions? Or, maybe, cannot do with high quality or low complexity using functions?

Colloquially: You can rewrite source code into a different form as it's being evaluated, then have it be further evaluated as if it were originally written in the new form.

One fairly simple example is Clojure's `when`, which is an expression that starts off looking like

  (when (= 0 1) (+ 1 2))
and gets re-written to

  (if (= 0 1) (do (+ 1 2)))
before being further compiled. This rewriting happens as many times as necessary until an expression "bottoms out" and can be evaluated in terms of only built-ins.

It's instructive to see how much of e.g., Clojure is implemented as macros. https://github.com/clojure/clojure/blob/master/src/clj/cloju... shows pretty clearly the correspondence between the original form and the rewritten form in the definition of `when`. `defn`, which is so foundational to idiomatic Clojure that it's easy to mistake it for a built-in, is a much more complicated example.

Re: Understanding the Power of Lisp (2020)

#50
post #34

I have the same response to this as I do to every other lisp article. It’s cool, but how have you personally leveraged this advantage that everyone talks about? What big lisp project has the author contributed to, such that they have enough data to sing it’s praises?

I wrote this to try and show how that could happen in a realistic enough way to make sense:

https://github.com/codr7/whirlisp

Post reply on HN