Live data from Hacker News

Why I still Lisp

mendhekar.medium.com

201–210 of 240 posts

Re: Why I still Lisp

#201
post #71

Earlier quoted context omitted.

I spent a lot of time thinking about this. What makes Perl or Clojure such fun languages to work with is they don't impose structure on you. You can do whatever the hell you want. On the other hand result of this is the code represents basically how you think about the problem. Which would be very different for every person. Languages with frameworks like Java+Spring, Ruby+Rails etc. are less "fun" to work with becau…

Yes, frameworks are kind of like a smarter programmer starting you off with a code base already, so if you don't really know what you're doing you can't mess it up as much. I've still seen people mess it up, and generally it's when the developers begin to "play" with things they don't understand, like bringing in Aspect J, writing custom annotations, slowly moving logic to configuration files, starting to dynamically…

> mess it up [...] like bringing in Aspect J

And, see? That's from a Lisp guy. QED.

Re: Why I still Lisp

#202
post #8

I think Lisp is going to live forever as a niche tool for people who "get" it. I use Clojure on a daily basis. Not necessarily because it is best Lisp, but rather because I am working with Java applications and being able to reuse the same Java code I have already developed is a huge boon to me. If I was able to choose, I would be using Common Lisp. The way I use it is to quickly develop adhoc tools and PoCs and more…

> This underlines the fact that Lisp projects can very easily end in spectacular disasters. This is not specific to Lisp, it happens to all dynamically typed languages. And this is why "holding invariants in my head" doesn't scale. Your objects have a type. Why not put it in the code and ask the compiler to verify it, so that future developers on that code (including yourself) will have an easier time reading it and…

Common Lisp allows to annotate code with type information, which can be checked at runtime. Also it's object system works on classes and thus generic function have arguments for those classes.

Something like Common Lisp is a dynamically typed language, but where implementations can use knowledge about types, either at runtime or even sometimes at compile time.

SBCL

  * (defvar *foo*)       ; a global variable *FOO*
  *FOO*
We tell SBCL that the type of the variable is an integer between 0 and 10.

  * (declaim (type (integer 0 10) *foo*))
  (*FOO*)
Now we try to set it to 30:

  * (setf *foo* 30)
SBCL detects the problem:

; in: SETF FOO ; (SETF FOO 30) ; --> SETQ ; ==> ; (THE (MOD 11) 30) ; ; caught WARNING: ; Constant 30 conflicts with its asserted type (MOD 11). ; See also: ; The SBCL Manual, Node "Handling of Types"

Re: Why I still Lisp

#203

Can someone please recommend a situation or common daily task that I can deal with using some version of lisp, in order to learn it little by little without forcing me to learn it all upfront and it is not just emacs? Like a shell replacement? Or some configuration manager? Or how do people actually learn lisp if it is not their job?

Perhaps Babashka[0]? It sounds like the closest thing to what you want =)...

Alternatively you could just use cursive[1] or vscode[2] and follow the REPL guide[3]?

There's Racket, which has it's own built in environment[4].

Perhaps you'd prefer Common Lisp[5] instead, I don't believe you need to use emacs?

There are options =)...

- [0]: https://github.com/babashka/babashka

- [1]: https://cursive-ide.com/

- [2]: https://marketplace.visualstudio.com/items?itemName=betterth...

- [3]: https://clojure.org/guides/repl/introduction

- [4]: https://docs.racket-lang.org/quick/

- [5]: http://www.gigamonkeys.com/book/

Re: Why I still Lisp

#204
post #38
post #17

> I have never had a static type checker (regardless of how sophisticated it is) help me prevent anything more than an obvious error (which should be caught in testing anyway). Obvious in retrospect is not the same as obvious. And such errors happen all the time, the same way without syntax checks typos happen all the time. And "caught in testing" is 2 extra steps removed from caught immediately by the syntax checker…

> What thing that violates a type check would be "perfectly fine to do"? One good example is where you might treat records or "product types" as maps Let's say you want to write a function that can capitalize all the string fields in the object passed in. In a dynamic language, you could map over the values and apply capitalization trivially. It would be a one-liner. In a static language, you'd have a few options, bu…

> In reality, you probably wouldn't even try to write such a function in a typed language because of how awkward it is.

In reality, you probably wouldn't because of how contrived and completely removed from any conceivably realistic practical goal this example is. In what situation would I actually need to solve this problem for every type in my program?

Re: Why I still Lisp

#205

> Languages based on the λ-calculus make it really easy to “play back the code” in your head. This really depends on the expression.. I've seen behemoth expressions such that you have no choice but write down intermediate results, or start explicitly breaking it down into sub-bindings so you could step through the code. And yes, you can usually step through subexpressions in the debugger, but if you have to debug any…

> I also noticed there is a tendency in lispy languages to avoid introducing variable bindings just for the sake of naming the subexpression, because it often comes with a `(let ((name (subexpression))) rest-of-code)`, which also results in extra tabulation for the rest of the body. Compare with variable introduction in languages like python/js/c++/rust, etc., where such thing wouldn't cause touching the rest of the…

