Functional Programming Jargon
github.com
github.com
The whole list seems to be mostly Haskell-inspired terminology translated to JavaScript(?), so OCaml-style modules and thus functors might make less sense to describe thoroughly. (Even though the OCaml people have a better claim to be using Functor in something resembling its mathematical meaning.)
I think that is not accurate. Haskell's notion of a functor is basically taken from category theory. Same with applicative functor. It is easy to draw commutative diagrams for things like `Maybe` or `Either a` to prove it!
In contrast in OCaml functors are module functions. Do modules form categories? Maybe? I haven't seen anyone talking about category of OCaml modules. Perhaps in some papers. But even if they do I wouldn't call OCaml's claim better. When one says Functor in Haskell it is generally understood as "the category theory thing". When one says functor in OCaml I think most people, myself included, would think "module function", whether it satisfies category-theory requirements or not.
Also, worth pointing out that OCaml too has applicative functors. Those are such functors that when applied to same modules produce same types. Whether that fits with the category-theoretic notion of applicative functor... haven't thought about that! Maybe?
Basically
module M1 = Make(F)(G)
module M2 = Make(F)(G)
then if `M1.t` is the same as `M2.t` for some `t` the we have an applicative functor. The other side of the coin are generative functors: each time you apply them they mint new types: module M1 = Make(F)(G)()
module M2 = Make(F)(G)()
Then `M1.t` /= `M2.t`. This has been introduced in OCaml `4.02`Wrong kind of functor, I believe.
Unfortunately, functor actually refers to a whole heap of different terms in various mathematical fields.
Ocaml's functor seems to come from Quine's predicate functor logic, or a related field like combinatory logic.
The mathematical concept seems to be like kind of a wrapper
In Haskell functors are endofunctors in the category Hask. Endofunctors are a special case of functors where the source and result category are the same, and Hask is a category of Haskell types. So essentially Haskell functors are all Hask -> Hask transformations. For example applying "fmap show" to a Maybe Int produces a Maybe String, which are both in Hask.
In OCaml you can treat modules of the same signature as categories. If you look at [1] and look at the example for intervals, you have one category of Comparable modules and another category of Interval modules. The Make_interval functor maps objects from Comparable to Interval.
So it really is the same concept, just different applications, but they follow the same theoretical framework and properties.
Functional works does not mention the MIT license and thus is allegedly infringing on his copyright.
They link to the original source though. And the author seems to be hemanth himself. So perhaps this is all false alarm.
We have a platform that givs visibility to the great work that’s being done in the functional space.
Wow, that's disingenous. That's nothing like what you do. You have a platform that promotes your brand by copying and pasting other people's content into a worse presentation with your logo in a sticky navbar stuck to the top of the page.
As with all articles on our blog that are not written by us, the authors can reach out to us at any time if they want to make any changes to the article and we'll be happy to comply. As well, they can make the changes by themselves at any point.
Regarding the MIT license, we didn't think of mentioning it on the blog - but thank you for head's up, we'll look into it.
Also, trying to explain Monad, Comonad, or Applicative as 'jargon' is probably a step too far IMO. They are not important for getting started with FP, and describing them without their equational properties is kind of meaningless.
That being said I liked alot of the inclusions; partial application, closure, composition. I think the collection is probably slightly guilty of trying to be too clever by including advanced concepts.
But that's also the reason I agree with you as regards their utility in most programming. Simply knowing the "what" of the definitions is barely a start. Those who know the definitions and are comfortable enough with the material to use them effectively would find little value in lists of this sort. For most (almost all) programming efforts outside a very narrow niche of academic applications it's not even necessary.
I clicked on any topic in the list and it just scrolled me to the top of the page. (Mac OS + Chrome latest / Safari latest)
Also if you refresh the page with a url which has a #link in it it will reload with an empty-ish content.
We’ll launch a new version of the site mid December which will address the current issues. Iterating...
It should probably say:
> Lifting is when you take a function and make a version of it that operates on functors / applicatives.
I'm not sure if lifting is just application of a coalgebra but I'm still learning too. :)
I understood this much already prior. What I'd like next now are at least a handful (half-dozen-or-so) of concrete and truly compelling examples of such "uncoverings" ;)
OK, 1 or 2 would also be a start
Monads are so pervasive that multiple languages have determined that they deserve special syntax (see: Haskell's do-notation, OCaml's let-syntax). Those syntaxes play nicely with a ton of seemingly-different types, such as promises, options (maybes/nullables), lists, monadic error handling (either, or_error), etc.
On a similar note, recognizing the structure of monads has in the past allowed me to abstract things in an interesting way. For example, say I have a dict lookup function (takes a key, returns a value) and I want to build a bunch of useful functions on top of that. But we want to use them in many different contexts - the dict might be remote or locally in memory (promises vs. not) and we may or may not be in a test context (monadic vs exception-based error-handling). By recognizing that we can just abstract over monads, we can easily handle these 4 cases (promise, promise+error monad, error monad, unit monad).
You can also add F# computation expressions to the list!
I failed to find F# computation expressions, probably because I searched for the word "monad" which they seem to be avoiding, but that's another great example.
https://bartoszmilewski.com/2014/10/28/category-theory-for-p...
validate :: Regex -> String -> T
validate r s = ...
validateIpAddr :: String -> T
validateIpAddr = validate ipRegex
validateZipCode :: String -> T
validateZipCode = validate zipCodeRegex
And so on and so forth. It can reduce boilerplate, and lets you do stuff like map partially applied functions to functors.
validate(IpAddr, Regex)
to validateIpAddr(Regex)
I have to admit I'm a little fuzzy on why currying is desirable so there's probably something obvious I'm missing. filter (validate ipRegex) listOfStrings
instead of filter validateIpAddr listOfStrings
where validateIpAddr string = validate ipRegex string map { validate(ipRegex, $) } listOfStringsThe primary advantage of curried functions is that they're trivially partially applicable.
With an uncurried function, if you have a function of two arguments and you want to apply the first but "hold off" on the second you have to wrap the thing in a new function with a single argument which will do the application later (the language may also provide a helper) whereas with curried functions, you can just apply one of the parameters:
let add5 = (a) => a.map((n) => n + 5)
versus let add5 = map (\n -> n + 5)
This means you can very easily create "small specialisations" of very generic functions.Languages with curried functions also tend to provide features like the ability to treat operators as functions ("sections"):
let add5 = map (+5)
and more function composition tooling: let add5ToEven = map (+5) . filter even
though these are not really intrinsic.I think it is in some way overused in Haskell for example. When your function takes five different parameters, it's unlikely that the curried style really makes sense, other than that it's just convenient and idiomatic in Haskell—in many cases you would be better off using a record type for the parameters.
But if you consider for example the map function, it really makes sense to consider it a higher order function in a "curried" way. That is to say, map f makes sense on its own, because map takes a function and transforms it into a function that works on lists.
So the type
map :: (a -> b) -> ([a] -> [b])
is really nice, and nicer than the uncurried alternative: map :: (a -> b, [a]) -> [b]
Of course they're isomorphic, but the curried one seems to definitely win in terms of elegance, and you avoid ever having to type \x -> map (f, x)
or similar.I think if Haskell had really convenient named parameters, people would use currying less, but we'd still want to use the curried style for many functions that actually make sense as higher-order functions.
To be honest, each concept like "partial application", or "applicative functors" deserves an hour-long lecture or more but if the content went that deep I think it'd lose its current audience.
There's been a nice functional language buried in JS all this time. It's still buried in there someplace.
Small suggestion: It would be really nice if the table of contents allowed me to click to the section itself.
1) any key/value data structure
2) a hashmap, specifically
3) a function that runs on each element of an array to make a new array
https://facebook.github.io/immutable-js/docs/#/Map
While this doesn't cause an immense amount of confusion, it does throw me every once in a while.
For purposes of education and communication, I think it's unfortunate that we use the same name for these things.
In my other deleted comment I thought only links don’t work; but it appears that you see nothing at all with js off.
regarding the JS stuff, the site is built as an SPA and the blog is only one feature, the others are job postings and a personal dashboard where a signed-in user can pin their favorite jobs to keep them for further reference
It's also built using ClojureScript, Reframe, Clojure & GraphQL plus a revamped version launch is planned for mid-December, so I'm afraid the JS is still going to be there :)