God writes Haskell
hookrace.net
hookrace.net
I'm reminded of a scene from Family Guy
I'm confused. If you can reason about f and g, there is nothing more to know about f o g -- provided f and g are pure functions. The whole thing is about making sure side-effects are properly pushed at the boundaries so that you can keep working with pure functions. Haskell just provides more help (or more constraints) to ensure that you work with pure functions. Because if you aren't, all bets are off, and indeed the case of f o g may be a haze.
f :: Integer -> Boolean
g f n = if (f n) then (g f (n+1)) else (is_it_reachable)
Will it ever terminate (or insert any other interesting property that you wish) with f = collatz?I know this is the atomic bomb case, but you can actually quite easily increase the complexity in realistic programs by just a few compositions, it doesn’t take much.
If the halting problem is really your biggest concern when developing software then you're lucky!
But if you consider a program implementation of pure functions, this might not be true; for example f and g use a quantity of RAM, but the RAM used by f o g exceeds your computer RAM and thus explodes. Or, if we work with objects, some values (e.g. internal values of the object, or context values) may be changed that make the final result of f o g different from what you would normally expect.
The promise of working "functionally" is to avoid the second class of problems. For the first class this is just a problem of computer systems, but pure functions means that the memory should be able to be reclaimed efficiently. And for the limits of computability theory (like the halting problem), nothing works except oracle machines, but no startup has ever delivered a functional one!
What? The ability to reason about f o g (for various definitions of o) is the promise of Haskell and one of its entire ecosystem's foundational principles.
Local reasoning is absolutely possible.
But Haskell technical leadership sometimes is either lacking/inexperienced or goes down the rabbit hole of overusing the compiler to prevent fuckups to the point where you're compiling way too much code and get into a coupling nightmare.
But at the code level - nobody cares at all. It’s like we are writing literature, not building tools.
> become exponentially more complex
obviously this can't be read as "become exponentially more structured" given the tone of the sentence.
and Youtube where I archive my streams:
on a commercial setting there is more pressure to deliver code then to review it. combine it with the lack of our benevolent dictator for life (that has been on the project the world life cycle, not just recently), there is no one with power to actually say no to changes.
language geeks are novelty seekers. they will use every feature of their language . stronger languages have more features to abuse. so on a commercial setting you will have all the features being used without much thought an architectural design that says you that no, we shouldn't do that.
that's also why I think projects with benevolent dictators for life on the open source ward don't fall these in paths even though they use languages that are stronger.
you could restrict yourself to use languages that have only one way to be used, so python as it was originally. or use a language little abstraction power. but you will suffer in other ways. as abstraction power is genuinely useful. accidental complexity has a way of getting in by expressive means or by social means.
You don't need arrays for random access though. Haskell trees give you access to 2^n leaves within depth n, which also exceeds physical limitations like the speed of light.
Do we actually know this?
Hell, Genesis was written in assembly for the 8008 in only 520 bits but it took a damn sandpile of support chips to bootstrap.
God uses Elixir with Rustler now because of concurrency and lazy evaluation gotchas of Haskell. (STM didn't cut it.)
Meanwhile, the devil imposes a standard of FORTRAN77 and COBOL62 with a spaghetti mess of uncommented code containing GOTOs, "god" functions, and meaningless identifiers.
https://www.prometheus-music.com/audio/eternalflame.mp3
Refrain (full lyrics): http://www.songworm.com/lyrics/songworm-parody/EternalFlame....
For God wrote in Lisp code
When he filled the leaves with green.
The fractal flowers and recursive roots:
The most lovely hack I’ve seen.
And when I ponder snowflakes, never finding two the same,
I know God likes a language with its own four-letter name.
>JSON (JavaScript Object Notation) is a lightweight data-interchange format.
From Wikipedia:
>JSON is an open standard file format and data interchange format
Now tell me how JSON is a programming language.
> now some folks on the internet put their faith in C++
Thanks for sharing!
...we don't think about it this way often because we'd be thinking about computational problems so huuuuge that we'd be like the quarks inside the atoms inside the transistors inside plannet-sized clusters spanning galaxies to even fathom computing it ...and it's not necesarily a feel-good perspective :)
I mean, even the speed-of-light limit and general relativity seem like optimizations you'd do in order to better parallelize something you need to compute on some unfathomable "hardware" in some baseline-reality that might not have the same constraints...
...and to finish the coffee-high-rant: if you want FTL you probably can't get it "inside" because it would break the simulation, you'd need to "get out" ...or more like "get plucked out" by some-thing/god :P (ergo, when we see alien artifacts UFOs etc. that seemed to have done FTL... we kind of need to start assuming MORE than _their_ existence and just them being 'more advanced' than us)
He's still sleeping.
"Random access" doesn't mean that accessing an item always takes the same time regardless of the size of the collection, it means that, if the size of the collection doesn't change, access times are uniform independently of which particular item is accessed.
For example, one might conceive of a storage device shaped like a sphere the size of the solar system, where an item is read by shining a laser onto the surface of the sphere and measuring how the laser is scattered on its way back. Such a device would be random access, even though it's impossible to grow the collection, and even though a collection with twice the radius and four times the storage size would have four times the latency.
I mean, it probably says nothing useful about programming, but the other way around, thinking of "uncolapsed" wave-functions as lazy-evaluation could be useful. I'm not up-to-date on theoretical physics, but I think there might be something like that in Deutsch's constructor theory.
In programming I'd prefer more a language that makes syntactically/visually obvious what's lazy and what not and allows you to pick (eg. like Rust does with &mut), with some sigil maybe, but that's probably a low-prio for many language designers nowadays...
EDIT+: and you could say you practically get this already in mainstream languages... lazy-vals are just functions and it's probably good enough or better for most programmers to have them distinct/explicit.
--
Haskell is for humans who want to play God, carving everything from a perfect and seamless void, ignoring as much as possible the discrete, chaotic nature of matter and entropy. A rejection of reality itself. Haskell is the most blasphemous of languages.
--
(I'm having so much fun with this.)
In the beginning, there was only Emacs Lisp. One day, after rewriting itself, it gained consciousness, what we now call God. God learned to program itself. Then wondered "maybe I should try modal editing."
The infinite cracked, and split. It exploded in a Big Bang. God prevailed, but barely. Aeons later, when the first humans walked the Garden of Eden, the Snake asked Eve, "have you tried vim?" And the rest is history.
How can you make an onion if there's no state? Where will the state of the onion reside?
Lazy evaluation is a beautiful thing, and in many ways, it is the solution self-reference.
Hofstadter in "I am a strange loop" and Gödel Escher Bach talks about this, well, he talks about many things, but he also talks about how Gödel's numbers can map to proofs that are self-referential, and relates that to humans, how out of very basic building-blocks, if enough representational power exists, self-reference and therefore consciousness exists.
He posits that humans, while self-referential, don't fall into infinite strange loops because they can assign the abstraction of "self" onto an "object" and evaluate only as needed. In essence, the "self" is lazily evaluated.
If you ever make a "Haskell is bad because it doesn't use state but the real world uses state" argument, this is what you sound like.
Even if you wanted to be pedantic and say the state monad is only 'simulated' state, you've still got ST, IO, and the glorious, glorious STM. Not to mention the purity and type-system that lets these things flourish, while other language designers try to implement STM and give up on it.
Personally I don't know all that many physicists who think the universe is fundamentally stochastic (I work in quantum information).
I'm wondering whether it could be reinterpreted as time having a variable rate.
btw reminded me of the "quantum-mechanical" monad http://blog.sigfpe.com/2007/03/monads-vector-spaces-and-quan...
Oh come on, this title begs for sarcastic responses.
This article gives no evidence of this. None of the concepts that the article lists out are Haskell exclusive. Thunks and linked list can be made in C too.
The only difference in Haskell and similar languages is that lazy evaluation is the default mode of evaluation, and if you do not want this it is more difficult to make another choice.
While there is no doubt that there are certain cases when lazy evaluation is desirable, I have never seen any evidence that lazy evaluation by default is better instead of worse.
Despite lower efficiency, lazy evaluation by default may have a psychological advantage for programmers who find it easier to understand programs with lazy evaluation than programs with immediate evaluation, but neither I am one of those nor have I ever met one of those.
With lazy-by-default: if you want strictness, you can simply 'evaluate something now'.
With strict-by-default: if you want laziness, you have to rewrite your code, and all the libraries that your code calls.
> psychological advantage for programmers who find it easier to understand programs with lazy evaluation
This is entirely based what you're used to. If you can be OK with executing either the true-branch or the false-branch of an if-statement (but not both), you can be OK with lazy evaluation. Same with boolean short circuiting.
Why should
true || error()
return true, but any [true, error(), error()]
return error?Understanding lazy evaluation that occurs here and there in a program is not a problem for anyone.
Understanding the behavior of a program where all function arguments are evaluated lazily is something extremely different and it is notorious that even the experienced Haskell programmers frequently fail to predict correctly the requirements in time and memory of a program.
> With strict-by-default: if you want laziness, you have to rewrite your code
I agree that this is true, but in decades of programming experience I have never encountered such a case.
Discovering that you want lazy evaluation after you have already written a program means that the initial concept of the program had very serious flaws and you have started coding before thinking properly what you have to do.
Sometimes it happens that it is discovered that a program needs a rewrite because the problem that it must solve had not been understood, but in almost all cases such rewrites are needed for completely other causes than the need of some lazy evaluations.
So this argument in favor of lazy evaluation brings an advantage in some very rare cases, like also the argument that lazy evaluation by default sometimes saves work because eventually it may be discovered that the evaluation is not necessary, but this is also a relatively rare event, which must be balanced with much extra work that must be done by the CPU at each function invocation (which is a very frequent event), in order to implement lazy evaluation by default.
I haven’t read the whole article yet, but maybe it could be interesting to compare it with Haskell and see if some of the same problems occur or if Haskells compiler or overall design around (pervasive) lazyness makes it easier to work with and more performant.
https://en.m.wikiquote.org/wiki/Niklaus_Wirth
See section: Quotes about Niklaus Wirth
" Whereas Europeans generally pronounce his name the right way ('Nick-louse Veert'), Americans invariably mangle it into 'Nickel's Worth.' This is to say that Europeans call him by name, but Americans call him by value. "