Personally I feel like the gap between Haskell and Lisp is measured less in productivity (the way the gap between X and Lisp is for most Xs) but instead in comprehension and robustness. The code I write in Haskell might be only marginally easier to write than the similar lisp code, but it comes with much nicer, more sustainable structure and 60% of my unit tests for free.
Frankly, I'm starting to feel very strongly that static typing in and of itself makes you much more productive -- in the long run. Not so much because you write stuff faster, but because you spend less time patching it up.
Both of those examples obviously have very little to do with the quality of the language used, and everything to do with the ecosystems that were built around them.
Also... I was not meaning to make an argument to the quality of the languages. If anything, my argument is admittedly about the ecosystems garnered by the different types of languages.
The problem with these massive ecosystems of dynamic code extensions is that when you layer leaky abstraction on top of leaky abstraction, each layer being broken in its own subtle ways, the end result is a ticking time bomb waiting to cost its users thousands or millions of dollars in lost productivity. Your example of JavaScript in web browsers is a perfect demonstration of this.
We are the only engineering discipline where there are a significant number of people who actually think extensibility is more important than stability or robustness. Imagine a civil engineer pooh-poohing the stability of the bridge he's building, pointing instead to how easy it is to add additional lanes. Imagine a mechanical engineer decrying running a formal analysis of a new design for a car, saying "forget about that, look at how easily customers can plug in custom dashboard attachments!" This is lunacy, plain and simple.
This reeks of what I have seen as a common attitude among software developers where we make sweeping statements about other professions with little to back it up.
I will not claim that extensibility is the be all end all attribute. I will claim that it is a valuable attribute. More so for some applications than others.
Similarly, I will make the same claim for formal checked programs. In some fields/industries, why wouldn't this be the norm?
So, if the claim is that static typing can make for a more completely specified application and that we should demand that for some fields. I agree.
If the claim is that static programming is superior to dynamic, I take issue.
"If the claim is that static programming is superior to dynamic, I take issue."
I think this would benefit from a little more clarity about what you mean when you say "static programming" versus "dynamic programming" - I'm sure you don't mean "Dynamic Programming".
If you mean static types, then I think that they are a tremendous win wherever they apply, and I think that sufficiently sophisticated type systems exist that they can apply most places. Trying to express meaningful constraints in a brain dead type system is awkward and you wind up moving between over- and under-constraining yourself - though I've been surprised at what I can express in C (with zero runtime overhead) with a little creativity.
If "static programming" is taken to mean "compiled, with runtime compilation of additional code made difficult to impossible", which often correlates with "statically typed" in existing languages but is technologically orthogonal, then I agree that this kind of "static programming" is not uniformly superior.
Yeah, apologies. I did not mean "dynamic programming." I thought the context made what I meant fairly clear, though.
If you have any examples that show how this is technically orthogonal, I'm all ears. Hence my request for examples of things that are as extensible as emacs.
And to be clear, my understanding is that ghc is actually fairly extensible. I would love if there were more examples. Preferably in more approachable domains than compilers.
'Yeah, apologies. I did not mean "dynamic programming." I thought the context made what I meant fairly clear, though.'
No worries - as I said, I'd understood that didn't mean "dynamic programming".
"If you have any examples that show how this is technically orthogonal, I'm all ears. Hence my request for examples of things that are as extensible as emacs."
Well, Typed Racket would presumably be one example. More generally, as a theoretical proof, one could bundle the entire compiler into the runtime and link in arbitrary new code.
"And to be clear, my understanding is that ghc is actually fairly extensible. I would love if there were more examples. Preferably in more approachable domains than compilers."
I'm not aware of it being exceptionally easy to write plugins for GHC compared to other compilers - it has incorporated a lot of extensions to the Haskell language but that's not the same as a plugin ecosystem (which might itself exist - just "I'm not aware"). It certainly has a plugin interface, but so does GCC. As GHC it itself implemented in Haskell, a lot of pieces of it are also available as libraries.
There are no non-leaky abstractions outside of toy applications. Extensibility is the unique strength of software. Otherwise you might as well do it with hardware. Other disciplines are (more) limited by their physical constraints. If air-tight abstractions could solve everything machines could do the programming and there wouldn't be much need for human programmers.
Well it is pretty self-evident that non-leaky abstractions don't exist -- or I haven't really seen one in all these years. Take functions in functional programming: if tail recursion matters that is one leak; if strict or lazy evaluation matters that is another leak; if you want to share intermediate results well that springs a big leak; etc. Engineering is about trade-offs. We are there to judge what matters to us and therefore "leaks" and abstract away details that may not matter to us (at the level we are working on). Yes fundamentally I do see this as the barrier to complete automation.
I don't think XMonad is a poster child for advertising how great (read: awkward) haskell is for runtime extensibility. Sure it does the job, but it's based on a giant hack (invoking the compiler on your configuration, forking a new process, etc.), this is pretty specific to xmonad and is non-trivial, so you can't easily reproduce this kind of extensibility for other applications. It's completely different to the kind of extensibility offered by something like emacs/lisp, which is done purely in the runtime and doesn't require transferring some state to a new process.
I'm pretty sure behemoths like NetBeans and Eclipse rate pretty damn high on extensibility.
Anyhow, you don't have to take an all-or-nothing approach. It's pretty common to write game engines in C++ and then use a dynamic language to provide game-specific scripting on top (e.g. World of Warcraft uses Lua for the UI, Civilization V uses Python for most of the non-engine stuff). Also, Photoshop has javascript builtin.
MS Windows and a lot of Windows applications are extensible via COM. The core of COM is a dynamic cast at runtime to a static interface. You see something similar in a lot of Go code. For me this is the right balance. Static types but extremely late binding. Or static types, dynamic dependencies.
They are high, no doubt. In my view they still fall well short of the heights that emacs reaches.
Take a look at skewer-mode for emacs sometime, and realize that is less than 1.5k lines of javascript and elisp.
I was also avoiding the approach of bundling in specially crafted hooks for extensions. If anything, that really just kind of makes my point. That for some things there is a highly perceived benefit to dynamic languages. (And yes, the converse is true.)
You're not going to get concrete comparable examples because Haskell has not had enough adoption and resources thrown at it to be able to compare it in this way. What I can do is point you at another comment I wrote about this the other day and the responses it got.
I've not done extensive development in any lisp, so I'm not able to make a robust comparison. There are clearly ways in which Haskell leads to more productivity (static typing when sufficiently expressive is a tremendous win), and some ways in which LISP has an advantage. It sounds plausible to me that it's a wash; something other than a wash is marginally more likely, but I'm not confident about which direction it would go.
Makes sense. I think that mirrors my view, mostly. I have lately begun to fall on the side of lisp more so than haskel. Sadly, I can not really give a good reasoning as to why.
I can say that finally going through SICP has been borderline mind blowing. It is hilarious/sad/crazy to see how many hot topics today were covered in a bloody introduction textbook from the 90s.
Are there things in haskel that would make you recommend it over lisps?