5 ms·
The difficult part is controlling complexity, which is where powerful tools such as Lisp really shine. Unfortunately, powerful tools also means custom solution
by codr7 6y ago
The difficult part is controlling complexity, which is where powerful tools such as Lisp really shine.
Unfortunately, powerful tools also means custom solutions which doesn't work that well in large teams.
- mac01021 6y agoIf your abstractions are good, why would they not be easily useable by other people?
- dunefox 6y agoExactly. I never understood the "Lisp curse". Every language allows one to write overly complicated, bad code. Lisp just makes it easier due to homoiconicity and macros - but nothing is keeping a company from conducting code reviews and having code standards, like for every other language.
- sbergot 6y agobecause Lisp allows you to define language-level abstractions that affects the control flow. Those "abstractions" are always leaky and everyone has to understand their implementation to be able to work with them or read code that uses them. Other language limit what you can do with abstraction. You get libraries with less nice api's but you have less digging to do to understand a piece of code that make use of them.
- TeMPOraL 6y agoDisagree. "Control flow-affecting" abstractions aren't really anything special or extra difficult. You always have to understand what the arguments of a function/macro call mean. And random macros don't just randomly leak project-wide control flow decisions.
- aidenn0 6y agoInversion of control is used on large teams and at it's best it is IMO more leaky and harder to understand than well written control-flow macros in lisp.
- codr7 6y agoBecause they're custom, and given enough people on a team everyone has to deal with lots of custom abstractions. I'm not talking about adding a WHILE-loop, it's really the least interesting use of macros from my perspective.
- foldr 6y agoI would take compile-time type checking over any of Lisp's features for controlling complexity in large projects.
- cb321 6y agoIt sounds like you might enjoy https://nim-lang.org https://nim-lang.org if you do not already know about it.
- ragnese 6y agoOnly if it's useful compile-time type checking. Unlike Java and C.
- foldr 6y agoI don't find compile-time type checking useless in either of those languages. It's relatively verbose, given the lack of type inference, but it still catches lots of errors at compile time that would otherwise be runtime errors.
- pmoriarty 6y agoYou don't have to give up Lisp's features to get compile-time type checking, as there are Lisps that have it.
- foldr 6y agoKind of. SBCL will flag type errors at compile time if it can find them, but there isn't any practical way (that I'm aware of) to force it to accept only code that has sufficient type annotations that it can be shown to be type correct at compile time. Racket has typed racket, but then you are getting into pretty obscure territory. You might be able to have strict standards for your own code, but you'll still be plugging in to a dynamically typed ecosystem.
- dunefox 6y agoThere's Coalton: https://github.com/stylewarning/coalton https://github.com/stylewarning/coalton
- sbergot 6y agoYou comment is interesting. In the first sentence Lisp is a good solution against complexity. In the second one it is not. A good litmus test for complexity is the following: as a developer analysing software in order to understand & modify it, how many lines of code do I have to read in order to grasp what is going on and what can I do to solve my problem? In my opinion this is the main goal of a good software architecture. The advantage of lisp is that I can create a DSL like library that precisely describe my domain. The issue is that because macros can have dramatic effects on the final program, I have to check carefully all of them in order to understand a piece of code. This and the inability to look up quickly what fields are inside an object or the exact api of a function. A common base language and static types are the best tools I know to create useful boundaries. Another way is to split the software but this comes with other issues. The use of the term "powerful" might be a bit misleading. Powerful is good. Here powerful refers to "easy metaprogramming". Metaprogramming is something you need in an ecosystem, but you need to hide it a bit so that you only use it when you really need it. I find the lisp community a little bit too proud of their metaprogramming capabilities.
- evdubs 6y ago> The issue is that because macros can have dramatic effects on the final program, I have to check carefully all of them in order to understand a piece of code. Do you have an example where you had to carefully check a macro when writing your Lisp code? I have never looked into macro code more closely than function code when writing Racket programs, and mostly I don't know or care if whatever I am calling is a macro or a function. > This and the inability to look up quickly what fields are inside an object or the exact api of a function. At least within Clojure and Racket, you have IDEs like Cursive and DrRacket that will show you function documentation and do code completion. Or are you saying that the presence of macros alters this somehow?
- pmoriarty 6y ago"how many lines of code do I have to read in order to grasp what is going on and what can I do to solve my problem?" I'm not sure that lines of code alone are that useful here, or APL would be everyone's idea of a perfect language, since it can express so much in so few lines. The Lisp community in particular seems to value verbosity over terseness, preferring long, descriptive function names and variable names, which make for more lines of code, but arguably greater readability. I personally value clear code far higher than terse or clever code. I'd much rather read over a page of easily understandable code in 5 minutes than puzzle over a single line that does the same exact thing for an hour.
- ddragon 6y agoI have doubts that the powerful tools that Lisp provides don't work in large teams. OOP was declared the default abstraction for managing software in large teams but there were still a lot of unmanageable code, but still people kept using it and pooling their experiences, creating innumerous design patterns to handle each limitation, and through "natural" selection the do and don't of OOP became more and more clear. Lisp on the other side not only had less of that collective experience due to becoming less popular, but it was also famous as the language that gives super powers allowing programmers to do 10x more, so the experience was also biased for single dev performance. The Lisp Curse is a cultural problem, not a technological one, you don't need to reinvent stuff just because it is easy (and fun). I'm optimistic though since the new generation of languages (closure, elixir, julia, nim, rust) is increasingly going against the rooted belief in OOP (stuff like inheritance) and incorporating more Lisp features like macros, code as data and everything as expression. This means more and more large dev groups will have access to the tools and reason to make it scalable in order to get a little of that super power under control.