4 ms·
Given the comment section is devoted to definitions, I'll add mine: the single most important characteristic of proper FP is _strictly segregated side effects_.
by vemv 8y ago
Given the comment section is devoted to definitions, I'll add mine: the single most important characteristic of proper FP is _strictly segregated side effects_.
At a high level, many e.g. Clojure programs are indistinguishable from an OOP program. Functional composition and immutability are just superficial details - another 'skin' containing the same stuff.
Does it really matter if you expressed something as a `for` or as a `reduce`? Is local mutability distinguishable from immutability?
Worth noting, real OOP webapps do very little in-process mutability. They're 'functional': request in, response out. State actually lives in Redis/Postgres so the actual mutability story is the same for FP and OOP langs.
That's not to say this functional-ish style is wrong or wasteful. It's a nice step forward. But we really ought to appreciate "strictly segregated side effects", namely actually pure functions, without exceptions.
There's no such enforcement in a great deal of FP langs, and IMO there really should be (at least in the form of a lightweight linter) if we want FP to be genuinely superior.
- elcritch 8y ago> the single most important characteristic of proper FP is _strictly segregated side effects_. This is one of the best definitions I've come across.
- kazinator 8y agoIf we have pure funtions, that is not "strictly segregated side effects"; pure functions do not have side effects, period. We can segregate side effects very well in imperative code. The segregation of side effects is clearer in a strictly evaluated imperative language than in a lazily evaluated functional language.
- kazinator 8y agoThe single most important characteristic of functional programming is that all control flow routing is done by function calls. Functional programming can include side effects. This is still basically functional: 1> (let ((cntr 0)) (list (mapcar (lambda (x) (inc cntr) (* x x)) '(1 2 3)) cntr)) ((1 4 9) 3) Just not "purely functional". Functional means we work mostly by applying arguments to functions, and avoiding loops, ifs and gotos in favor of canned mapping operations that work with sequences and such. If an assignment sneaks in here and there, it's still functional. (if antecedent consequent alternative) is not functional because control flow is being diverted by a special operator without the use of functions. But if we have a function iff: (iff f-antecedent f-consequent f-alternative) such that iff will call the f-antecedent function and then either call f-consequent or f-alternative based on what f-antecedent returns, then that is functional. Functional just means "obsessed with functions"; without further qualification, it has nothing to do with purity. That's just certain politico-religious camps trying to hijack the word for their own agenda.
- imtringued 8y agoThe reason why purity ([0]) falls flat is because the pure approach only handles 90% of the problems efficiently. The remaining 10% will take more effort so you do not actually see a 90% reduction in cognitive burden but perhaps a 70% reduction. If there is an escape hatch for the remaining 10% of problems the cognitive burden would be reduced by the full 90%. But purists don't like escape hatches, because they think all the benefits of purity are gone, because it's an all or nothing thing (it isn't). [0] It doesn't really matter what type of purity we are talking about here. Whether it's about pure functions as in FP or Rust code that never depends on unsafe code.