4 ms·
> FP doesn't mirror how the actual machine instructions work, whereas imperative languages do. Can you explain what FP concepts don't "mirror how the actual ma
by tom_mellior 7y ago
> FP doesn't mirror how the actual machine instructions work, whereas imperative languages do.
Can you explain what FP concepts don't "mirror how the actual machine instructions work"? Arithmetic maps to arithmetic instructions. Calls map to calls or jumps, which are well-supported by hardware. If statements map to conditional jumps. Pattern matching maps to something like switch statements (plus extra jumps), which are not hardware features, but they aren't hardware features in imperative languages either. What else? Oh, you don't write "malloc" or "new" to allocate memory (which, again, don't map directly to individual machine instructions). That's about it, I think. What am I missing?
- kstenerud 7y agoGenerators don't mirror the hardware. They are higher order tricks with hidden costs that can bite you if you're not careful. Lazy evaluation is a convenience that is dangerous to think of as free, as is recursion. Code-as-data limits the kind of addressing that can be used in the chip itself. There are mitigations for 95% of cases, of course, and nothing's stopping you from changing the algorithm entirely or parallelizing or whatever. I'm not saying that FP is a dead end. What I'm saying is that it comes with a cost in that you end up limiting your options if you hit a roadblock, because you can't just modify the imperative path due to the higher order functionality you're relying on. FP is very powerful, but that power doesn't come for free. For real-world applictions, a mixed approach will work best for most things.
- tom_mellior 7y ago> Generators don't mirror the hardware. You mean like this? #include <stdio.h> #include <stdlib.h> struct generator_state { int next_value; int limit; }; struct generator_state *enum_from_to(int from, int to) { struct generator_state *generator = malloc(sizeof *generator); generator->next_value = from; generator->limit = to; return generator; } int has_next(struct generator_state *state) { return state->next_value <= state->limit; } int next(struct generator_state *state) { return state->next_value++; } int main(void) { printf("try to enumerate from 1 to 10\n"); struct generator_state *generator = enum_from_to(1, 10); while (has_next(generator)) { printf("%d\n", next(generator)); } return 0; } Oh no! Imperative programming doesn't mirror the hardware! > Lazy evaluation is a convenience that is dangerous to think of as free So your problem isn't really FP, it's Haskell? > as is recursion It's dangerous to think of any computation as free, so... OK. > Code-as-data limits the kind of addressing that can be used in the chip itself. I don't know what you mean here, but "code as data" isn't a universal feature of FP languages. Even in Lisp it's essentially a compile-time abstraction for macro expansion, you don't massage your function definitions at runtime. And once your code is compiled to machine code, what exactly is the problem with using all of the chip's addressing modes? Maybe by "code as data" you mean "first-class functions", i.e., that you can have pointers to code that you can store in data structures? I'll spare you the C example of function pointers because we've established above that C is a terrible language that doesn't map nicely to the hardware ;-) Maybe it's Pascal you want!