Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Similarities, Differences, and Pros/Cons of this library compared to FunctionalJava #2054

Closed
JordanMartinez opened this issue Aug 15, 2017 · 8 comments

Comments

@JordanMartinez
Copy link

I apologize if this will lead to more opinion-based answers, but I'd still like to hear them.

I'm interested in adding more functional idioms to a project written in Groovy on which I'm working.

How is this project similar to and different from FunctionalJava? What are the pros/cons of each? When and why should I use one over the other?

@danieldietrich
Copy link
Contributor

danieldietrich commented Aug 16, 2017

Hi @JordanMartinez,

I think you can compare the relation fj/vavr to scalaz/scala. Several of fj's initiators are scalaz comitters, e.g. Runar.

It is my understanding that fj targets effect-free programming by encoding states using types. You need to know some bits of the algebraic methodology. For example (streaming) IO effects may be abstracted using transducers, getters/setters may be used in a functional way using lenses and so on.

I've experienced that Java is not the right language to do these abstractions. It is technically possible but it is bulky and has significant performance impacts. Also, in Java several things can't be expressed, it seems we have to stop half the way (missing higher kinded types, no tail recursion, no lazy evaluated values, etc).

During the creation of Vavr's Vector we made benchmarks. FJ's solution is more than 100x slower for some operations. However, if you want to be able to mathematically proof the correctness of (parts of) your application, fj is the way to go.

Vavr intends to give you some bits of functional programming without breaking the Java programming model moving too far away from standard Java. I will elaborate on it soon, a blog post is in the make...

Please also see https://www.quora.com/What-is-Scalaz-useful-for

Cheers,

Daniel

@danieldietrich
Copy link
Contributor

danieldietrich commented Aug 16, 2017

@JordanMartinez, I'm the creator of Vavr / Javaslang, I might be too biased to give an objective comparison.

@jbgi, looking at the recent commit history and the activity outside of the Github repo, currently you can be considered as main comitter of fj. My impression is that you keep fj alive. You also contributed to Vavr / Javaslang in the past. Could you please drop some sentences here what makes fj so special regarding FP in Java?

  • Which is the target audience of FJ?
  • What are prerequisites to get started with FJ? Would you recommend it to 'Average Java Joe'?
  • Is it recommended to use FJ in production? What about GC pressure in enterprise-sized applications?
  • Is there a risk of memory leaks due to reference-capturing closures and extensively used state wrappers?
  • Are there any measures (benchmarks) regarding runtime performance?
  • For which kind of applications FJ fits best? Is it a swiss army knife or domain specific?
  • ...

Comparing libraries is such a delicate matter, especially if one is involved 😅

Thank you!

@He-Pin
Copy link

He-Pin commented Aug 16, 2017

I think both libraries are great, but as user, we mostly only choose one and stick with it:)
which one is better, sometimes it's just a piece of personal taste.

@JordanMartinez
Copy link
Author

@danieldietrich Thank you for the response! I'll respond inline.

I'm the creator of Vavr / Javaslang, I might be too biased to give an objective comparison.

That may be, but it also helps to hear from the mind(s) that designed and implemented the project, wouldn't you agree?

I think you can compare the relation fj/vavr to scalaz/scala. Several of fj's initiators are scalaz comitters, e.g. Runar.

Helpful analogy. Thanks!

It is my understanding that fj targets effect-free programming by encoding states using types. You need to know some bits of the algebraic methodology. For example (streaming) IO effects may be abstracted using transducers, getters/setters may be used in a functional way using lenses and so on.

I've experienced that Java is not the right language to do these abstractions. It is technically possible but it is bulky and has significant performance impacts. Also, in Java several things can't be expressed, it seems we have to stop half the way (missing higher kinded types, no tail recursion, no lazy evaluated values, etc).

I read through a book on Haskell recently, so I understand (at least at a primitive level 😉) algebraic datatypes (ADTs). However, I agree about the bulkiness of it all. For example (and not to bash on FJ, but..) how can one use FJ's Tuples (P1, P2, P3, etc.) to simulate these ADTs without the code getting completely confusing since one cannot use type aliases (an issue in Java and Groovy alike). Extending P2 (e.g. class Person extends P2<String, Integer> { /* name, age */ }) wouldn't work well because their getters wouldn't be named according to their fields; reading it later would be a difficult task. Creating my own named Tuple2 class class Person { String name, int age } would require isomorphism to turn it into FJ-compatible P2<String, Integer>, but that feels like it would turn into boilerplate at some point.
I believe Groovy has tail recursion, but not higher-kinded types. I'm not sure about the lazy evaluated values (though it seems FJ already has that...?).

During the creation of Vavr's Vector we made benchmarks. FJ's solution is more than 100x slower for some operations. However, if you want to be able to mathematically proof the correctness of (parts of) your application, fj is the way to go.

FJ seems slower due to using non-primitive types for primitive types, but is that still the case when using non-primitive types? Is FJ actually faster because they can use their FingerTree implementation? I didn't find that data structure in this library, but I'm not sure if you're using one internally either.

Vavr intends to give you some bits of functional programming without breaking the Java programming model moving too far away from standard Java. I will elaborate on it soon, a blog post is in the make...

I look forward to reading that blog post! Could you post its link in this issue when you finish writing it, so that I can be notified of it?

Please also see https://www.quora.com/What-is-Scalaz-useful-for

Helpful. Thanks again!

Comparing libraries is such a delicate matter, especially if one is involved 😅

I agree and will end by saying that both libraries are powerful and very helpful for adding support for what is lacking in the Java language itself.

@hepin1989 I agree. My first problem is just understanding the pros/cons of each. My second problem is learning what it would look like for me to use either library in my project, and finally deciding which to use based on what meshes with my personal tastes.

@jbgi
Copy link

jbgi commented Aug 16, 2017

I agree with what @danieldietrich said. It is true that FJ has not had a strong focus on micro-optimizations. There is surely more GC than ideal although it has improved bit by bit.
The fundamental "problem" of FJ is that its contributors often move to better languages after a while (scala(z)/haskell) so we are constantly looking for new contributors: I guess it is a testimony of the effectiveness of FJ as gateway drug to (pure) FP.

So if you believe that Object#equals is evil and your career plan is to move to better languages than Java, then FJ is for you: it surely have been used in production and you can learn quite a bit of FP using it.

Even though there may be performances issues, most of the one that have been identified so far had relatively straight-forward solution.
The fact that FJ avoid sub-typing contribute a lot to its simplicity of maintenance and ease of reasoning.

@danieldietrich
Copy link
Contributor

@jbgi thank you, well spoken! 😊

@JordanMartinez
Copy link
Author

I think this has answered my question, so I'm closing it (forgot to earlier, sorry!).

Thanks for the feedback!

@danieldietrich
Copy link
Contributor

Thanks for asking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants