Live data from Hacker News

Why I still Lisp

mendhekar.medium.com

61–70 of 240 posts

Re: Why I still Lisp

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

> If value is not a numeric type, square is not going to be happy.

That is not necessarily true. In Common Lisp, with its generic-function based object system, you can extend the operation of any function at any time to cover new types. So, for example, one could define a method for SQUARE that operates on matrices.

> What thing that violates a type check would be "perfectly fine to do"?

(define (self-apply fn) (fn fn))

Re: Why I still Lisp

#62

In other words, static typing is pointless. It has, maybe, some documentary value, but it does not substitute documentation on other invariants. 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]”. The rest of y…

You can express those invariants using dependent types. Look at something like Lean.

Re: Why I still Lisp

#63
post #48
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"? A typical example, in dynamic programming languages, is to treat numbers as strings and vice-versa; evaluate lists in boolean context; and so on. > If value is not a numeric type, square is not going to be happy. And that's the case with most (all?) dynamic code. Some programming languages will be glad to accept a string and treat it as a number…

that sounds really awful, not "fine."

Re: Why I still Lisp

#64

I've installed portacle, and ended up in a nest of errors I didn't understand. Can anyone here recommend a non-editor based version of lisp?

what is a editor based version of Lisp?

fwiw, I really like Racket. It's definitely the most clean/elegant Lisp around.

Re: Why I still Lisp

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

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. And they're right to love it! Purely anecdotal, but I can accomplish more faster (from a clean slate) with a dynamic language like Python than I can with Haskell, Go, or Rust. The difference is small, but non-negligible.

But static typing has a few key benefits:

* No searching through comments for type constraints.

* Better autocompletion.

* Better compilation.

* Better serialization/deserialization.

I do think static typing pays for itself in the long term. Sometimes, we shouldn't care about that. Engineering means managing tradeoffs: short-term velocity vs long-term performance and maintainability?

Re: Why I still Lisp

#67
post #21

The author of the article, Anurag Mendhekar, is one of the authors in the original paper on AspectJ [1], which introduced Aspect-Oriented Programming. The origins of AOP are in Smalltalk and the Meta-Object Protocol, I think. I really liked Aspect-Oriented Programming, despite its great issues with mutually interfering aspects etc. I wonder if it will make it as a big paradigm, but I hope it does. [1] https://www.cs.…

I have used aspectj in somewhat unhealthy dose in my project. Mostly for reasons not even intended as an use to aspect. We have to work on giant configs reified as giant java objects. And I have was able to collect enough metadata about the code using aspects and keep them tied to the live objects in such a way that I was able to simulate creation, transformation and move of method calls.

yes, a byte code parser and reflection might have achieved the same, but the library made it breezy. Maybe, java is not a hacker's language but ecosystem comes with hackers toolbox.

Re: Why I still Lisp

#68

Earlier quoted context omitted.

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

When would shadow binding help create more readable code? (I agree with everything else in your post)

I think it would do that, if in the inner scope, you only need a part of something from the outer scope. Lets say you have a list of things and they have the name according to what they are, lets use "things" as a placeholder. Then in the inner scope, you are still working with "things", just not all of the outer scope, but for reading the code of the inner scope, it does not matter. You are still working with "things". OK, this is quite abstract. I am thinking about it in something like nested named lets, where you make a functional update to something, that comes from the outer named let, inside the inner named let and then use it as an argument to a procedure call. Situations like that. And perhaps only, when it is difficult to name this subset of things anything else than the original name. If there is easily available another fitting name, then I would always go for that.

It does make renaming things harder though.

Re: Why I still Lisp

#69
post #43
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…

Honestly I’ve seen just as many disastrous codebases written in highly structured, statically typed languages. Any language with intrinsically interesting features tends to attract inexperienced (or just bad) developers who don’t appreciate the tradeoffs of their tools and design decisions, and think the tool is a panacea. This leads to disastrous codebases, and is not at all limited to lisps or dynamically typed lan…

The question isn't whether it is possible to write shitty code in a given language. Every language can be used to write shitty code.

The issue is, given a person that knows the language does not know how to structure their code, what is likely going to be the outcome with regards to maintainability.

My production experience is mostly with C, C++, Python and Java.

As an example, consider typical Java backend application. Even novice developers would typically learn Spring and create applications that contain controllers, views, repositories, services, etc.

They (I mean novice developers) would be constantly repeating rules they don't know why they are following, but heard it is important or seen it as popular. So maybe things like you should have your objects accept injected dependencies.

It does not mean they will know how to use these or even that they will use these productively to create more readable code, but what this does is creates code that has at least some structure.

The code might have huge amount of duplication and redundant or unnecessary constructs, but you will be able to move around, understand what you are looking at (okay, this is controller so I know how this most likely works, this is database layer so I know what I can expect, etc.)

On the other hand Clojure imposes exactly ZERO structure on your application. That is powerful but only if you know how to structure the application yourself, know what kind of choices you need to make and know ins and outs of various options.

If you have no experience creating structure, have been Java dev all your life and have always relied on structure that was given to you and never thought about it until today, you are likely to produce absolutely unmaintainable mess that nobody is going to be able to figure out.

Re: Why I still Lisp

#70
post #11

> 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). This is the static vs dynamic type debate in a nutshell. Personally I think Typescript hits a sweet spot of static typing by default with an escape hatch (via the `any` type) when you need it. I think more self-documenting code makes the trade…

In that debate, we quite often hear something along the lines of "I can't remember the last time a static typechecker actually helped me" and that makes me imagine a fish saying they can't remember the last time that water actually helped them. Maybe the ambient help is so constant that it no longer even registers in long-term memory.
Post reply on HN