DEV Community

Marcos Sevilla

Posted on • Updated on

Functional Programming in Dart

You can find even more and keep in contact with me on my socials:

bitoolean

Thank you for sharing this information!

I'm a fresh beginner with Dart and just looking into functional programming, but I was taken aback by something.

Were you trying to enforce / illustrate the immutability of the collections when you made those variables final? I find that confusing because I would've expected you to make the values (collections - map/list) final instead, on the right-hand of the assignment. I thought functional programming still allows for variables (reassigning of values). I suppose that was just a sleight of hand on your part?

Thanks again!

Marcos Sevilla

Hi! Sorry, I didn't understand what you mean, can you explain with a code snippet which part are you referring to?

bitoolean

At the end of the article, the last code sample:
final aList = [3, 6, 7, 9];
final aMap = {'name': 'Marcos', 'age': 21};

var aList = final [3, 6, 7, 9];
var aMap = final {'name': 'Marcos', 'age': 21};
in order to better illustrate functional programming concepts, if that is what you were trying to do? I expected you would be making the values final, not the variables - there should still be variables in functional programming, right? That is, F.P. paradigm still allows assigning new values to variables (which is why they are called variable), I understand? Or am I taking things too far by analyzing the syntax.

Keep in mind I'm just learning Dart, so I might be wrong about some things, as in not understand some things fully/correctly.

Marcos Sevilla

var is used to define a variable, final is used for constants. So you can’t define a list as var and final, and variable declarations go left to right, the snippet you shared won’t work because it expects an identifier after the final keyword.

If a variable is final, its value is assigned only once. But in the case of lists or maps, you can add entries even if they’re constant (final). I highly suggest you test the code snippets you see in this and other posts on dartpad.dev or a brand new project, that way you can play with it and understand it better.

Hope that clarifies your doubt. 👍

Thank you. Yes, I did confuse terms. I was thinking of the "const" keyword. Still, the point applies - why use "constants" instead of variables, when Dart allows using const in front of a map / set / list value expression, which is what I understand FP is about? So why not enforce immutability on the values (the list/map/set etc. objects) instead by making them const?
var aList = const [3, 6, 7, 9];
var aMap = const {'name': 'Marcos', 'age': 21};

Why even make them final?
"Note: Although a final object cannot be modified, its fields can be changed. In comparison, a const object and its fields cannot be changed: they’re immutable." (from the Dart Language tour - "Final and Const" section)

We still want to have variables in a FP paradigm, if I am understanding the concepts correctly? We want immutable collections instead. Simply making variables read-only / const is not what FP is about, is it? Or maybe there's something I'm missing.

EDIT: Oops, my bad. In my defense, I'd read this past midnight originally and the last time. I see the example is using ilist/imap abstractions to make a collection immutable and work with collections as immutable. Still, I guess the use of const collections is worth consideration in the FP context?

This looks compelling, but I am not sure it is. Dart isn't a functional programming language, and this package, though very compelling on the surface of it, seems to help, I am not sure I would want to use it in my projects. I understand that implementing things like Either and Option is hard, but the code below I would not want to ever write, and I am not sure I would like to have it in any library included in my application

``````  static Function1<Either<L, A>, Either<L, B>> lift<L, A, B>(B f(A a)) => ((Either<L, A> oa) => oa.map(f));
static Function2<Either<L, A>, Either<L, B>, Either<L, C>> lift2<L, A, B, C>(C f(A a, B b)) => (Either<L, A> fa, Either<L, B> fb) => map2(fa, fb, f);
...
static Function19<Either<L, A>, Either<L, B>, Either<L, C>, Either<L, D>, Either<L, E>, Either<L, F>, Either<L, G>, Either<L, H>, Either<L, I>, Either<L, J>, Either<L, K>, Either<L, LL>, Either<L, M>, Either<L, N>, Either<L, O>, Either<L, P>, Either<L, Q>, Either<L, R>, Either<L, S>, Either<L, T>> lift19<L, A, B, C, D, E, F, G, H, I, J, K, LL, M, N, O, P, Q, R, S, T>(T f(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, LL l, M m, N n, O o, P p, Q q, R r, S s)) => (Either<L, A> fa, Either<L, B> fb, Either<L, C> fc, Either<L, D> fd, Either<L, E> fe, Either<L, F> ff, Either<L, G> fg, Either<L, H> fh, Either<L, I> fi, Either<L, J> fj, Either<L, K> fk, Either<L, LL> fl, Either<L, M> fm, Either<L, N> fn, Either<L, O> fo, Either<L, P> fp, Either<L, Q> fq, Either<L, R> fr, Either<L, S> fs) => map19(fa, fb, fc, fd, fe, ff, fg, fh, fi, fj, fk, fl, fm, fn, fo, fp, fq, fr, fs, f);
static Function20<Either<L, A>, Either<L, B>, Either<L, C>, Either<L, D>, Either<L, E>, Either<L, F>, Either<L, G>, Either<L, H>, Either<L, I>, Either<L, J>, Either<L, K>, Either<L, LL>, Either<L, M>, Either<L, N>, Either<L, O>, Either<L, P>, Either<L, Q>, Either<L, R>, Either<L, S>, Either<L, T>, Either<L, U>> lift20<L, A, B, C, D, E, F, G, H, I, J, K, LL, M, N, O, P, Q, R, S, T, U>(U f(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, LL l, M m, N n, O o, P p, Q q, R r, S s, T t)) => (Either<L, A> fa, Either<L, B> fb, Either<L, C> fc, Either<L, D> fd, Either<L, E> fe, Either<L, F> ff, Either<L, G> fg, Either<L, H> fh, Either<L, I> fi, Either<L, J> fj, Either<L, K> fk, Either<L, LL> fl, Either<L, M> fm, Either<L, N> fn, Either<L, O> fo, Either<L, P> fp, Either<L, Q> fq, Either<L, R> fr, Either<L, S> fs, Either<L, T> ft) => map20(fa, fb, fc, fd, fe, ff, fg, fh, fi, fj, fk, fl, fm, fn, fo, fp, fq, fr, fs, ft, f);
``````

A significant effort for sure, but again, nah...

Marcos Sevilla

Yeah, I highly suggest checking out the package oxidized as dartz hasn't been updated in a while. The post originally was to explain how to bring functional approaches to Dart, but its use is optional, having functions as first-class citizens is the only functional characteristic by default.