Live data from Hacker News

Functional programming jargon in plain English

github.com

81–90 of 191 posts

Re: Functional programming jargon in plain English

#81
post #57

Earlier quoted context omitted.

And precisely because of the code sample, it should be obvious that currying is not the same as variadic function arguments. Instead, it allows for very concise partial function application, as demonstrated by the code. I can just call any function with a subset of its arguments, and it automatically returns a “new function” which you can call with the remainder of the arguments. It allows you to reason about calling…

Saying "it allows for very concise partial function application" does nothing but repeat the definition. It does not, in particular, offer any reason to want that. What is so special about the first argument, that I want to fix it? Why not the third? Why is what I do to fix the third not just as good for the first? Pattern matching is a good example of a language feature included because they could not figure out how…

Currying support is orthogonal to how function arguments work. Some languages (e.g. OCaml according to this question[1]) combine named parameters with currying, allowing partial application with any of the function's arguments.

[1] https://stackoverflow.com/questions/3015019/is-there-a-progr...

Re: Functional programming jargon in plain English

#82

Earlier quoted context omitted.

Mathematicians use "just" with a specific meaning: it is not used to gloss over something that the author doesn't know how to explain. It has a purpose, useful for mathematically trained readers. For suc a reader, "a homomorphism is just a structure preserving map" makes it clear that "homomorphism" and "structure-preserving map" can be used interchangably, and that by understanding one of the concepts, you'll immedi…

Sure, but the title does say plain English so this would be the sort of thing the author is trying to avoid. If that’s the meaning just write all a are b.

While I agree that the English used in the repo could be plainer, that's not remotely the same thing as "using 'just' to gloss over something that the author doesn't know how to explain", which was the complaint that goto11 made.

Re: Functional programming jargon in plain English

#83
post #5
post #3

This is great. Finally understand monads a little better. Definitely saving this for later.

Why do monads come up so often when people talk about FP? Is it a meme or are they really an important and difficult to understand concept?

If you want a lazy-by-default language, you need to deal with a problem — laziness means you don't need to actually evaluate the reads until you use `a` and `b`, and the print uses `b` before `a`, so the two reads can be executed in reverse order:

    a = read()
    b = read()
    print("{b}, {a}")

One of Haskell's original goals was precisely to be lazy-by-default, which necessitated coming up with a way to solve this problem, and monads are the solution they came up with that gave us reasonable ergonomics. From a practical point of view, monads are just types that have reasonable implementations for three simple functions: `pure`, `map`, and `flatten`

    # lists as monads:
    pure 1 = [1] # put a value "inside" the monad
    map f, [1, 2, 3] = [f(1), f(2), f(3)] # apply the function to the "inside" of the monad
    flatten [[1], [2, 3]] = [1,2,3]  # take two "layers" and squish them into one
    
    # also, the simplest, but least useful, way to use functions as monads:
    pure 1 = (x -> 1) # putting a value inside a function is just giving you the constant function
    map g, f = (x -> g(f(x))) # map is just composition
    flatten f = (x -> f(x)(x)) # you squish by returning a new function that performs two nested calls
("reasonable" here largely means "they follow the principle of least surprise in a formal sense")

The trick is that, once you know what monads are, you can use them in any language (with varying degrees of support), and you can see instances of them everywhere, and it's an incredibly useful abstraction. Many common patterns, (like appending to a log, reading config, managing state, error handling) can be understood as monads, and compose quite well, so your program becomes one somewhat-complex data type, a handful of somewhat-complex functions that build an abstraction around that data type, and then lots of really small, really simple functions that just touch that abstraction. I have a .class parser written in Scala that exemplifies this general structure, need to put it up somewhere public.

Re: Functional programming jargon in plain English

#84
post #14

All these niche functional programming languages are an exercise in pseudo intellectualism Give me an object oriented language any day. The world is made of state and processes, (modern niche) functional programming goes too far to derecognise the value of state in our mental models The good thing about functional programming is stressing to avoid side effects in most of the code and keep it localised in certain plac…

Functional programming is actually mathematics based on lambda calculus. Imperative programming isn't. OOP is a failed metaphor, unless you use composition, not inheritance, even then, the actual basis for OOP was about the messages between objects, not the internals. > The world is made of state and processes No, the world is made of objects that have state and messages (events) between them.

The lambda calculus is an entirely arbitrary way to organize things in math. It’s not based on nature or truth at all.

The real problem, though, is that FP doesn’t do anything well. It’s never the fastest method of programming, which means that it needs to excel in some other way for its proponents to be right about it. Is it the most maintainable? Maybe if you have zero side effects but then any paradigm would be in that case. Once you introduce state, it becomes a nightmare to maintain, unlike OOP. It’s certainly not the most readable.

