loading...

Ask me dumb questions about functional programming

joelnet profile image JavaScript Joel ・2 min read

header image of f(x)

Hello! I am the author of MojiScript (a functional re-imagining of JavaScript) and I would like to help programmers who may be functional-curious :)

Have questions about functional programming but were afraid to ask?

Post questions here or @ me on twitter @joelnet use the hashtag #fpquestion.

I'll do my best to answer your questions and if I don't know, I'll try to point you in the right direction. If I can't do that, I'm sure someone smarter than I am will swoop in to save the day.

Don't bother asking "What is a Monad?" because everyone knows:

A monad in X is just a monoid in the category of endofunctors of X

If you have a code question, like "How do I do XXX" and you post source code, please make sure the code is runnable and make sure the code is boiled down to as small as you can make it. I can't convert your 1,000 file for you :)

Example of a good question

How do I do this...

for (let i = 1; i < 6; i++) {
  setTimeout(() => console.log(i), 1000)
}

Oh and let's have fun!

My articles are very Functional JavaScript heavy, if you need more FP, follow me here, or on Twitter @joelnet!

More articles
Let's make a DEV.to CLI... together
Let's talk about auto-generated documentation tools for JavaScript

Cheers!

Posted on Oct 15 '18 by:

joelnet profile

JavaScript Joel

@joelnet

Cofounded Host Collective (DiscountASP.net). Cofounded Player Axis (Social Gaming). Computer Scientist and Technology Evangelist with 20+ years of experience with JavaScript!

Discussion

markdown guide
 

I have two functions:
getUserFromDB :: Token -> Either NotFound User
and
getNewUser :: Token -> Either NoMoreInfo User
The Token is a token from OAuth api response. getNewUser uses it to get more info from api and create new user in my DB. and getUserFromDB just gets a user from DB with the help of token info. The problem is: how do I combine these two functions into one like getUser :: Token -> Either OneOfTwoPossibleErrors User, which will first try to getUserFromDB feeding token to it and then, if it fails, try to getNewUser again feeding the same token to it? FP is very good at creating consecutive streams that process data, but how to create two or more parallel pipes that are tried in sequence until one of them returns good result, and return any result from the last one if none succeeds?

 

It depends on the library you are using for the Either. But maybe these docs from Folktale's Either can help: folktale.origamitower.com/docs/v2....

There's a leftMap method that will run when the either is a Left. So it would look like

getUserFromDb(token)
  .leftMap(err => getNewUser(token))
  .cata({
    Left:  err => {},
    Right: value => {}
  });

 

Thanks! Good to know. But what about more general way, for example if I had a list of functions to try in order, like [getUserFromDb, getNewUser, trySmthElse, ....]? And I don't want to map that list into a list of results because that would mean execution of all of them, and I don't need a new user if getUserFromDB had found the one I needed.

Maybe something like this?

f = pipe([
  leftMap(getUserFromDb),
  leftMap(getNewUser),
  leftMap(trySmthElse)
])

Isn't leftMap, as a function (not a method .leftMap) takes an Either as its first argument? And to put up a pipe of leftMaps with Eithers I would need to first get all the Eithers and that would mean running all the functions again, which I try to avoid.

There is a function until in PureScript that is the closest to what I'm looking for: until :: ( a -> Boolean ) -> m a -> m a, but m is Monad, and I don't quite get yet how I can put a list of functions in it so that they will all get the same input value and be run one by one and tested after each run. until then returns a m a that is also can just be a list of results, kind of like map would produce, but that list will end as soon as (a -> Boolean) evaluates to true. Then I could just last on that m a result and, according to last definition, -> maybe get a successful output from the first succeeded function in the list =)

I think I found a somewhat simple solution!

const getUser = token => fold(
  (res, f) => res.isRight ? res : f(token),
  left('None Worked'),
  [getUserFromDB, getNewUser, someOtherAttempt, ...]
)

Ahh okay. I see what you are trying to do. Nice solution!

 

What is the best way to introduce a mostly FP codebase to newly hired junior developers?

 

Great question and difficult to answer. It would highly depend on how the codebase is written. For example, a MojiScript application I would start with explaining the pipe, because your app will be very pipe heavy.

But as a general introduction to FP, I like to start with map, filter, and reduce.

Show patterns imperative patterns they are used to with FP patterns used in the codebase. Something like this: Functional vs Imperative Patterns in JavaScript

Immutability is a great subject.

And I also love function composition!

JavaScript Allongé, the "Six" Edition is one of my favorite books. You can read it free at that link. It starts out pretty easy and goes very deep. So you can get something out of it at every level.

What is your current process for onboarding?

 

We're in a new stage of growth, adding developers for the first time in a while. I.e., we are starting anew with this process! Any feedback for onboarding is welcome. In fact, I think someone wrote about it recently.

