projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.87k stars 2.38k forks source link

Support Javaslang collections in @Wither #1063

Open udalrich opened 8 years ago

udalrich commented 8 years ago

Javaslang is an framework that adds useful functionality, such as immutable collections with many common streaming actions available as a built-in method.

It would be useful if the types of collections that were supported by Wither included these collections.

One potential complication is that the Javaslang interfaces do not implement the java.util interfaces, which is a good thing in general. (None of their methods throw UnsupportedOperationException.) It does mean that this is not just an extension to how java.util.Collection fields are implemented.

dabraham02124 commented 8 years ago

That would be very useful for me as well.

I've been using lombok to make my objects immutable, and javaslang to get collections that are syntactically immutable as well (I used to use the guava collections, but the javaslang ones have all the higher order functions built in, and come with Tuples and Try statements, and... It's just less boilerplate).

sir4ur0n commented 7 years ago

Javaslang was renamed to Vavr.

I like this idea, and actually feel the same need. Vavr encourages and provides many immutable collections. Currently in our code we use a lot @Wither for our model objects (more fluent English code), but for all Vavr collection fields we write by hand such a method:

// MyClass.java

// This is a io.vavr.collection.List, not a java.util.List
private List<String> comments;

public MyClass withComments(Function<List<String>, List<String>> mapper) {
  return new MyClass(field1, field2, ..., mapper.apply(comments), fieldN);
}

This allows us to write code like this:

MyClass withNewComment = loadMyClass()
  .withComments(comments -> comments.append("My latest comment!"));

With this method, we can manipulate the previous immutable collection in whatever way we wish:

MyClass withNewComment = loadMyClass()
  // Append a comment
  .withComments(comments -> comments.append("My latest comment!"))
  // Remove an element
  .withComments(comments -> comments.remove("Comment to remove"))
  // Any manipulation, like filtering
  .withComments(comments -> comments.filter(comment -> !comment.isEmpty()));

On second thought, this is not even linked to Vavr. If you provide Wither methods which, instead of taking a value as param, takes a function converting the previous value in a new value, then it's perfect, and even more flexible.

public <className> with<FieldName>(Function<fieldType, fieldType> mapper) {
  return new <className>(previousFields..., mapper.apply(<fieldName>), nextFields...);
}

This would massively help in coding with immutable values 👍