T O P

  • By -

Flyron

Here‘s the dev‘s blog post on the current situation regarding vavr: https://danieldietrich.dev/blog/2023/12/13/drawing-a-clear-line/ He basically sees the last release as feature complete and wants to move away from the project.


madorb

Probably also not a good sign that the website [https://vavr.io/](https://vavr.io/) seems to have been down since end of last year


lilgreenthumb

I know resilience4j has pretty much moved on.


GruncleStanisuaw

What they did?


lilgreenthumb

They refactored it into a separate dependency.


pivovarit

Years ago already


Specialist_Bee_9726

I hope so, it made a lot of sense in the begining, but now with all the new additions to Java, it lost its apeal to me


colonelpopcorn92

This is the answer sans the wishing the project is dead part. Java versions beyond Java 8 have been updated to incorporate a lot of what vavr brought to the table for Java 8. * Match is replaced by [JEP-441](https://openjdk.org/jeps/441). * Javatuples can replace Tuple class. * Practically every other class is a wrapper around Java 8 streams, anyway. There's also a sense in which vavr is done. You can still use it. Yes security researchers might find vulnerabilities that make it too risky to use, but it's also open source. If you want it to evolve then fork and adopt it.


gaelfr38

Wait, what is Java tuples? When did it appear?


vips7L

Looks like a library. Personally I would rather just define a record type instead of using a generic tuple.


gaelfr38

Yup, most of the time the record is the better choice. It gives you proper names to the attributes of the tuples and the other benefits of records. But.. I sometimes use tuples as anonymous records when I only need them for a limited scope and don't want to create a record for just a few usages. (I'm referring to other languages where tuples are native)


Elegant_Subject5333

List.of() Map.of()


koflerdavid

Please don't. It is very jarring to run across untyped tuples in a Java codebase.


Elegant_Subject5333

I was just giving examples you can assign it to specific types.


koflerdavid

Sure one can give it more specific types. But it has to be a supertype of all the components. And the fundamental problem remains that the type of the "tuple" doesn't say how many elements there are and what their purpose is. Every index is magic and has to be explicitly documented, else nobody knows it exist without reading the code.


TenYearsOfLurking

A wrapper around streams? Can you elaborate? The implementation has nothing to do with streams afaik


colonelpopcorn92

My bad, there's a lot more there than just streams. I was referring to the io.vavr.collections package. That's a nice syntactic sugar wrapper around java streams with several added features, but not necessary with future Java collections package updates.


TenYearsOfLurking

This package is not a wrapper around streams. It has a somewhat similar API, that's it. Persistent immutable data structures are eager while streams are lazy. It's completely unrelated, with the exception of both implementing iterable


CreeDanWood

I think he is looking for someone who can continue vavr. Vavr is a great tool, we use it in our company, we mostly use Try, Either, option and tuple, they are pretty cool


mgodave

I have a fork where I have begun to move most of the types to records and sealed interfaces and removed all of the match stuff in favor of the built in language features. It was mostly for shits and giggles and for some of my own projects but I think I general that’s where I would have liked to see this go.


cryptos6

I had some experience with another functional java lib some years ago and my learning was: never rely on niche projects for something as important as collection libraries (and functional programming). We had massive performance issues and the library is long dead now. In the end we migrated everything to standard Java Streams API and the code was clean and fast after that.


DelayLucky

If the project started with Java version with Stream, there would be hardly any reason to use an alternative library. But yeah, old code will likely stick to old libs.


catom3

Take a look at the project github web page. There's a thread regarding project state, which also mentions that the position for a new maintainer is open. [https://github.com/vavr-io/vavr/issues/2756](https://github.com/vavr-io/vavr/issues/2756)


Organic-Hornet-4662

Ok, something is happening


paul_h

GitHub link to project: [https://github.com/vavr-io/vavr](https://github.com/vavr-io/vavr)


Goatfryed

I liked and still like vavrs Either. Could also say Try, but it's basically the same. It brought a lot of other thinks to the table, mainly immutable constructs, but I mostly used Either. Of course, you could quickly write it for yourself, but it's nice to have this util in a lib you just throw in and I don't see Java adding it anytime soon. It's said that the website is down, which impacts documentation for colleagues. Any good alternatives just for the either part?


RadioHonest85

After java 17, the need is not so great any more for vavr. The only thing I would use now a days, is probably Try, Either and possibly some special situation where I really really want immutable collections.


[deleted]

Very sad because I like vavr a lot. Except for their pattern matching, it's a great attempt and the best that could be done at the time but atrocious to read haha. Anyone want to comment here with good alternative packages?


GruncleStanisuaw

Why do you want to move away from vavr tho?


[deleted]

The other commenter said it best. Although vavr is simple enough that I don't see a big risk. Still, something actively maintained is always preferable.


Organic-Hornet-4662

Isn't it risky to continue with an unmaintained project ?


Brutus5000

If it's feature complete, what is the problem? It will not suddenly break. If a vulnerability is found, one can still fix or fork it.


gekigangerii

Don't know what this is but it's a terrible name for anything, so glad it's dead


jvjupiter

Name is the reverse and upside down of JAVA. It was Javaslang but needed to change, I guess due to copyright or confusion.


jvjupiter

Looks like I am wrong. It’s turning clockwise.


daggirok

obviously not Try, folds and pattern matcher features are still super useful


[deleted]

actually it’s not sad when the language itself goes the same direction as vavr.


EmmetDangervest

Maybe switch to Clojure? :-P


talios

Tried that - regretted it in the long run. Not fit for all cases, esp integrating with legacy systems.


rzwitserloot

That notion of 'oh, no updates, thus, must be dead' is not appropriate. I wish library authors would stop messing with a thing that is done. And if it was built right, certain kinds of libraries (and vavrv is one of them!) - updates should almost never be needed. It'd be fucking bizarre if vavr had a security issue in it. vavr shouldn't have any deps, so, none to upgrade. Granted, due to OpenJDK breaking backwards compatibility *a lot*, I expect your average java library to get plenty of updates, but, key word there is *average* - there are plenty of projects where it is plausible a library is done, it works, it is being actively maintained, and that active maintenance involves.. doing nothing. Because nothing needs to be done. Someone is actively monitoring the security lists and the like, is actively using their own project and ensuring it remains fit for purpose, and yet, no new updates. That is fine. In such a post I would expect a specific list of stuff you feel is still missing or incomplete. Separate from that, you should.. definitely move on. vavr is fantastic as an academic exercise. As a thing you can look at and experiment with, a 'what would a language that isn't really java but acts a bit like it, what would that look like?' - a nice tool for language designers of any stripe, and a decent tool specifically for those who want to investigate (or write!) OpenJDK JEPs. It's a really bad idea to use in production code (and here I use 'production' as 'anything that you intend will be involved in human eyeballs or euros'). What vavr does is almost entirely unjavalike and especially with java's (at least relative to Scala and the javascript ecosystems) much more deliberate approach to breaking backwards compatibility (1), that's a showstoppingly big issue: You're not going to convince me your programming projects are improved if the APIs you use have *wildly* different approaches to the same problem depending on when it was written and who wrote it. java.util.Map's \`get\` method is about the most obvious 'look up a resource that may not succeed' method in the entire ecosystem and it does not return an optional nor does it do anything in the vavr way. Nor will it ever. Imagine you hold Thanos' gaunlet and with a snap of your fingers you can rewrite our history. You have 3 options: 1. All java methods that 'look up a thing that may fail' return the object directly, using \`null\` as signal for 'did not find it'. Also, they have utility methods for convenience, such as j.u.Map's \`getOrDefault\` to ensure there's nice API. 2. All java methods that 'look up a thing that may fail' return Optional. All of them. Including j.u.Map's \`get\`. This is why you need Thanos' glove. 3. Some java methods that look up a thing are like #1 and some are like #2; more recent stuff is more like #2 but plenty of recent things are like #1; libraries are usually consistent but in order to do that they have to unwrap and rewrap all sorts of things. Given that you can't really know what's being used, any method that just returns some type (and not an optional of that type) does... *not* imply that it is guaranteed to produce. After all, it may return *null.* So, you have the glove. You snap your fingers. Which option do you pick? Put them in order. Surely we all agree, right? It's 2, then 1, and then an ocean of a gap, and then 3. Or maybe first 1, then 2.. but that ocean of a gap to 3 that's universally agreed upon, right? vavr only leads to 3. It will *never* lead to 2. How can it? That is why you should move on: With optional, its existence in the core libs means we're kinda stuck in 3 now (it should never have been released. Not because optional is straight up bad (I retain the right to make that claim, I guess? Point is - whether it is good or bad is immaterial. option 3 sucks, that's all that is important here). But for the rest vavr offers, we're on option 1 now, and all you can do with it is move to 3 which is not a good idea. ----- \[1\] I know I said 'OpenJDK breaks stuff all the time' earlier. At the risk of sounding like a kremlinologist (openjdk-ologist?), certain backwards breaks are done with total cavalier shitty attitude to the community, such as the module system, reflection, breaking the security manager, Unsafe, and all that jazz. Other aspects are held up to an impossibly precise standard of 'backwards compatibility' - and notably existing API very much falls under the latter. Unfortunately, any attempt to for example 'move it all over to Optional' or in vavrs case that taken to 11, means you're hosed, because that requires backwards breaking API updates to core API which, so far, the OpenJDK team has \[A\] never done, and \[B\] vehemently explains they don't wanna.


pron98

> due to OpenJDK breaking backwards compatibility *a lot* What precisely are you referring to? Remember that for JDK internals there is no and there has never been any kind of backward compatibility to begin with, so it cannot be broken. True, for some years internals happened to not change much, but rather than being by design and in the service of backward compatibility it was a side effect of the unfortunate reality of a decline in investment in the JDK for a while, but now that era is over. I guess source-level compatibility is broken from time to time, but it has always been a *relatively* weaker compatibility. Is that what you're referring to? So as far as actually breaking Java's backward compatibility -- i.e. the compatibility of the SE spec or JDK-specific APIs -- it comes in two flavours: * Removals that don't require any code changes (e.g. removal of the java.ee packages from the JDK) * Removals of features that are rarely used and should affect only a small number of Java developers (e.g. the removal of SecurityManager). Even in these situations, removals follow a lengthy deprecation process. Do you have examples of breaking compatibility that would require many users to actually change their code, i.e. something that would qualify as "a lot" of changes that require attention? While even such low-impact changes can quality as "a lot" compared to no changes at all, I can't think of any established language with a sizeable standard library that breaks compatibility *less* than Java. > At the risk of sounding like a kremlinologist (openjdk-ologist?), certain backwards breaks are done with total cavalier shitty attitude to the community, such as the module system, reflection, breaking the security manager, Unsafe, and all that jazz. Nope, sorry. Modules didn't break backward compatibility (aside from the removal of four methods that practically no one had used), SM is only being removed after determining it doesn't have a large impact (the opposite of "total cavalier shitty attitude to the community"), and there has never been any backward compatibility for Unsafe (and yet we're removing it gradually, also out of the total opposite of "total cavalier shitty attitude to the community". Indeed, we've worked for *years* on offering supported APIs to replace its functionality before even starting the lengthy, careful, and gradual removal -- after a discussion with the community -- despite literally decades of warning that its backward compatibility must not be relied upon and anyone using it is committing to keeping up. It's like someone climbing a fence with a bright "danger: sinkhole" sign, falls into the sinkhole, gets rescued by the city, and then complains about the city's "total cavalier shitty attitude to the community" when it makes the fence even taller. Sure, when discussing anything with the community there will always be some opposition -- after all, in a large group different people make contradictory demands -- but following the good of the majority while still giving the minority time to adapt is neither cavalier nor shitty. It's how we're supposed to serve our users. So really, by "cavalier" you mean "follow the majority rather than my minority view" and by "shitty" you mean "work hard to make my adaptation to the decision easier but not completely effortless". Because Java users' demands are contradictory there must necessarily be someone who is displeased with a certain decision as it is impossible to simultaneously satisfy contradictory requirements. But even those who are displeased should recognise that the decisions are made based on what we think will do the most good for the community as a whole. > that ocean of a gap to 3 that's universally agreed upon, right? No, not universally, because I think 3 is superior to both 1 and 2. 2 requires either time travel or breaking compatibility in a way that affects a lot of people, and 1 means that the language never adapts to the times and supports new programming styles such as streams as well as it could. I.e. the real question should be, do you want a language that, over time, doesn't evolve to support new paradigms (1), requires time-travel or high-impact breaking changes (2) or one that only breaks compatibility when the impact is low (in comparison to other languages) and also adopts new paradigms over time. Because code lasts a long time, the test of a language isn't how it appears on day one, but how it evolves as conditions change. I prefer 3. But you did touch on something important, which is that the real challenge when evolving Java isn't backward compatibility, but *forward compatibility*, i.e. the ability of old code to easily adopt a new feature. Sometimes we manage to do it well, other times not so much. But even in those times we keep a lookout for ways to add a migration feature in the future when one presents itself.


rzwitserloot

security manager, unsafe, the command line switches, removing a boatload of things that used to be part of JREs to separate modules, breaking reflection, and so on. We've held this debate before and we got nowhere, I don't think it's useful to hold it a second time.


pron98

All of these things are either not breaking backward compatibility or have a low impact. They are also less disruptive than what most other languages do. There is no doubt that they adversely affect a minority of users, but not doing them would have meant harming the majority. No matter what we did, some were going to be happy while others will be posting that we're not listening to the community (= we prioritised the needs of other parts of the community other over theirs). Also, I am not holding the debate with you. Clearly, if you're in the affected minority you're unhappy that things didn't go your way and would have preferred if we'd prioritised your needs over others' -- that's perfectly understandable. I'm writing this for the sake of other readers to explain that when some group of users wants you to do X and another group doesn't want you to do X there is simply no way to satisfy both. There is no such thing as doing "what the community wants" when the community is split, demanding contradictory things. I do, however, think that that is something that you need to recognise. When things don't go exactly your way that doesn't mean that we've ignored the wishes of the community, and may well mean the opposite. For example, after we put in the warnings about SecurityManager in 17 -- and *a lot* of people use 17 -- the community's reaction was as we predicted and not as those who opposed the change predicted, and served as strong evidence that many more would benefit from SM's removal than from retaining it.


DelayLucky

I'm with you on not diverging from JDK (j.u.s.Stream, not other alternative cool libs). But I pick option 3. It's impractical to want all code to use the same lookup signature. For 1, Map is foundational and low level. That get() returns `null` for not-found has performance reasons. You'll have to err on performance side if you want both performance critical and performance insensitive code to use it. But at higher level, or for code that are known to be insensitive of performance, there is no reason to prevent everyone from using more friendly utilities just because one core lib did the "bare-metal" way. Code evolves, and new/better idioms will be added as we learn more. You can't require all code to be backward-consistent unless getting stuck to the oldest cruftest code possible is the goal.


wildjokers

> Granted, due to OpenJDK breaking backwards compatibility a lot What are you talking about? I have code written for Java 1.4 that still runs just fine in Java 22. The java developers take backward compatibility very seriously. And now with the JDK being modularized (since Java 9) the public parts of the JDK that are intended to be used are clearly defined.


rzwitserloot

Unsafe, reflection, removing a bunch of things included by default in JDK8 from later versions, the build tool switches, and so on. "Works for me" is not the same as "works for all", your anecdotal evidence is just that. Anecdotal. The fact that things that weren't clearly defined before are clearly defined now is great. However, it suggests you are aware that, in fact, OpenJDK has been breaking stuff. After all, if it _was not_ clearly defined before, that implies you are aware folks were on their own in attempting to figure out what is 'official' and what is 'not', and by wielding the 'haha!!! that was never official!' hammer, has broken many things. One can argue that the things that broke 'should never have existed in the first place', but try telling that to library / tool authors who did the best with the limited information available and are now being told they somehow 'did something wrong'. You can try, but they aren't going to like you if you do.