I have been contemplating creating a series on functional programming, targeted towards junior and new developers. Would this be something you would find interesting?

 

¡Yay! Personal StackOverflow comes to my feed :)

 
 

How can I implement right-side currying (e. g. partial application popping arguments from the right side) in Javascript?

This is a very common task when working with 3rd-party libraries that supply functions with a weird argument order. Basically, I need a generic way to foldr the argument list by arbitrary length, returning the function curried.

Thanks!

What a great question!

Fortunately I have already written an entire article on this subject with Ramda!

I ❤ Ramda - Partial Application with a Special Placeholder

 

FP is said to be slow in certain use cases as compared to imperative programming (I don't remember the exact use case, but I'd say Fibonacci number generation is a good use case). Why, then, should I not stick to the imperative paradigm all the time?

 

In certain use cases FP is also faster.

Redux is FP and the majority of the React community has no problems with it.

When you are performance testing your code, the slowdown will not be cause by a map vs a for loop. The slowness will come from an Ajax call, reading a file, access a database and not from the code itself.

I would say put human readability and code-reusability above fast code. Optimize after you need to optimize. Do not prematurely optimize.

Do not let this myth hold you back.

I would recommend watching this video that tackles this subject:

 

How do you write something like websocket.onmessage or event-emitter.on in a functional way?

More question will come when I am on my notebook 😅.
Thanks for starting this thread.

 

Could you explain the state monad for me?

 

Not well. I have never used it.

The state monad is a lazy state manager. I could see it being useful when passing to functions as they would lazily update the state. The state wouldn't then be computed until you need to compute it, which wouldn't happen inside of the pure function.

It's also nice that it returns the computed value and the state as a pair. I feel like this could be useful, but I haven't really thought of a good use case for it yet.

I have read a bunch of stuff on the state monad and don't understand any of it.

The only thing I did understand was this, which might also be helpful to you:

State Monad in JavaScript

I'm not so much of a stickler for this level of purity and algebraic state management. When I need state, I'll usually grab redux.

I would compare it to a be redux reducer.

Cheers!

 

I'll try to point you in the right direction. If I can't do that, I'm sure someone smarter than I am will swoop in to save the day.

He means me.

 
 

Hi joel,
can you explain the diff between curry and partial function application?

thanks

 

This is a great question!

First let's define arity as the number of arguments a function takes. This function is 2 arity.

const add = (x, y) => x + y

Currying is taking a 2+ arity function and splitting it into many 1 arity functions.

So if we were to curry add, it would look like this:

const add = x => y => x + y

Now I would call the add function like this:

add (3) (4) //=> 7

Partial application is used with curried functions to partially apply arguments.

const add3 = add (3)
add3 (4) //=> 7

But partial application is not specific to curried functions either. For example, you could partially apply any non-curried function using bind.

const add = (x, y) => x + y
const add3 = add.bind(null, 3)

add3 (4) //=> 7

I hope that has been helpful!

Cheers!

 

Explain to me functional programming like I'm 5, you said dumb questions right? Seriously though I hear this term but I'm always lazy to search it up.

 

To me, functional programming is all about composing (or combining) functions to create new functions.

A good example of this would be map and it's siblings filter and reduce.

Imperative

const values = [1, 2, 3]

let sum = 0
for (const x of values) {
  sum = sum + x
}

Functional

const values = [1, 2, 3]

const add = (x, y) => x + y
let sum = values.reduce(add)

Instead of coding all the steps to create the sum, we told reduce to use the add function.

If we were using something like Ramda, we could even do this to create a new function:

import { reduce } from 'ramda'

const add = (x, y) => x + y

// Here we are composing a new function `sum` from `reduce` and `add`.
const sum = reduce (add) (0)

const values = [1, 2, 3]
sum (values) //=> 6

To be able to compose functions like this, you need to also create pure functions, curried functions and also have immutable data. Which is why functional programming can be tricky to learn. It's not difficult to learn, it just takes time to fully understand the why.

I hope this was helpful!

Cheers!

 

Now that's something a 5 years old can understand lol. Thanks!

Happy that you were satisfied with the answer. Hopefully others can also chime in with what functional programming means to them.

And don't be shy about asking more questions ;)

 

To me it is not just composition but also isolation.

There are many good things. I tried to boil it down to one for simplicity.

For me, it's also about not having the mistakes of OOP: Inheritance, State, Mutations, Combining data + functions into one Object, Access Modifiers (public, private, internal, protected), property accessors get/set. etc.

Yeah but still we need streams and emitters.

For sure. I use event emitters also. I usually tie those in together with RXJS.

You know, everybody is like rxjs and mocha and Jasmine and mojiscript and asynchronous curry ketchup frameworks but to me they are just collections of 'helpers' from other people that I like to write myself most of the time. Functional programming to me is closely related to context free development and that means elimiting dependencies. If functional programming really insists on being a thing then don't clean up only the language but also the rest.