Re: Functional programming jargon in plain English

#86
post #73

Earlier quoted context omitted.

Currying is one of those cases where the code is the explanation I think in many cases this isnt right, eg., Monads. The reason flatMap() "flattens" is just that "flattening" is really just sequencing, denesting the type using a function requires a sequenced function call: f(g(..)) This applies to many of these "functional design patterns"... theyre just ways of expressing often trivial ideas (such as sequencing) und…

While I _think_ I understand monads on some rudimentary level through how join and bind operate, your "just sequencing" doesn't tell me anything. And this is a problem with a lot of these texts. Maybe that's trivial to the writers, but it makes me feel even dumber when I cannot understand a concept I already understand, lol.

This is one of those things where looking at the type signature hard enough eventually gives the game away, but most writing on it sucks:

    bind :: m a -> (a -> m b) -> m b
Because that function in the middle takes an `a`, your implementation of `bind` needs to be able to take an `m a` and pull an `a` out of it, which means it also has to evaluate however much of `m` is needed to actually get to that `a`.

Because that function in the middle returns an `m b`, binding again with a function `b -> m c` requires you to pull `b` out of `m b`, which in turn forces pulling an `a` out of `m a` to make progress. This is where you force sequentiality — you can only evaluate the `m` in `m b` after you've evaluated the `m` in `m a`

Re: Functional programming jargon in plain English

#87
post #57

Earlier quoted context omitted.

And precisely because of the code sample, it should be obvious that currying is not the same as variadic function arguments. Instead, it allows for very concise partial function application, as demonstrated by the code. I can just call any function with a subset of its arguments, and it automatically returns a “new function” which you can call with the remainder of the arguments. It allows you to reason about calling…

Saying "it allows for very concise partial function application" does nothing but repeat the definition. It does not, in particular, offer any reason to want that. What is so special about the first argument, that I want to fix it? Why not the third? Why is what I do to fix the third not just as good for the first? Pattern matching is a good example of a language feature included because they could not figure out how…

In a language like Haskell, pattern matching was explicitly chosen to be a primitive operation. It's not that there's no way to put it in a library; it's that it was chosen to be one of the small set of ideas everything else is described in terms of. Along with allocation and function application, you've got the entirety of Haskell's evaluation model. (Note: not execution model. That needs a bit more.) Having such a small evaluation model probably should be taken as evidence the primitives were chosen well.

Re: Functional programming jargon in plain English

#88

These definitions don't really give you the idea, rather often just code examples.. "The ideas", in my view: Monoid = units that can be joined together Functor = context for running a single-input function Applicative = context for multi-input functions Monad = context for sequence-dependent operations Lifting = converting from one context to another Sum type = something is either A or B or C.. Product type = a recor…

I completely understand what you’re saying, but assuming that this guide is aimed at people entirely unfamiliar with these concepts, I’m not sure whether these “ideas” provide any meaningful explanation to them. Demonstrating by example what e.g. currying actually looks like is much more powerful, at least from my point of view. In that regard, I’m actually pleasantly surprised this guide does a very good job at that…

No post body was provided.

Re: Functional programming jargon in plain English

#89
Let me present this intuition I've developed.

• You have a producer of Cs, then you can turn it into a producer of Ds by post-processing its output with a function g: C → D.

• You have a consumer of Bs, then you can turn it into a consumer of As by pre-processing its input with a function f: A → B.

• You have something that consumes Bs and produces Cs, then you can turn it into something that consumes As and produces Ds using two functions f: A → B and g: C → D.

With pictures: http://mez.cl/prodcons.png

If you understand that, you understand functors:

• producer = (covariant) functor;

• consumer = contravariant functor;

• producer-consumer = invariant functor;

• post-processing = map;

• pre-process = contramap;

• pre- and post-processing = xmap (in Scala), invmap (in Haskell);

• defining how the pre- and post-processing works for a given producer or consumer = declaring a typeclass instance.

It doesn't mean that "a functor is a producer", but the mechanics are the same.

Re: Functional programming jargon in plain English

#90
The absolute state of github projects.

This project should be exactly 1 (one) file. The readme.md.

LICENSE - There is a license? Why? Someone might steal the text for their own blog post? So what? The license won't stop them.

package.json - to install dozens of packages for... eslint. Just install globally. It's just markdown and code examples. Yarn.lock - ah yeah let's have this SINGLE, NON EXECUTABLE TEXT FILE be opinionated on the javascript package manager I use. Good stuff We have a .gitignore, just to hide the files eslint needs to execute. wow. FUNDING folder - wow we have an ecosystem of stating the funding methods?

This should have never been a github repo. This is a blog post. It's a single, self contained post.

I hate this crap. We have 9 files just to help 1 exist. It's aesthetically offensive.

Post reply on HN