-
-
Notifications
You must be signed in to change notification settings - Fork 647
Rethinking modularization of Vavr #2316
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
Comments
Hey Daniel! I'm not very familiar with JPMS. Anything that I say might not make sense at all. As for what the individual modules should contain, where the module boundaries should be drawn, I think we should select a few fundamental things that should go into the core module, the non-fundamental things can go into their own modules. The fundamental things from my point of view are:
*) We don't presently have this class, and I think, where it makes sense, we should make vavr classes implement a vavr Iterable. That is, a type that provides a "better" |
Hello, @danieldietrich I agree that most of developers currently use Java 8 and if vavr would require Java 9 this would also decrease the amount of potential users. If the vavr codebase stays on Java 8, this could be the option to be available for Java 9+ users on module path and in future gradually move vavr to Java 9 when most of the projects will migrate on it. |
For me, I 100% support the removal of The modularization... I didn't really research the topic, but I view java9 modules as something which is useful to modularize big systems.. like the JDK (which was done). Or possibly very large enterprise software (like the way some systems today use OSGI). Intuitively I didn't think about splitting vavr itself; vavr feels "small", especially since it doesn't pull any dependency itself. Actually to me the great added value of vavr and of FP libraries/preludes is the symmetrical/uniform API accross these concerns (Option, Either, collections, Future...). And I'm afraid that splitting them, this can be lost or hampered. Certainly to me the loss of To summarize I think vavr 0.9 really hit a sweet spot for many people, maybe more than you may have realized as the author. I agree with some concerns, that it would be a shame to loose some of this to gain benefits for a very small minority of users which would actually potentially take advantage of the modularity (and the maintainers, although I of course sympathize with the load of work that is yours as the vavr maintainer). |
PS: regarding the modules, honestly we use it all, except for kotlin, gwt, some collections like Trees or OrderedMaps. I mean honestly dependency size is not a concern, we would just pull it all. PPS: another thing.. I see you'd drop Tuple and have some Entry class for map entries.. I just hope that Entry would also have |
Thank you all for your input, it is very valuable to me. I distilled it:
I also thought about wrapping CompletableFuture in a Scala-like Future but I'm not sure, yet. I think our current approach might be fine for now. |
Sounds great! Regarding tuples, Tuple2 might be enough. Tuple2 has a special role with Map in particular. |
@emmanueltouzery / @nfekete / ... Do you use Function1..N and/or Tuple1..N? |
Regarding types being iterable, I think it's important to have |
@nfekete scala.collection.Iterable is different, it is at the top of the collection hierarchy. With Scala 2.13,
Instead of re-introducing the Then Vavr would look more like Java. 😅 |
I was mainly thinking about an iterable declared in a similar way: package io.vavr.core;
public interface Iterable<T> extends java.lang.Iterable<T> {
@Override
io.vavr.core.Iterator<T> iterator();
} I'm wondering about the usefulness of the map/flatMap methods. Do you have a use-case? |
The current code base just contains example code. Iterable will soon look more like this, having 20-50 methods (not only map & flatMap). Please don't confuse Vavr's current Iterable with Java's. It is a collection interface (in Scala and currently in Vavr). The collections in Scala always flatMap to Iterable. In fact this relaxes the Monad laws a bit but it is still okay. It also works well in Java/Vavr. You have in mind that Iterable will be used not only by collections. This is what I meant with
in the comment above. If we move Iterable to Note: Our Note 2: |
@danieldietrich I stumbled across this thread from gradle/gradle#5120, and after browsing 41cd78ff, have a couple of comments:
I've created a sample project for my own learning that implements suggestion 1 and 2 from above; you're welcome to check it out. |
Hi @asarkar, thanks you for your feedback - here are my thoughts.
Thanks for your suggestion! We already do that in both, the current v0.9.2 and the upcoming v1.0.0.
You read different things. I also stumbled across these docs. It is just a convention that has no effect regarding the builds. Some do it, some not. It does not matter.
That's right. I started with one Gradle file. But Gradle's current Nevertheless, the link to the JPMS I gave you (in the Gradle issue on Github) is an old commit. The current version on the v1.0.0 branch does not have Thx! |
Those that do it includes the JDK, so AFAIC, the rest of the lot doesn't matter; YMMV. The funny thing about conventions is as soon as you create one, some people feel compelled to violate them for no apparent reason :)
I suppose that's because your Gradle module names are not the same as the JPMS module names, hence you need a property. If those were the same, you could've just used the project name as the module name. Thanks for maintaining the Vavr library, BTW, I use it extensively. |
I see! That's nice, thank you for the hint! |
Hi @danieldietrich - I realise that this goes against @emmanueltouzery's earlier opinion, but I'd find at least some modularisation to be a useful incentive for adopting Vavr; specifically, making at least the From my perspective, functional persistent collections are intriguing but I've yet to become comfortable with the idea of using them in any of my personal projects or introducing them to my colleagues, whereas I'm convinced of the value of Do you have any thoughts regarding this? :) |
@jbduncan Vavr is relatively small. All the past discussion showed that people are more willing to include just one lib (and maybe do not use parts of it) instead of having the overhead of including several libs. It complicates things. Also, we need to throw away existing features (like Try.sequence) when shipping control as separate module. Therefore my current strategy is to keep things backward compatible if possible (like package structure, naming etc) and just fix wrong design decisions in order to get Vavr right (like type hierarchy etc). |
Okay, those are totally fair reasons to avoid splitting up Vavr! Thank you very much for responding to my comment. :) |
Thanks |
Uh oh!
There was an error while loading. Please reload this page.
This is the first question I ask on my own here (I think).
(Also see how Scala does modularization: here and here).
Log
For the last weeks I started to rewrite Vavr. The new code-base is influenced by actual versions of Scala and Java, and also by things I've learned from the past.
For example common interfaces at the root of our type hierarchy will disappear, like Lambda, Tuple and Value. The main reason is, that some methods, like Value.flatMap and Value.filter, could not be defined in a generic manner. Also some Value methods that make only sense for wrapper types (like Option et al) leaked into the collections API. A common 'placeholder' interface 'Lambda' for functional interfaces did not work out well on the type level. And Tuple encouraged the use of instanceof and type casts, which isn't the way we should code in a first place.
However, beside these relatively small changes, I started to modularize Vavr. The first module was vavr-control. But soon, the community began to question the modularization efforts, which seemed to serve the maintainers only. Beside other things, controls were missing 'rich' Iterators and methods like sequence() disappeared.
Meanwhile, I thought about removing Future but also started a poll on Twitter:
It reminded me of the fact that it is okay that a major release introduces backward incompatibilities but it should not completely drop central functionality.
Question (@nfekete, @emmanueltouzery)
Therefore here is my question: How would you slice Vavr into modules?
Let's say, if the main Vavr lib still consists of the packages
The JPMS module name would be io.vavr. But that would prevent us from releasing other modules that share this package name, like the currently existing
I think the simplest solution is to change the package of the main library:
What are your thoughts? How would it affect your existing code bases. What are your preferred migration paths?
There is also the option to stay on the classpath. But I think it is important to be at least 'JPMS-ready'.
Thx in advance!
The text was updated successfully, but these errors were encountered: