Hacker News new | ask | show | jobs
by Tcepsa 937 days ago
I think in some ways functional programming is easier to understand conceptually; it's a closer match to how I think about things. Like if I want to transform an array, I don't think "I want to create a new, empty array and then loop over the first array and call a function on each value and put the result in the new array", I think "I want to run this function on all the values in this array" (same for filter, same for find...). Reduce is a bit trickier, perhaps, but if you start with the example of finding the sum of all the values in an array that probably lays a decently intuitive foundation for it as well.

So yeah, I don't consider myself a particularly math-y person, but I find functional programming to be a more straightforward and less fiddly way of going from a design in my head to something the computer can execute.

1 comments

> I want to run this function on all the values in this array

I think most people get lost on the "run this function".

My impression from high school math classes is that very few people understand the concept of a function in abstract terms. Like, they will learn that sin(90) = 1, because it's a particular, specific function, but they don't understand functions as "first class citizens" in the sense of "apply this function to this array". That seems like a new plane of abstraction to which many never get.

Hmm,that could be--I've been doing this long enough that I've probably forgotten some of the things I struggled with. It feels like it would work to say, "Here's this graph of a sine curve, and what that means is if you take a value you want to find the sin of on the X axis, and trace upwards until you get to the line, and then over to the Y axis, that's the sin of that X value [draw a couple of examples] and if you have a bunch of X values that you want to calculate the sin of, you can put them in an array A and use A.map(sin) and the result will be a new array with the corresponding sin values [draw input array A with the same values as the Xs selected on the graph, A.map(sin), and a new array with the corresponding Y values as from the graph]"

Sure, it won't work for everyone, but I'm guessing (hoping?) that "functions as first class citizens" won't seem that weird to people who have never worked with a language where they weren't

I think the hard part is trying to imagine 'run' combined with 'function'. If you present a picture of a collection of data, a function that maps input values to outputs, and a picture of the output collection of data, that's fairly easy to grasp. The difficulty comes from bothering to describe how the computer does it by running a first-class function on the data. And that's the part of understanding that could be delayed IMO. Treat more of programming as declarative rather than procedural.
> If you present a picture of a collection of data, a function that maps input values to outputs, and a picture of the output collection of data, that's fairly easy to grasp. The difficulty comes from bothering to describe how the computer does it by running a first-class function on the data

I think your describing the solution to the problem: this is how (pure) functions are introduced in high school or university, and that's also what they fundamentally are defined like!

Of course no function in a computer program is really a black-box, but introducing

  f: A -> B
as a black-box gets you far enough for all practical purposes! Defining the properties of a mathematical function and the related categories of injective, surjective and bijective maps between sets is all one needs to know about a (pure) function.

And when it comes to e.g. f(x)=sin(x), how many programmers or high school students could write down an algorithm to calculate e.g. sin(1/4) out of their head?

I know it's a long-solved basic algebra question, but treating functions as black-boxes can be perfectly fine.

When it comes to programming, of course, shared mutable state (i.e. lexical scoping) and how actual functions in some language relate to these concepts is the meat of the problem.

But even this space can be explored without knowing complex FP concepts. And JS is a great language to do so :)

Any JS programmer learns about the difference between a pure function and an impure "function" in some intuitive fashion sooner or later, because lexical scoping is so much at the heart of the language.

So much that day-to-day work can even include a fair amount of shifting around logic between shared mutable state, function parameters and captured closures.