Comments (4)
Perhaps some additional background on jOOλ. jOOλ was created because I was disappointed by the verbosity of the JDK 8 stream pipeline at the time: https://twitter.com/lukaseder/status/639802749878697984
I wanted to use FP constructs in jOOQ's test code, and found this whole stream().collect(toList())
ceremony terrible. Also, I needed zipWithIndex()
all the time, and maybe 1-2 other sequential only stream methods. Adding tuple support as well as "fixing" checked exceptions in lambdas was a no-brainer. But really, having a Stream.toList()
method was the main motivation at the time, and the fact that I knew many felt the same way, I could get some marketing buzz for jOOλ/jOOQ by creating a similarly branded library.
There were other libraries at the time, including:
- https://www.functionaljava.org (predated Java 8)
- https://www.vavr.io (mimicked Scala SDKs)
- https://github.com/amaembo/streamex (similar to jOOλ but different focus, i.e. not "fixing" streams but "enhancing" them)
The first two have a much more complete vision of FP in Java. StreamEx and jOOλ merely "improve" the JDK Stream
API. In the meantime, the JDK itself has improved a lot, and parts of jOOλ are no longer necessary. For example, while I still think that tuple support and tuple collectors are great, they're not strictly necessary anymore with the teeing()
utility in the JDK.
For a while, I thought that there's a lot more potential in jOOλ, but designing an FP API is really really hard. You constantly have to fight the temptation of adding weird things, because they're not really canonical or as composable as they should be. For a while, I accepted quite a few PRs, all prematurely, and now jOOλ can't get rid of those things anymore, because of backwards compatibility.
So, for a while now, I haven't really added anything to jOOλ anymore, knowing that there are tons of opinions and utilities, and only very few are universal and versatile enough to be worth adding. I guess that's why the JDK Stream API was so limited when it was first introduced. Endless possibilities, but what's really really needed, knowing that any prematurely added thing can never be removed again?
An example, take your Loops
class. Is that really the best approach? Shouldn't we have more lazy pipeline evaluation directly on the JDK collection types, e.g. on List
? So, perhaps a List
subtype that offers new API for internal iteration? There are so many possibilities to solve this problem of doing less than a full fledged stream pipeline, and thus faster, but still FP-ish.
from jool.
I didn't choose Functional Java and VAVR exactly because they are too heavy/complex/cumbersome and have "too much" :-)
The difficulty is to avoid turning jOOλ into a "too much" library. (It's hard, I know)
from jool.
Thanks for your various suggestions. They're probably quite independent of one another, so if we do decide to go forward with individual changes, we'll probably need separate issues (it's often best to keep things separate from the beginning. Much easier to track and close things individually). I'll comment on your individual suggestions below:
- [completely optional] Gradle 7.5.1 build with Error-Prone
https://errorprone.info/ - is a great statistical analyzer from Google. It is used at compile time to find problems in code.
I don't want to maintain a gradle integration. It's only really useful for power users who insist on forking jOOλ and using gradle. But that's a user problem, not a jOOλ problem. https://github.com/jOOQ has multiple modules, and there's no reason to do this only for jOOλ. But doing it for all of them is just busywork, I think. So I'll reject that.
Error Prone can be useful indeed, but from my experience, it is also a PITA to maintain across build systems (maven / gradle) and JDK versions. If you want to add it on your end, and then report bugs based on its findings, that's great. But I wouldn't want to maintain this. Again, this isn't just about jOOλ.
2. Added Predicates (Predicate0- Predicate16) similar to Functions (Function0- Function16). The API is almost identical.
The JDK has dozens of names for things that should be structurally typed, just because the authors insisted Java stays a nominally typed language. E.g. ObjIntConsumer
. Adding new types for every variant doesn't scale when you have to add N
of these. A Predicate<T>
is just a Function<T, Boolean>
with a non-null guarantee (or a (T) -> Boolean
, if you wish).
Unless you have several very compelling use-cases for such predicates within jOOλ, then I think this won't be very useful.
3. Fixed Javadoc errors and Error Prone errors.
Sounds great, can you create a separate issue for this?
4. Sub-project/branch "jOOL" had one type End-of-lines and "jOOL-java-8" the other. So it wasn't easy to understand: are they the same? Now both branches are identical except 'module-info.java' and build scripts.
This is why asking first and sending PRs later is a good idea, always. You didn't know why this is. It's because jool-java-8
is a generated project, using an internal (non-public, non-open source) API preprocessor: https://blog.jooq.org/how-to-support-java-6-8-9-in-a-single-api/
So, you shouldn't touch that module in your PRs. In case a PR is accepted, I'll just re-generate that module after merging.
5. Loops.java - tiny funny functional "external" loops. Quick and fast replacement for some nasty repetitive "while" and "for". Can be used occasionally as "poor man's JMH" (There is a version with warm-up and measurement).
There is also a "multi-/nested for" version, with so many nested for loops as you like. Can be used as "forEach", Iterator or Seq version.
Fun fact, jOOQ's internals have those to avoid the full stream pipeline and still offer FP-ish APIs. I've thought about publishing those as their own module, but we'll probably not agree on API design, when I look at your suggestion.
It's not something jOOλ has to do. Why not create your own library for this?
6. [!!!] "Optional" wrapped/alternative/default-value or "Safe" version of Unchecked and Sneaky.
jOOλ's main goal was to "fix" Java 8's shortcomings. I understand that a lot of folks wished Java was Scala, and they want a monad for everything. That's not what jOOλ aims to do. So, there won't be anything like Either
.
I personally think Either
is a terrible abstraction. I like the imperative nature of unchecked exceptions. Checked exceptions are a bit weird. They are best translated to union types, which e.g. Ceylon or TypeScript have.
In any case, jOOλ does not aim to offer such things. If you want Scala-ish APIs in Java, there's vavr.
7. Safe Runnable and Callable
I don't understand why jOOλ needs this? You just want to ignore all exceptions from a lambda body?
So, long story short, apart from the Javadoc flaws, which can certainly be fixed, I don't think anything is worth adding to jOOλ.
from jool.
Thank You very much for such detailed and informative explanation!
You've highlighted some very strong points here:
I didn't choose Functional Java and VAVR exactly because they are too heavy/complex/cumbersome and have "too much" :-)
jOOλ have the most beautiful and light API of all.
As I already said, all changes come from some ad-hoc solutions to easy my pain, while migrating a very old Java 1.6 App to Java 8. I have just refactored them to make more pretty.
As You have recommended:
In a short time I will write a new issue and send a new pull request with fixed Javadoc and Error Prone errors and most obvious warnings.
And I will apply them only in "main" jOOL directory (V8 version will be auto-generated by your pre-processor).
from jool.
Related Issues (20)
- A multi-release jar maybe better, if no extra classes for Java 9+ HOT 1
- Add zipWithIndexAndSize() HOT 3
- Change Tuple v1 to fst and v2 to snd HOT 3
- IllegalStateException on Seq#append after Seq#forEach HOT 9
- Implement shortcut for 0.0 and 1.0 percentile calculations HOT 3
- Add Seq.toMap() with mergeFunction HOT 1
- Add support for PERCENTILE_CONT semantics HOT 6
- Add @param javadoc to Agg methods
- Add Agg.covarianceDouble HOT 1
- Add Agg.correlationDouble()
- Add Predicate<Tuple[N]<T...>> Tuple.predicate(Predicate[N]<T...>) HOT 5
- A strange issue on java 8: consumer isn't being called HOT 1
- Add Gradle build with Error-Prone in addition to maven HOT 3
- Add set of Predicates 0-16 (similar to Function 0-16) HOT 1
- Wrong result for Agg.regrR2Double() HOT 6
- Fix Javadoc errors, Error prone errors and most obvious warnings HOT 9
- Excess type variables in Agg::bitAndInt and Agg::bitAndLong
- Replace <code><pre> by <pre><code> in Javadoc HOT 1
- Release 0.9.15 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jool.