10 ms·
A different view on Functional Programming
- tzahola 9y agoMost of us spend 90% of our time reading other people’s code. So even though writing a concise and elegant formula in J might be a satisfying puzzle, I personally don’t want to deal with the cognitive burden of point-free style when sifting through my colleagues’ pull requests.
- pimmen 9y agoIn the author's example of the geometric mean, shouldn't the function return an error if any of the numbers were negative? Because the program shouldn't be sending negative numbers to that function to begin with so he/she should maybe get some hint that one of those functions producing said numbers isn't working properly. And if there are no positives, I sure as hell don't want a divide by zero error bringing the program to a complete stop when I could just simply display "Could not calculate geometric mean, check the inputs" to the user.
- wvlia5 9y agoThe functions in the article are not the geometric_mean. They are functions which first filter the list and then take the geometric mean. I only misnamed them that way for the sake of exposition. The only true geometric_mean in there is the J version
- thethirdone 9y agoMinor typo > reduce(lambda b, b: ab, 1, positives) Should be > reduce(lambda a, b: ab, 1, positives)
- wvlia5 9y agoThanks, fixing it :)
- ungzd 9y ago> attempts to reduce programs to equations Logic programming is close to this. In functional programming, left side of equation always consists of dependent variable and nothing more. Logic programming allows to put any variables on both sides of equation.
- jlg23 9y agoI get the idea (doing fp for a living for 15 years) but the article lives in a bubble populated by mathematically pure unicorns: This strength/feature of fp can only weigh in where we have the mathematical formulas, arriving at those is the hard part in most programming jobs - most of the time those who "define" the product/spec cannot even do it in plain English (because they have to make up things as they go, no criticism, just acknowledgement of bizdev-reality).
- maxxxxx 9y agoI always envy people who can work on something that can be expressed with math or some other kind of consistent logic. Most company problems are inherently messy and you just end up with a litany of convoluted code.
- jjaredsimpson 9y agoExample please? Because I'm tempted to respond that there are no inherently messy problems, only insufficient solutions. What problem could possibly exist that only could be implemented in a convoluted way? Sounds more like: me and my team made trade offs that were, in retrospect, bad and now we don't know how to transform our code into a new program will fulfills the same requirements but is easier to inspect and understand.
- dxhdr 9y ago> Because I'm tempted to respond that there are no inherently messy problems, only insufficient solutions. Really? There are entire industries which only work on "messy problems." ie game dev: implement a controller where jumping is both responsive and fun.
- maxxxxx 9y agoIn big companies requirements often change when strategy changes or some top manager has set his mind to something. So you are always behind the curve and you never get a set of stable requirements. Unfortunately that's reality in many companies. I pity people who have to work with SOAP or Salesforce.
- avmich 9y ago((+/) % #) &. ^. is the same as (+/ % #) &. ^. because adverb (/ in this case) binds with + before three verbs +/ , % and # are grouped into the fork. So some parentheses aren't necessary. It would be cleaner to show three expressions which share the common part as similar in letters as well.
- wvlia5 9y agoThanks, fixing it
- kowdermeister 9y agoIs this software? What does it do?
- skybrian 9y agoHave you considered that many people aren't particularly fond of deciphering complicated math equations? For them, your argument is in favor of avoiding functional languages. Too math-like! A step-by-step procedure might be simpler to understand.
- wvlia5 9y agoA good analogy would be music notation (pentagram) I could describe a piece of music in English prose, telling you were to put your fingers and for how long. The language itself would be easier to understand, but the efficiency of information transmission would be very low. Chinese looks complicated, unless you know Chinese. The ultimate criteria to judge a language should be how efficiently (concisely) it expresses the concepts of the subject matter. At most, I will concede you: Goodness_of_language = conciseness × parsing_speed_of_an_experienced_user
- Arainach 9y agoUnderstandability is more important than conciseness in a team environment. In a team, you're not writing code for you - you're writing code to be reviewed by other people, integrated with other people's code, and maintained by other people in the future. In the example from this article, all developers I've ever worked with would understand what the "good old C" example is doing within seconds. Most would understand the Python example. Most of them still working in the industry today would be able to figure out what the functional python code was doing without much excessive effort - it would take them longer, which is bad, but if they were working in it every day I'm willing to believe that they'd parse simple examples like that readily enough. None of them would understand APL. J is even worse. I stared at the J code for a full minute without any comprehension of the language syntax or what was being accomplished. That code isn't readable or maintainable. It is bad code.
- mikebenfield 9y ago> J is even worse. I stared at the J code for a full minute without any comprehension of the language syntax or what was being accomplished. That code isn't readable or maintainable. It is bad code. But why does code need to be readable to someone who doesn't know the language? Yes, it's true that Python and some other languages are pretty readable even to people who haven't written any of that language, and that is a nice feature in many contexts... nevertheless, if I'm hiring a Python programmer, I'm either going to hire someone with experience in Python, or I'm going to accept that they're not going to hit the ground running and be massively productive right out of the gate... so how is it really such a loss to write in J and accept that non-J programmers won't understand my code?
- gt_ 9y agoI am something like an intermediate programmer and this is useful. I want to understand how FP replaces OOP in a similarly concise example. I have a sense that it involves a reconsideration of why OOP is useful, and solving that issue with a widely new approach, but I am not there yet myself. I’d love to see something like these Python comparisons but involving the demolition of an OOP implementation.
- wvlia5 9y agoI'll keep that in mind, thanks
- AlexCoventry 9y agoTry this: https://www.braveclojure.com/multimethods-records-protocols/ https://www.braveclojure.com/multimethods-records-protocols/
- gt_ 9y agoThanks. OK. This gave me a good outline. These ideas were somewhat right under my nose, in some of the Python concepts like closures and decorators. I don't know the languages here quite the same but the possibilities are convincing nonetheless. Hmmm... I could see myself getting carried away with this if I put some time into it.
- dukeflukem 9y agoHaving messed with Haskell I'd say the hidden data in OOP becomes "public" and that data is processed in pipelines. In C# you sometimes objects with just public getters/setters and static methods using linq manipulating those objects. This is kind of a functional style.
- im3w1l 9y agoPython with numpy has a pretty concise solution np.exp(np.mean(np.log(a[a>0])))
- wvlia5 9y agoThat's what the J sample is doing (minus the filtering)
- xixixao 9y agoI wrote my own functional, Haskell-like, language, and after a couple of years and seeing a couple more code bases in various languages, I am now starting to firmly believe that currying should be strictly avoided (or at least highly discouraged). Obscure symbol operators with operator precedence are also a clear readability problem. But unlike what this article suggests, these traits are not essential to functional programming. As long as you stick to functions which given values return other values, and your language has support for passing functions to other functions as well, you can reap most of the benefits of functional programming.
- naasking 9y agoI'm mixed on currying. It really increases expressiveness, but it does allow obscure point-free composition styles that can look like line noise.
- quicksnap 9y agoThis quote made me smile.. Thanks OP! Happy holidays! > Just in case all that wasn’t enough to convince you about the superiority of the functional gospel, take this threat: FP will displace OOP, so start thinking along our lines our you will eventually lose your job
- discreteevent 9y ago"The fact that the functions are collected into records and called methods is irrelevant. As a result, the typical object-oriented program makes far more use of higher-order values than many func- tional programs” - William Cook, On understanding data abstraction revisited. OOP, especially with a focus on immutability, is not that far away from FP. It's not like, say physics where two domains can be conceptually quite different. OOP and FP are just two programming tools meaning that their variation is quite limited by the domain they are in.
- quicksnap 9y agoObjects as a higher-order abstraction, as an encapsulation of data and methods, are all fine and dandy. When I think of OOP, however, I think of deep inheritance. I'm not a great fan of the latter.
- platinumrad 9y agoThat unnecessary addendum made my eyes roll so hard they still haven't recovered eight hours later.
- danidiaz 9y agoOne could also say that functional programming prefers expressions to statements —and treats functions as just another expression. When needed, statement-like things are constructed from expressions. Equations in lambda calculus do seem to have a "preferred direction" specified by the evaluation rules, though referential transparency lets you go "in the other direction" in your head, when reasoning about your program. Perhaps the programs ~ equations idea would apply even better to logic programming, or term rewriting?
- ridiculous_fish 9y agoSay we changed the problem to the geometric mean of non-negative numbers (instead of positive). This allows us to early-out if zero is encountered. It's obvious how to change the imperative code: `if (x[i] == 0) return 0;` What would this optimization look like in APL or J?
- efnx 9y agoI haven’t used APL but it looks like it has list comprehensions, so a simple “x != 0,” would work there
- avmich 9y agoGeometric mean is nth root of product of n numbers. If you replace any of those numbers with 0, it will all collapse to 0 - perhaps not what you want. But it's not hard to write such a program: geometric_mean1 =: (+/ % #) &. (^."1) @: (0&>.) geometric_mean1 2 4 8 4 geometric_mean1 _2 4 8 0 If you want to replace negative numbers with their positive counterparts, you may first replace a number with its absolute value: geometric_mean2 =: (+/ % #) &. (^."1) @: (>. -) geometric_mean2 _2 4 8 4 geometric_mean2 2 4 8 4 Original geometric_mean probably meant to be geometric_mean =: (+/ % #) &. (^."1) - note the copula (assignment symbol) and rank of first verb (^.) .
- draw_down 9y agogeometric_mean1 =: (+/ % #) &. (^."1) @: (0&>.) Just this makes me want to cry. Good lord. Even if you like functional programming why would you want it to look like this?!
- 31reasons 9y agoI think the main feature of Functional programming is not avoiding side effects but abstraction. You can compose different kinds of powerful abstractions and programmers are free to choose their "language" of abstractions, compared to "X Oriented" languages that forces programmer to think in certain terms and limits in ways you can create layers of abstractions.
- Veedrac 9y agoIt should be obvious that if a transformation is syntactically trivial, it can only solve trivial problems. If programming is not-math, it's not going to become math just because you change the surface syntax. A mathematician's definition of a sorted list is different to a programmer's at least in part because a mathematician is interested in a sorted list and a programmer is interested in sorting a list. This difference is intrinsically invariant of the programming paradigm (though not of the context). This issue isn't so much that this post didn't convince me that there is an underlying, semantically relevant sense in which the APL approach is more mathematical, but that it didn't even seem to notice that this was a thing that needed to be argued.
- avmich 9y ago> If programming is not-math Programming is _always_ math; was it Dijkstra who said "programming is one of the hardest branches of applied mathematics"? It's also engineering - as in "engineers have to do some math occasionally, even if they don't realize that". I often ask on the interviews to produce an expression returning sorted 3-element list using some simple primitives. I've found that with chosen primitives you still can model different approaches - and even though in all cases the result is an expression ("sorted list is..."), the structure of that expression can model imperative style ("first do this, then this...")
- Veedrac 9y agoOn one hand, yes. On the other, classifying whether programming is a math or not doesn't help you decide whether you should use APL, or much else for that matter.
- twic 9y ago“Well, that’s supposedly functional code, and it still doesn’t look like an equation” – I can hear you say It does, we only need to change the syntax (semantics will stay the same), and the underlying mathematical structure will flourish before your eyes. Hold on. Does this guy think "mathematical" just means "expressed as a string of symbols instead of words"?
- wvlia5 9y agoThere is a J interpreter Android app which works like a charm. I enjoyed solving the Project Euler problem set in it. You might too: http://code.jsoftware.com/wiki/System/Installation http://code.jsoftware.com/wiki/System/Installation
- dahart 9y ago> it’s usually defined by some of its features, such as: reification of functions, avoidance or banning of functions with side-effects, use of higher-order functions and so on. But, doesn’t that sound like a collection of random features? What’s the motivation behind them? It's a bummer to pose that question as though there isn't an answer, when the answer is well known and very important. The motivation of avoiding side effects is because we humans make more mistakes when there are side effects. Functional programming is about making a piece of code not depend on anything outside itself. When you do that, it's easier to get right, and harder to screw up the code. In a word, it's safer. > I’ll present you a view which, at least to me, makes that set of features seem coherent; and functional programming, like a deep and beautiful paradigm: Functional programming attempts to reduce programs to equations. We also make more mistakes when we make things too abstract, remove specificity. Write code that is too concise, and you lose meaning, context, and readability. The "functional python" is the best looking code in the article to my eyes. It explains what it does to the reader, semantically. The APL & J examples aren't very enticing to me. I'm curious about them, but I wouldn't want to work in a codebase where if you don't know what the name of the function means, you can't figure out what it does. Making code mathier is good occasionally, when working on mathy problems, but generally I'd rather have words and const statements in my functional programs than a concise expression with single letter variables.
- SwellJoe 9y ago"The APL & J examples aren't very enticing to me. I'm curious about them, but I wouldn't want to work in a codebase where if you don't know what the name of the function means, you can't figure out what it does." Is it possible that APL and J fail this test only because you (and I) don't know how to read APL or J? I think there are some languages that end up being difficult to read due to failings of the language, but I don't know enough to know if APL or J is among them. Python is, perhaps, more readable than most languages, but I've seen people learning Python have a hard time with many of its choices, so we really have to consider whether we find some version of the code more readable only because we've read a lot more of that kind of code. Most of the time "easy to use" just means "what I'm used to", and I don't think programming languages are an exception to that.
- skywhopper 9y agoThis is an interesting post, and the code sample from APL got my attention. I have questions. How do I learn/get/run APL or J? How do I even type the APL code given? What does the J code even mean? As for the content... "makes code super concise (less room for bugs)" Unfortunately, while this sounds great, it does not logically follow. And while geometric mean is well-defined and understood, most functions I'm probably going to write in whichever language are going to be more complicated and less well-defined. So, how does APL/J/pure-functional help/make my non-trivial code more beautiful/concise/bug-free/provable?
- wvlia5 9y ago>How to type APL characters They are unicode characters. Type them the way you would type any unicode character. If you have not yet found a practical way of doing it, there are plugins for editors to help you type APL characters with no hassle. >How to learn APL? There's a Dyalog APL manual which is quite clear, Google it. Also, you can use the GNU APL interpreter. I would recommend learning APL first, only by reading the Dyalog manual and writing programs with pencil an paper, then learn J in detail. > How do I learn J? Jsoftware provides a free interpreter. They also have a sleek interpreter app for Android. I would recommend to download this app and go through the project Euler problem set. Jsoftware provides all the documentation you will need in their webpage http://code.jsoftware.com/wiki/System/Installation http://code.jsoftware.com/wiki/System/Installation > what good will J do for me? The best would be to learn it and see it for yourself. Sadly, you find yourself in Paul Graham's Blob Paradox.I can't get you out.
- avmich 9y ago>> what good will J do for me? > The best would be to learn it and see it for yourself. I've found the statement on the front page of jsoftware.com to be rather accurate: "If you are interested in programming solutions to challenging data processing problems, then the time you invest in learning J will be well spent." And "data processing problems" could be understood pretty widely. I've had a case when I first spent about 45 minutes producing a prototype (a program which would generate realistic plans for floor of an office building) using J, then converted that prototype in functionally equivalent (no embellishments) program in C# spending a couple of hours. Certainly working on a prototype took several failed attempts, yet it was still faster than doing the same in C# after the algorithm was already clear.
- euske 9y agoI kinda agree with the idea; functional programming turns your program into a series of tubes.
- kortex 9y agoThis is exactly it. I don't write 100% functional code, but when given a possibility of implementing functionality using state vs pure function, I aim for the pure function whenever possible.
- deleted 9y ago[deleted]
- dgreensp 9y agoyou might know that it’s usually defined by some of its features, such as: reification of functions, avoidance or banning of functions with side-effects, use of higher-order functions and so on The "function" in "functional programming" and the "function" in "avoidance or banning of functions with side-effects" are two different words, by the way! FP is named after the math word, not the programming language word, which means different things in different languages but usually means a kind of subroutine. FP means programming in a style that emphasizes composition of mathematical functions, and in an imperative language this generally amounts to writing your subroutines in a certain way. It just so happens that many imperative languages call subroutines "functions."
- d--b 9y agoDeclarative programming is the attempt of reducing programming to equations. Functional programming is a way of organizing code as chains of functions...
- oh-kumudo 9y agoThe example is so simplistic and toy-like that it is not remotely convincing.