> 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"? Here is an example limitation of typescript's type system that I routinely run into while developing real code [1]. I look at it like this. If you consider all possible programs, some are invalid, some are valid, and some are valid and useful. A type system's job is to reject as many invalid programs as possible while accepting as many valid pro…
Why I still Lisp
221–230 of 240 posts
Re: Why I still Lisp
#222Earlier quoted context omitted.
Sometimes the type system is forcing you to think in terms of what it is that you are passing around. In this case, getEmails() isn't expecting a group of students or a group of faculty, but rather a group of people that can be emailed. You can introduce an interface of that type and have it inherited by both Student and Faculty and use that in the method for clarity and type-safety without over-relying on union type…
I appreciate the effort you’ve both put in to concrete examples. I think yours gets to a point that I haven’t often seen stated. You’ve named your interface Person, but perhaps even Emailable could serve the purpose. The problem is that you had to name it. Naming well is hard, and I believe strong type systems often create a need for more names. It’s a cost I don’t often see considered in the tradeoff.
function getEmails(group: Array) {
return group.map((p) => p.email)
}
which leaves the function more open ended than relying on an explicitly named interface that other types then have to inherit from.Re: Why I still Lisp
#223Earlier quoted context omitted.
> Most implementations of Common Lisp prevent shadowing builtin symbols. So? Make your own package.
What's your point? In CL it is trivial to determine both at compile and at runtime the package of all symbols involved. Same for generic methods, you can query the runtime which methods it is going to use for some concrete combination of parameters. Much easier than to determine how which overload of a C++ operator does the compiler/linker deem to fit in given context.
> Most implementations of Common Lisp prevent shadowing builtin symbols.
is irrelevant. It's actually irrelevant for two reasons. First, the example under discussion was SQUARE which is not a CL builtin, and second, even if it was, you could just do this:
Just make your own package and do:
(in-package :my-package)
(defmethod square ((n number)) (* n n))
Now you can extend SQUARE to work on things other than numbers. Or, to pick a more realistic example:
(defmethod sqrt ((n number)) (cl:sqrt n))
Re: Why I still Lisp
#224I 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. I've been following HN since 2014 and haven't seen any submission about such a thing. The closest was some article or comment from someone who worked at Cycorp, about some horrors of the legacy code base. Here it is: https://news.ycombinator.com/item?id=21783828 "... the biggest mess I have ever seen by an order of magnitude"…
Re: Why I still Lisp
#225Lots 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.
Re: Why I still Lisp
#226Earlier quoted context omitted.
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.
Any examples of successful large scale production code in LISP? There are many examples of those in Java/C++/...
Re: Why I still Lisp
#227Earlier 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.…
Re: Why I still Lisp
#228Earlier quoted context omitted.
What's your point? In CL it is trivial to determine both at compile and at runtime the package of all symbols involved. Same for generic methods, you can query the runtime which methods it is going to use for some concrete combination of parameters. Much easier than to determine how which overload of a C++ operator does the compiler/linker deem to fit in given context.
My point is that this: > Most implementations of Common Lisp prevent shadowing builtin symbols. is irrelevant. It's actually irrelevant for two reasons. First, the example under discussion was SQUARE which is not a CL builtin, and second, even if it was, you could just do this: Just make your own package and do: (in-package :my-package) (defmethod square ((n number)) (* n n)) Now you can extend SQUARE to work on thin…
Re: Why I still Lisp
#229Earlier quoted context omitted.
I've read a few times that Java and enterprise languages are so horribly tedious for the purpose of slowing down armies of monkeys to avoid catastrophic design. ps: what kind of clojure projects do you have in mind ?
That's a common meme but there's not much evidence for it. Java has the syntax it does because it's based on C++. It is verbose because (a) C++ is verbose and (b) it insists on everything being inside a class. The latter is a reasonable choice given that the underlying VM needs some unit of linkage and scope ... sort of like criticising C and C++ for requiring that everything be inside a function, but there are reaso…
Re: Why I still Lisp
#230Earlier quoted context omitted.
You might be one of those experienced developers who has gone through their entire career without ever meeting a well designed, beautifully architectured application, and therefore concluded, sensibly, that all real-world applications look like shit if you look inside, and you seem to have come to believe that this is the only possible way. I have a different experience. Code that is well designed makes mistakes look…
> a well designed, beautifully architectured application I've seen everything during my career, bad code with lots of bugs, bad code running stable. Nice code full of bugs, and nice stable code. The reason something was stable was never how the code looked, but how battle tested the product was. You will learn, don't worry. Plus, at a certain point, it's about tradoffs and compromises. I would love to see highly opti…
Difficult-to-read code always causes problems, either because it directly causes bugs due to its logic being obfuscated, or because no one can approach it to make necessary modifications when change is invevitably required.
You claim that "The reason something was stable was never how the code looked, but how battle tested the product was". I am claiming that you're wrong and your counter-argument is that I will learn to be like you one day. This shows that you're the one who has to grow up.
I am constantly looking for ways to write code that works in all scenarios, provably. I don't need to battle test code if I can do that. I only need battle tested code in the absence of that property. I will concede that in many occasions, this is all you can get, but that's due to a lack of time and skills, not an inherent property of a system or the process of writing software.
It's sad to see people who gave up on creating good software (because if you only can create reliable software after it's battle tested, that means it was buggy all along before that - so for the majority of the life of your product, your software was buggy - that is not acceptable).
If you believe I am a dreamer, an unexperienced developer, let me prove you wrong. Show me some code you believe it's impossible to make reliable without "battle-testing" it over a decade, and I will show you how.