Live data from Hacker News

Understanding the Power of Lisp (2020)

joshbradley.me

121–130 of 140 posts

Re: Understanding the Power of Lisp (2020)

#121
post #23

Earlier quoted context omitted.

don't count on (eq '(a b) '(a b)) being NIL. In Common Lisp it can be T. From what I read of Racket, it could be true, too.

If that were true I would consider it a very weird Common Lisp implementation. The main point is that you should never depend on it being true even though the two forms look the same. A couple more examples for the Common Lispers in the audience that highlight the difference between the reader and the evaluator: (setf foo (list #1=(list 3 4 5) #1#)) (eq (car foo) (cadr foo)) ; --> ?? What should we expect the second…

> It might return true in some implementations (very weird implementations), but in general one should not expect it to do so

That is incorrect. It must always return false. LIST is called multiple times, and each time it is called it must produce a distinct cons. Note this is a different issue from literal coalescing (mentioned else-thread).

Re: Understanding the Power of Lisp (2020)

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

Agree. There seems to be a lot more articles praising how awesome Lisp is than there is awesome code developed with Lisp.

Re: Understanding the Power of Lisp (2020)

#123
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 don’t consider myself a Lisp wizard and mostly stick to pretty simple code but to name a few cool things that would have been tedious or impossible in another language: - A desktop application for a bank in which not only the gui’s content but the look and structure was generated or changed on the fly mimicking the status of a database. - An interpreter in which most of its classes and methods were automatically ge…

I have implemented pretty much all of that in C++. It wasn’t hard or tedious. Using declarative data structure to runtime generate the UI from (for example) is something I do all the time. In C++, C# and Typescript. And evaluating expressions at runtime is just using an AST. Something I have also done a lot.

Re: Understanding the Power of Lisp (2020)

#124
post #106

Earlier quoted context omitted.

In ruby your lower level API should support methods with ! syntax that throw and without it that return nil instead: def get_from_cache get_from_cache! rescue NoRecord nil end Then you just do this to not only do it all but only do it once lazily on access: def record @record ||= get_from_cache || get_from_database || get_from_api || compute || default_value end Be slightly better if ruby supported a proper null coal…

> In ruby your lower level API should support... Assume, for purposes of the exercise that someone else wrote some of the methods you're calling and they do not behave this way. You could write your own wrappers, but that's a lot more code to write and maintain than a simple control structure that doesn't care what's inside it.

Submit a patch to get them implemented, or really just don't throw in cases that aren't actually exceptional and return nil instead.

Re: Understanding the Power of Lisp (2020)

#125

Earlier quoted context omitted.

I don’t consider myself a Lisp wizard and mostly stick to pretty simple code but to name a few cool things that would have been tedious or impossible in another language: - A desktop application for a bank in which not only the gui’s content but the look and structure was generated or changed on the fly mimicking the status of a database. - An interpreter in which most of its classes and methods were automatically ge…

I have implemented pretty much all of that in C++. It wasn’t hard or tedious. Using declarative data structure to runtime generate the UI from (for example) is something I do all the time. In C++, C# and Typescript. And evaluating expressions at runtime is just using an AST. Something I have also done a lot.

The GUI application was particularly elegant because the program would detect the changes in the database, change the class structure and attributes of screens and widgets at runtime with all runtime instances being updated. Note that this was written decades ago, way before people got excited at Swift UI, Qt QML or Javascript web apps.

As for "just using AST", it is tedious to me, that's why I don't bother with it in other languages, and judging by the code that I've seen, it is for the average programmer as well.

Re: Understanding the Power of Lisp (2020)

#126
post #106

Earlier quoted context omitted.

> In ruby your lower level API should support... Assume, for purposes of the exercise that someone else wrote some of the methods you're calling and they do not behave this way. You could write your own wrappers, but that's a lot more code to write and maintain than a simple control structure that doesn't care what's inside it.

Submit a patch to get them implemented, or really just don't throw in cases that aren't actually exceptional and return nil instead.

I think this makes my point perfectly.

With macros, I can write a short macro regardless of how the upstream code behaves. Without macros, I can request a change to the upstream code and hope the maintainer will agree to make it behave how I want.

Re: Understanding the Power of Lisp (2020)

#127

Earlier quoted context omitted.

I'm happy to chat more if it's helpful (contact details in profile). I'll be honest that I didn't get Lisp for a long time, and stilll wouldn't claim true expertise. I attempted SICP a few times based on the glowing reviews from folks I admire. One of my paths to tech was via Paul Graham's writings, so I had a bias for Lisp early on. Two parts here. First, and briefly a note on short circuiting and lazy evaluation. S…

> homoiconicity... is simultaneously very prosaic and very deep That's what drives me on. That and Rich Hickey's enthusiasm and the sense that he knows something really valuable that I don't. I watch a lot of videos as well, so I can't remember who said that programming languages were user interfaces between human and machine and are an attempt to talk to machines to get them to do things. In that sense, programming…

Homoiconicity is neat, but I think the real nice thing is the S-expressions and general lack of special keywords. It makes it easy to take a chunk of code in your source file and seamlessly send it to the REPL and have it work.

Compared to Elixir (another language I like) - it is homoiconic but it doesn't have this feature. I can't, for example, take an arbitrary function definition and update or define it in the REPL - because all functions must be defined in a module. However, I like these modules because I think it helps enable discovery of functions - it's much easier to find all operations you can do on lists or maps in Elixir than Clojure.

Also, I wouldn't necessarily call macros more powerful than functions. They're just different, and they enable different things. You cannot, for example, pass a macro around like you can a function. Personally I've never written them, but I use them every day because the core library defines macros. I view them as ways to let people smarter than me to give me tools I can use to write my programs.

As far as driving you on, I don't think Clojure is the end-all be-all language. I happen to like it. I also like Elixir. I know people who really love other, more standard languages though. I don't think you need to force yourself to love or "get" Clojure, but playing around with it can expand your mind a bit, especially if you've never used an FP before.

But if you want an FP that (IMHO) would be easier to transition to, Erlang was the first FP that I "got", afterwhich I tried Clojure again. The syntax is a lot more like traditional imperative programs which can ease the transition. Nowadays I would recommend Elixir over Erlang for several reasons: more modern with modern tooling, less syntax quirks, more active online community, lots of active development.

For me, the main benefits of Clojure are (other FP languages have some of these too):

1. Sharable, immutable state as the default.

2. A set of higher order functions that can do all sorts of data transformation.

3. Being able to use the same language on the web in client + server (without having to use Javascript).

4. Clojure gives me the ability to, more than other languages I've used, target the level of abstraction that I need for the problem at hand, which removes a lot of cruft.

5. Lack of special syntax: helps enable REPL driven development, makes it easier to seamlessly adopt new features from other languages.

6. It's hosted on two ecosystems I'm very familiar with - Java and Javascript.

Re: Understanding the Power of Lisp (2020)

#128
post #126

Earlier quoted context omitted.

Submit a patch to get them implemented, or really just don't throw in cases that aren't actually exceptional and return nil instead.

I think this makes my point perfectly. With macros, I can write a short macro regardless of how the upstream code behaves. Without macros, I can request a change to the upstream code and hope the maintainer will agree to make it behave how I want.

You can get macros out of rust or julia or other languages other than LISP as well.

It is also arguable that overuse of macros leads to less readable code since you wind up inventing your own personal language the more you do it, which requires more of a learning curve to work on it.

There's a large advantage to sticking with verbose idioms that are common and built out of a relatively few building blocks rather than building a meta-language which is terse.

At the same time I'm not saying don't have macros, but they should really be reserved for more extensive heavy lifting, not a pile of tiny ones used all over the codebase to make it terse.

A well written codebase should read more like Hemmingway at an 8th grade reading level using simple constructs from the base language which are put together, generally using programming design idioms which are common and terminology which everyone shares. There shouldn't be a lot of "what does this macro do and where it is it defined?" questions on every other line.

Re: Understanding the Power of Lisp (2020)

#129

Earlier quoted context omitted.

I have implemented pretty much all of that in C++. It wasn’t hard or tedious. Using declarative data structure to runtime generate the UI from (for example) is something I do all the time. In C++, C# and Typescript. And evaluating expressions at runtime is just using an AST. Something I have also done a lot.

The GUI application was particularly elegant because the program would detect the changes in the database, change the class structure and attributes of screens and widgets at runtime with all runtime instances being updated. Note that this was written decades ago, way before people got excited at Swift UI, Qt QML or Javascript web apps. As for "just using AST", it is tedious to me, that's why I don't bother with it i…

Yep nothing that I haven’t done in other languages. I learned Typescript and wrote a 52 page business application from scratch in a few months using the declarative approach. I used JSON to declare everything the same way you would declare it in Lisp and had all the same advantages. Parsing JSON in Typescript is a single line of code. The same as calling read in Lisp.

And a college of mine took the application and easily made a version for another customer in less than a day. Changing most of the 52 pages to match the other customer. The look, the page layout, some of the logic etc. He never looked at the source code.

And mind you I have written my own Lisp dialects just for fun, and have written code in Common Lisp and Scheme. I like the simplicity of Lisp the same way that I like the simplicity of Forth. But I just prefer other languages. Not having types is tedious to me.

Re: Understanding the Power of Lisp (2020)

#130
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…

This story is a fabrication. Please tell John that we're worried about him.
Post reply on HN