Haskell is the "Periodic Table of Computation". You really can't advance to "organic chem" levels of complexity without first mapping out the elements and their key properties, and then further super-specializing in the structures of Carbon. Haskell's C/H/N/O is functor/applicative/monad/arrow and these are the elements of data/interpreters/evaluators/compilers. Software engineering is still in the alchemy stage – thousands of king-funded charlatans attempting to transmute lead into gold
Great analogy. Poetical. Actually your first version (before editing) was more poetical but I understand that many of us may be too biased to find it funny: "king-funded javascript charlatans attempting to transmute lead into gold."
I appreciate a good JavaScript dig every time. But in fairness, when I was trying to learn FRP (functional reactive programming, different from React), JavaScript was the only other language where I could find some interesting FRP libraries. There's definitely a lot of exciting JavaScript libraries (and more likely to have documentation than Haskell) you just won't find them used in big corporations.
What was most helpful was the tutorials and explanations these projects had. Haskell projects, if they have documentation at all, are often written for other Haskell users, and so hard for me to understand as a novice.
These JavaScript projects had a unique perspective and a unique way of explaining FRP concepts I found helpful.
Then why is actual "organic chem" level of complexity (running bio-chemical simulations in Python, C, C++, Fortran, Matlab, Julia, Rust, ...) simulated in different programming languages?
My question is partly serious, as I would imagine a superior programming language to find applications across multiple domains (and Haskell is mostly just used in the Parser/Compiler and web service industry).
Interestingly enough, a professor of organic chemistry[1] created a new Common Lisp implementation[2] just so that, among other things, he can use a very high level functional(ish) language in his research. His CL implementation is specifically designed to allow more seamless interoperability with libraries written in C and C++.
I think you've basically hit on the reason: chemistry is hard! Organic chemists would get nowhere if they had to do everything from scratch, deducing the behavior of large complicated hydrocarbons by applying quantum mechanics to the individual atoms. Instead they can just say "I know how benzene behaves", "I know that alcohols act this way", etc. Similarly, when coding, it's nice to have a lot of concepts baked into the language in the form you're going to use them in rather than have to reconstruct them from scratch. For instance, Haskell supports something resembling structs with named fields via "optics" (lenses). But it's a lot to wrap your brain around compared to opening a python repl and typing "x.attr".
Haskell supports structs with named fields out of the box in the form of records.
data Foo = Foo { attr :: Integer, attr2 :: Integer }
printSomeNumbers = do
let x = Foo { attr = 3, attr2 = 4 }
print (attr x)
let y = x { attr = 7 }
print (attr x)
It's true that the formatting is different, but given the rest of the language that's not really a problem. What is a problem is how ugly nested record updates are:
data Bar = Bar { attr3 :: Integer, foo :: Foo }
setTheThing x i = x { foo = (foo x) { attr = i }}
That's... not great, is it? And as you get deeper it gets worse, and it can actually get less efficient to as you keep diving down through structures to grab the pieces you need to reconstruct the unchanged parts of your new copy of the record.
So it's not about "x.attr", but "x.attr.field = 7" and friends.
i didn’t say haskell should be used commercially; imo it should not. I say commercial projects would benefit greatly from a study of computational structure and that is equivalent to a study of Haskell (given that it is exactly a catalogue of computational structure). That knowledge can then inform commercial practices.
Hmmm. Nice metaphor but it actually doesn’t work. Many of the properties of complex molecules, esp organic ones, are not computable from their atomic structures with current knowledge/computational power. If they were, we wouldn’t need a whole lot of experimental chemistry.
evaluator is superclass of both interpreter and compiler. monad is interpreter only - as it essentially models continuations, you cannot know what a monadic computation will do without running it whereas compilers are static analysis transforms over a static AST data structure. monad : dynamic :: applicative : static. dynamic means control flow (continuations being the foundational control flow primitive that can express all others aka imperative programming); static means declarative, it’s a data structure (no control flow) which can be inspected and statically analysed and decomposed into components then reassembled, all without evaluating it. applicative permits zero cost abstractions where a declarative high level abstraction is compiled into a target implementation and baked such that the abstraction has no runtime cost. because it has no control flow, applicative also captures parallelism - a data transform can be massively parallelized because there is no control flow / dynamic runtime state to coordinate.
> you cannot know what a monadic computation will do without running it
This is not unique to monads. You cannot in general know what any computation will do without running it. That's the halting problem. Even compilers are subject to this if you have a sufficiently expressive type system (or macros).
Huh??? The Wikipedia article on declarative programming [1] lists functional programming as a sub-paradigm of declarative programming, and Haskell and Scheme as examples of functional languages. But Haskell and Scheme are obviously Turing-complete.
arrows generalize function composition and capture the essence of a DAG which is a foundational primitive in compilers with applications in garbage collection, structured concurrency and reactive programming