5 ms·
Why not just use COBOL and Gotos while we’re at it? It was “the right tool for the job” for decades until the OOP religion took over! /in_jest
by epgui 4y ago
Why not just use COBOL and Gotos while we’re at it? It was “the right tool for the job” for decades until the OOP religion took over! /in_jest
- mrkeen 4y agoSure /s. But seriously I dislike the notion that FP is somehow a successor to OOP, like you have to keep piling abstractions onto OOP until it becomes FP! If you do it that way, you end up with map() implementations like: public final <R> Stream<R> map(final Function<? super P_OUT, ? extends R> mapper) { Objects.requireNonNull(mapper); return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { public void accept(P_OUT u) { this.downstream.accept(mapper.apply(u)); } }; } }; } Ain't nobody got time to read that. Step back from OOP before putting in the FP and you can get map() looking like: map _ [] = [] map f (x:xs) = f x : map f xs
- epgui 4y agoPersonally I do see FP as a “successor” to OOP, but not in a strictly constructive or chronological sense. Building FP functionality with classes sounds just as fun as building java classes with assembly.
- _old_dude_ 4y agoThe problem of the Java code above is that it tries to serve many masters, one of them being the JIT, i.e. the code is written that way so the JIT can fully inline the whole code. The first "final", the "StatelessOp", the "StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT", the "int flags" are all here because of performance.
- teh64 4y agoWell your second example relies for speed and efficiency on Haskell being lazy. If you did e.g. a map -> filter -> sum chain, the performance is not that great without lazy evaluation guaranteed by Haskell's implementation, which can complicate code in other scenarios or in the complexity of the compiler. OCaml is also an FP language, and the second example would be almost the same text, but with much worse performance. Also, Python is an OOP language, but a simple map implementation there is not much more verbose: def map(function, items): if len(items) != 0: return [function(items[0]), *map(function, items[1:])] return []
- epgui 4y agoI think the more pythonic way would probably be to use a list comprehension: def map(f, items): return [f(i) for i in items] These differences are all more about specific languages than about FP per se, however.
- teh64 4y agoTrue, but I tried to make it as close to the Haskell example as possible. I just think the OOP -> verbose/complex argument is really annoying, especially if it applies mostly to Java code.
- epgui 4y agoEither way, in both our examples, what we wrote was very much in a functional style, and Haskell also uses list comprehensions. The only thing unique about the Haskell example, I think, was pattern-matching... And while that's nice, you don't really need that for FP.