Two Vexing Problems in Functional Programming
141–150 of 217 posts
Re: Two Vexing Problems in Functional Programming
#142Earlier quoted context omitted.
But it's a pain to write out assembly, so we go via LLVM and SSA. In SSA, rather than modelling your program using 16 mutable registers (imperative folk love talking about "the real world" or "real computer"), we use an infinite number of immutable registers. Infinite registers won't fit in a computer (we only have 16), and not being able to overwrite registers must kill performance right?
I'm not sure what your point is. Yes, it is possible to build "functional" layers of abstraction on top of real hardware. The hardware itself is not "functional", that's why you need layers of abstraction.
I'm pointing out that this is a terrible argument and needs to die: "It is not the way computers work at a hardware level"
> it is possible to build "functional" layers of abstraction on top of real hardware.
It's not just possible; I don't see any alternatives gaining traction anytime soon.
Re: Two Vexing Problems in Functional Programming
#143Earlier quoted context omitted.
immutability is amazing. you can make assumptions about the data that you have received, it's friendly to caching, it's friendly to crashes, it's very easy to reason about. it's even more amazing when you enter a territory of multithreading/multi processor.
But the real world is mutable. The authors example of a GUI program is a good one: the user wants to change the state of the program, and expects the new state to be reflected in the GUI. You can model this in fp, but it feels like I'm standing on my head. The user wants to modify a glyph, and the program should modify that glyph. It's the simplest way of modeling what is happening.
if you believe in super-determinism and that everything progresses based on predetermined laws you can take the view that space+time already exists in all its past and future and that nothing happens.
or, quantum mechanics in the multiple world interpretations. you can say that the state of the world literally splits whenever there is an event.
i guess the metapoint here is that just because something seems mutable does not mean it’s really mutable and that mutable and immutable only make sense at certain levels of matter organization (are atoms mutable? what about photons? what about quarks?)
Re: Two Vexing Problems in Functional Programming
#144> To be clear, there’s nothing inherently superior about functional programming. (Despite the fact that these self-contained functions are also known as pure functions.) It is not the way computers work at a hardware level. Hah. Weird way of approaching it but okay. Here's the thing: it is exactly how computers work at hardware level. If you look at an electronic circuit you and a program written in a function…
That works for simple circuits. Actual computers have oodles of state - we usually call it "main memory". Assembly is a language that can only do one thing: mutate this state.
Re: Two Vexing Problems in Functional Programming
#145Then, I think there are two different aspects of the problem:
- There is the identity of each object in your program (e.g. a key, reference or pointer), regardless of its value.
- And there are the versions of values each object has / had.
Imperative tracks identities but no versions while functional tracks versions but no identities. Ideally the program would run in a VCS so that one could track both versions and identities.
Re: Two Vexing Problems in Functional Programming
#146Earlier quoted context omitted.
Ok, let's get specific. Here is an STM function: orElse :: STM a -> STM a -> STM a It returns the first argument if there isn't any synchronicity problem, or the second if some other execution line conflicts with the first. What exactly do you mean by "same input -> same output" and how exactly does a programmer thinks about that function on this way when composing it into an STM interpreter?
I was referring to the ST monad which bts and travisathougies were talking about, not STM. I mean that when you run ST code twice with the same input, you will get the same output. E.g., if I write (runST f) + (runST f), that's the same as 2 * (runST f), etc. As for thinking, it means I don't use step-through debuggers ever, because I don't need the whole program to be in a certain state to watch what happens. I just…
None of what I said applies to ST.
Re: Two Vexing Problems in Functional Programming
#147> Functional programming, however, suggests we should create and destroy these structures willy-nilly. It really saddens me that some people completely miss the point of what FP is about. How did this happen?
Two reasons: 1) Uncle Bob's "perpetual state of immaturity" [1] 2) Non-FP languages and "hybrid" languages do a bad enough job of FP to stop people from seeking out more. E.g. FP lang: Doesn't have null. Uses Maybe in the rare cases its useful. The benefit is not having null . Imp lang: Keeps null. Adds Optional so now there's two ways not to have a value. FP lang: Functions are lambdas are first class. Imp lang: Sep…
Re: Two Vexing Problems in Functional Programming
#148I think there might also be another idea to avoid too heavy updating in case of the many many functional updates to the 30K data, but it depends on how Archetype works and what it does. It might be possible to not apply some updates immediately, but group them together with other updates or simplify multiple subsequent updates into one update in clever ways. This might be difficult to implement though and as I said, might not be appropriate for all situations, as you might want to give immediate feedback in the GUI for any change.
Re: Two Vexing Problems in Functional Programming
#149Earlier quoted context omitted.
> you want to modify a list - how do you know if the inner list changed or not You know for sure that inner list did _not_ change, because it is immutable. Someone else might have a reference to an updated hashtable with an updated inner list, but the one you hold will never change—isn’t that the whole idea of immutable data structures?
No, I mean "update" in the persistent sense - create a new list, with some (or none) elements changed/added/removed. e.g. say you have a method remove_all_in_values that takes an int x and a hashmap of list of int, and returns a new hashmap of list of int, with x removed from each element of the hashmap. Obviously you'd use something like List.filter for the inner operation, but most functional programming languages…
Re: Two Vexing Problems in Functional Programming
#150Earlier quoted context omitted.
That's fine from a philosophical sense, but doesn't it make consecutive reads extremely heavy? You're throwing away the efficiency of in place updates at the language level, no?
This is why Clojure’s big thing is to also, at the language level, emphasize copy-on-write data structures.
The thing about copy-on-write is that it's only a good solution when writes are infrequent. My sense is that Clojure largely deals with this by simply not targeting business domains where frequent writes to mutable data structures are particularly necessary.
Which hints at my own opinion on how to deal with this Gordian knot: just acknowledge that there is no universally best programming paradigm. Some problems are, as a practical matter, best modeled in an imperative manner. That's fine. And I don't think it should be personally threatening to us fans of functional programming. John Backus openly discussed it in the paper where he originally proposed the paradigm, and I personally prefer, for moral reasons, his suggestion for how to solve it. In a world where everyone's trying to build the best spork, I think I'd rather have one good spoon and one good fork.