I just stop myself when I detect tab-driven development. Readability and function have to trump aesthetic concerns about indentation level.

Re: Why I still Lisp

#206
post #14

Earlier quoted context omitted.

Have you looked at Nubank? Largest neobank in the world by users and valuation, it's a clojure shop to such an extent they literally bought Cognitect No affiliation, just a satisfied customer

There are examples of successful companies using any programming language. It doesn’t prove anything about the quality of the language. The world still succcesfully runs on COBOL. That is not a good enough reason to pick COBOL for your next project.

The difference here is that Nubank attributes part of their success to the use of Clojure.

Re: Why I still Lisp

#207

Lots of articles like this out there about Lisp. To quote Linus Thorvalds: > Talk is cheap, show me the code If you think you can write better code in Lisp, well, show us some examples of that.

OK, here's an example: https://cs.brown.edu/~sk/Publications/Papers/Published/fkt-t... In this paper the authors describe how students actually grasped fundamental concepts better in Schema than in Java, despite being taught both throughout the course of the semester.

If they wrote java with closures people would understand it as well. Instead they used more complicated examples for java which skews the results. Example if you translate their lisp example directly.

Their original lisp:

    ( let ([ x 3])
      ( let ([ f ( lambda (y ) (+ x y ))])
        ( let ([ x 5])
          (f 10))))
Java:

   { int x = 3;
     { Function f = y -> y + x;
       { int x = 5;
          { return f.apply(10); }}}}
They argued that Java is less concise so they couldn't have as many examples, but I feel that example gets the point across just as well and it has comparable number of characters.

Re: Why I still Lisp

#208
post #103

Earlier quoted context omitted.

> sinking complexity from a bunch of code Sometimes macros provide domain-level constructs. This creates very dense code - which can improve code understanding. One thing I would recommend to put extra effort into macros, especially with these aspects: One should write documentation what the macro expects and what it does. This way this has not to be inferred from reading the often quite complex code. Document the im…

With those things in place, macros can absolutely be a net positive for code understanding. And if I saw that being done with any regularity at all, that would be great. As I get older and more jaded, though, am coming to think that, in an office setting, it is a mistake to choose a language is optimized for maximizing the effectiveness of a thoughtful programmer. It's much more valuable to minimize the damage that c…

That is exactly what I have realized after decades of work.

There is a cap on how much work you can do individually. There is no cap on how much damage or improvement you can cause to other people you work with.

It does not matter how clever you are with your code if nobody else is going to be able to continue that work or support its results.

For this reasons I have developed following, informal rules I try to follow:

1. It is ok to be clever with the code if I am going to be only one to ever read or use it. This can assumed to be always false for production code. I limit my cleverness to PoCs, adhoc tools and emergencies.

2. Always think how other, and especially junior members of the team are going to develop and support my product. Is it too complex for them to follow? Is there something that can be done so there is less chance they are going to misuse it?

3. I use my cleverness to try to develop simpler and more reliable products. Simplicity is defined by how much work junior member of the team is going to have to expend to understand it. Reliability is defined by how likely it is to fail in face of junior team members operating / developing the piece of code.

4. If team members have trouble understanding or working with my products it is always my fault. Figure out how to make the product simpler or at the very least provide training and ensure they understand how it works.

Re: Why I still Lisp

#209
post #25

> For example, your invariant might be something like I’m expecting here a monotonically increasing array of numbers with a mean value of such and such and a standard deviation of such and such. The best any static type checking will let you do is “array[float]”. Isn't this just plainly false? With dependent type system wouldn't you be able to encode all such invariants into the types? Curry-Howard isomorphism and so…

This is possible to do without dependent types. You could have something like this (using TS syntax):

  function produceComplexArray(arr: array): ComplexArray | null {
    ...
  }

  function consumeComplexArray(arr: ComplexArray) {
    ...
  }
If the only place where you can produce a ComplexArray is produceComplexArray, and produceComplexArray ensures that the arrays it receives are "a monotonically increasing array of numbers with a mean value of such and such and a standard deviation of such and such", then all the functions after produceComplexArray can be assured that they have the right array. Therefore, even with a relatively simple type system, you can ensure this invariant.

I think I got this idea from this article: https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...

Re: Why I still Lisp

#210
post #38

Earlier quoted context omitted.

> What thing that violates a type check would be "perfectly fine to do"? One good example is where you might treat records or "product types" as maps Let's say you want to write a function that can capitalize all the string fields in the object passed in. In a dynamic language, you could map over the values and apply capitalization trivially. It would be a one-liner. In a static language, you'd have a few options, bu…

There is no limit on the number of problems easier to solve using dynamically typed languages. For an individual hacker, dynamically typed languages make a lot of sense. I don't forget what types my functions accept as I am writing a program. All static typing can accomplish is slow me down when I'm trying to bang out something. This is why Python (for instance) is loved by data scientists, researchers, and startups.…

One more that people easily forget. An IDE or LSP can detect much more errors as you type, saving quite a lot of context switch of mind.
Post reply on HN