The top comment on YouTube raises a valid point: > I've programmed both functional and non-functional (not necessarily OO) programming languages for ~2 decades now. This misses the point. Even if functional programming helps you reason about ADTs and data flow, monads, etc, it has the opposite effect for helping you reason about what the machine is doing. You have no control over execution, memory layout, garbage col…
> FP will always occupy a niche because of where it sits in the abstraction hierarchy At some point in history, people stopped worrying about not understanding compilers, how they allocate registers and handle loops and do low-level optimizations. The compilers (and languages like C or C++) became good enough (or even better than humans in many cases) in optimizing code. The same happened with managed memory and data…
Why Isn't Functional Programming the Norm? [video]
381–390 of 417 posts
Re: Why Isn't Functional Programming the Norm? [video]
#382OOP was designed to prioritize encapsulation at the expense of referential transparency. Functional programming was designed to prioritize referential transparency at the expense of encapsulation. You cannot have referential transparency and encapsulation at the same time. In order to prevent mutations (which is a requirement of FP), a module cannot hold any state internally; this necessarily means that the state mus…
" the more interchangeable the components will be. It's like Lego blocks; " This is precisely the reason why pure FP is prioritizing referential transparency. Even if objects are perfectly encapsulated, with enough complexity, because other objects will depend on that information, and because that information mutates and changes over time, this is bound to cause some errors. Compilers can't check program correctness…
I would argue that when other objects from different parts of the code depend on the same state and there is no clear hierarchy or data flow direction between those objects, then that is going to cause problems regardless of whether the language is OOP or FP. The problems will manifest themselves in different ways but it will be messy and difficult to debug in either case (FP or OOP) because this is an architectural problem and not a programming problem. It will require a refactoring.
OOP helps to reduce architectural problems like this because it encourages developers to break logic up into modules which have distinct, non-overlapping concerns.
Re: Why Isn't Functional Programming the Norm? [video]
#383I have one compute device, the GPU, that I program with its language (eg GLSL, OpenCL).
I have another compute device, the CPU, that I program with its language (eg C, C++).
I have code to control these devices, that mostly handles scheduling and waiting on the results of these computations (as well as network traffic and user input), and I program that in a language that supports functional style (eg C#, TypeScript).
Re: Why Isn't Functional Programming the Norm? [video]
#384Earlier quoted context omitted.
Never written even a simple C compiler, but I, and most c++ programmers that care about performance I think, do have a decent idea what code g++ is going to generate.
But g++ is probably better than you at producing fast code for whatever architecture you run it on.
Re: Why Isn't Functional Programming the Norm? [video]
#385Earlier quoted context omitted.
Personally, I get frustrated that there seems to be a belief that you can only use FP or OOP, when the reality is both models can be used in conjunction, and there may be reasons to choose one over the other dependent on what you are doing. Not to mention there are other models such as Protocol Oriented Programming. You see this in languages like Swift.
The issues is that you get benefits for sticking to one paradigm, because then everything is made of the same stuff. If everything is an object, then you can use all your tooling that works with objects, which is everything. If everything is pure, you get easy parallelism. If everything is an actor, you get easy distributability. If everything is a monad or function, you get easy compositionality. The list goes on. S…
Re: Why Isn't Functional Programming the Norm? [video]
#386Earlier quoted context omitted.
Yes, and this is one of the areas where functional programming really shines. An imperative program is defined as a series of ordered steps and the compiler can't (in general) reorder steps to optimize use of resources because the steps could have arbitrary side-effects.[1] The FP version is essentially a dependency graph which constrains the order of operations without mandating a specific final order. The pre-heate…
> the compiler can't (in general) reorder steps to optimize use of resources i'm not sure what you mean by that because compilers reorder instructions to improve performance all the time (and CPUs do it dynamically too).
But that doesn't really happen in reality. FP languages promised auto-parallelisation for decades and never delivered. Plus you can get it in imperative languages too - like with Java's parallel streams. But I never see a parallel stream in real use.
Re: Why Isn't Functional Programming the Norm? [video]
#387Earlier quoted context omitted.
Yes, and this is one of the areas where functional programming really shines. An imperative program is defined as a series of ordered steps and the compiler can't (in general) reorder steps to optimize use of resources because the steps could have arbitrary side-effects.[1] The FP version is essentially a dependency graph which constrains the order of operations without mandating a specific final order. The pre-heate…
> the compiler can't (in general) reorder steps to optimize use of resources i'm not sure what you mean by that because compilers reorder instructions to improve performance all the time (and CPUs do it dynamically too).
The kind of reordering you see in imperative programs tends to be on the small scale, affecting only nearby primitive operations within a single thread. You don't generally see imperative compilers automatically farming out large sections of the program onto separate threads to be evaluated in parallel. That is something that only really becomes practical when you can be sure that the evaluation of one part won't affect any other part, i.e. in a language with referential transparency.
Re: Why Isn't Functional Programming the Norm? [video]
#388Earlier quoted context omitted.
You may want to consider Ramda.js instead: https://ramdajs.com/ IMHO does a better job than Lodash, because: 1. All functions are automatically curried. 2. The order of parameters lends itself to composition. EDIT: 3. Transducers.
I never understood the point of Ramda. It's like it's trying to replace the core functionality of JS with something that's completely orthogonal to what the language actually is, but it's just a bolted on library. I've worked on codebases where people ignore all built-in JS functions (like Array.map/filter) and write Ramda spaghetti instead with multiple nested pipes and lens and what not to show off their FP purism.…
It’s nice to be able to make a function as concisely as something like:
Const foo_finder = R.find( R.propEq( ‘prop’, ‘foo’ ) )
...
Const a_foo = foo_finder( a_list )
Re: Why Isn't Functional Programming the Norm? [video]
#389Earlier quoted context omitted.
Yes they are documented, though the documentation is really something like "-fawesome-optimization, enabled by default on -O3" and the "-fawesome-optimization" has documentation like "enables awesome optimization" without explaining much more than that. And even then pretty much every project out there uses "-Ofast" instead of whatever "-Ofast" enables without caring about what it does or how its behavior will change…
-Ofast enables fast-math optimizations and generally is not standard compliant. I hope projects do not deliberately enable it without thinking (as they say, it is hard to make stuff fool proof because fools are so resourceful).
For example according to the documentation in GCC 7.4 -O3 turns on:
-fgcse-after-reload
-finline-functions
-fipa-cp-clone
-fpeel-loops
-fpredictive-commoning
-fsplit-paths
-ftree-loop-distribute-patterns
-ftree-loop-vectorize
-ftree-partial-pre
-ftree-slp-vectorize
-funswitch-loops
-fvect-cost-model
whereas in GCC 9.2 -O3 turns the above, plus: -floop-interchange
-floop-unroll-and-jam
-ftree-loop-distribution
-fversion-loops-for-strides
So unless you control the exact version of the compiler that will generate the binaries you will give out, you do not exactly know what specifying "-O3" will do.Moreover even though you do know the switches, their documentation is basically nothing. For a random example what "-floop-unroll-and-jam" does? The GCC 9.2 documentation combines it with "-ftree-loop-linear", "-floop-interchange", "-floop-strip-mine" and "-floop-block" and all it says is:
> Perform loop nest optimizations. Same as -floop-nest-optimize. To use this code transformation, GCC has to be configured with --with-isl to enable the Graphite loop transformation infrastructure.
...what does that even mean? What sort of effect will those transformations have on the code? Why are they all jumbled in one explanation? Are they exactly the same? Why does it say that they are the same "-floop-nest-optimize"? Which option is the same? All of them? The -"floop-nest-optimize" documentation says:
> Enable the isl based loop nest optimizer. This is a generic loop nest optimizer based on the Pluto optimization algorithms. It calculates a loop structure optimized for data-locality and parallelism. This option is experimental.
Based on the Pluto optimization algorithms? Even assuming that this refers to "PLUTO - An automatic parallelizer and locality optimizer for affine loop nests" (this is a guess, no other references in the GCC documentation as far as i can tell), does it mean they are the same as the the code in pluto, that they based on the code and are modified or that they are based on the general idea/concepts/algorithms?
--
So it isn't really a surprise that most people simple throw out "-Ofast" (or -O3 or -O2 or whatever) and hope for the best. They do not know better and they cannot know better since their compiler doesn't provide them any further information. And this is where all the FUD and fear about C's undefined behavior comes - people not knowing what exactly happens because they are not even told.
Re: Why Isn't Functional Programming the Norm? [video]
#390Earlier quoted context omitted.
> the compiler can't (in general) reorder steps to optimize use of resources i'm not sure what you mean by that because compilers reorder instructions to improve performance all the time (and CPUs do it dynamically too).
Compilers and CPUs only reorder over tiny instruction windows. He's talking about re-orderings over enormous windows, in a way that requires whole program analysis. But that doesn't really happen in reality. FP languages promised auto-parallelisation for decades and never delivered. Plus you can get it in imperative languages too - like with Java's parallel streams. But I never see a parallel stream in real use.
EDIT: An example of effective parallelism in Haskell:
import Control.Parallel (par)
fib n
| n = 15 = b `par` a `seq` a + b
| True = a + b
where a = fib (n-2); b = fib (n-1)
main = print $ map fib [0..39]
Note that the implementation of `fib` has been deliberately pessimized to simulate an expensive computation. The only difference from the non-parallel version is the use of `par` and `seq` to hint that the two operands should be evaluated in parallel when n >= 15. These hints cannot change the result, only the evaluation strategy. Compile and link with "-threaded -with-rtsopts=-N" and this will automatically take advantage of multiple cores. (1C=9.9s elapsed; 2C=5.4s; 3C=4s; 4C=3.5s)