Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 21:44

    danieldietrich on v1.0.0

    Fixes malformed .travis.yml (#2… (compare)

  • Jan 31 2019 21:44
    danieldietrich closed #2369
  • Jan 31 2019 21:31
    codecov-io commented #2369
  • Jan 31 2019 21:31
    codecov-io commented #2369
  • Jan 31 2019 21:31
    codecov-io commented #2369
  • Jan 31 2019 21:18

    danieldietrich on v1.0.0

    Simplification (#2367) (compare)

  • Jan 31 2019 21:18
    danieldietrich closed #2367
  • Jan 31 2019 21:18
    danieldietrich closed #2368
  • Jan 31 2019 21:18
    danieldietrich labeled #2368
  • Jan 31 2019 21:14
    danieldietrich labeled #2369
  • Jan 31 2019 21:14
    danieldietrich labeled #2369
  • Jan 31 2019 21:14
    danieldietrich milestoned #2369
  • Jan 31 2019 21:14
    danieldietrich opened #2369
  • Jan 31 2019 21:14

    danieldietrich on travis-yml-fix

    Fixes malformed .travis.yml (compare)

  • Jan 31 2019 21:10
    codecov-io commented #2368
  • Jan 31 2019 21:10
    codecov-io commented #2368
  • Jan 31 2019 21:10
    codecov-io commented #2368
  • Jan 31 2019 21:10
    codecov-io commented #2368
  • Jan 31 2019 21:10
    codecov-io commented #2368
  • Jan 31 2019 20:51
    danieldietrich opened #2368
Daniel Dietrich
@danieldietrich
Yes that’s right, @rojanu. I suggest to use 0.10.4. It is feature complete and bullet proof, used by many people in real world projects. The version is just a number. The project was formerly called Javaslang, which was at v2.x. With the new name Vavr, I reset the version numbering. The 0.10.x version is still maintained. 1.0 needs time which I currently do not have because I lead a company since the start of 2021 and we have many exciting open source projects. Vavr has still a special place in my heart. As long as it is useful for the Java community, we all will be there to support you.
Daniel Dietrich
@danieldietrich

Btw - the company is TypeFox. We are searching software engineers located in Germany (or willing to relocate)... Come and join us!

TypeFox
austek
@rojanu
what's blocking, which issues need help, I'll try to help
Daniel Dietrich
@danieldietrich
Thank you @rojanu, that is kind of you. I got my hands on Vavr this weekend. Mainly I need to reorganize the API (collections vs controls). This is a bigger issue, I need to finish that on my own. I will let you know if there are other things...
wenhoujx
@wenhoujx
hello, does Future#await(timeout) throw TimeoutException if timeout exceeds? does it then cancel the future?
NicklasWallgren
@NicklasWallgren
I'm looking for a ifInvalid(Consumer consumer) for the Validation interface, is there something similar available?
13 replies
Daniel Dietrich
@danieldietrich
@wenhoujx you will find the answer in the javadoc. Spoiler: it throws a TimeoutException
Daniel Dietrich
@danieldietrich
πŸ“¦ We just released vavr 1.0.0-alpha-4 πŸŽ‰
Feedback welcome!
nishantpandit
@nishantpandit

Good day experts.
I would like to know what the best way to do this is - I have a list of customers and within that list is a list of countries they have been to. If a customer has been to a tropical country then he needs to be added to the list. I have it this way in traditional java. Could you tell me the best way to achieve this in vavr?

List<Customer> customersInTropicalCountries = new ArrayList<>();
for (val customer : people.getCustomers()) {
for (val countryVisited : customer.getCountriesVisited()) {
if (countryVisited.isTropical()) {
customersInTropicalCountries.add(customer);
}
}
}

Daniel Dietrich
@danieldietrich

Good day, Sir!

I translated your statement based code to something more functional. I think you could also achieve the same with plain Java Streams, but it is a bit more verbose if you use the collect calls. Here is a Vavr version, a direct translation of your requirements:

// use io.vavr.collection.List instead of java.util.List
var customersInTropicalCountries = people.getCustomers().map(customer ->   // I have a list of customers
    customer.getCountriesVisited()      // and within that list is a list of countries they have been to
        .filter(countryVisited -> countryVisited.isTropical()) // If a customer has been to a tropical country
        .map(countryVisited -> customer) // then he needs to be added to the list
);
4 replies
(I just did that in a text editor and did not test it)
You might want to do a final .distinct() in order to get sure that each customer appears only once in the list. Your original code could be modified by using a Set instead of a List.
In order to get .distinct() work correctly, Customer needs to have a proper implementation of equals and hashCode.
Geovanny Mendoza
@Geovanny0401

I have a question, can I work with the vavr library and vert.x at the same time? Additionally applying the CQRS pattern with this two technologies, how productive or feasible can it be? About two years ago I worked with Java 8 + vavr and CQRS, I found it very good.

Thanks.

chefhoobajoob
@chefhoobajoob
our team uses vavr, vertx, and rxjava 2 together across several projects and they compliment each other nicely
rxjava's used for async processing together with vertx, and vavr is used with synchronous flows / processing
Geovanny Mendoza
@Geovanny0401
@chefhoobajoob thanks
sergio200801
@sergio200801
Hi
@danieldietrich I hope everyone is well, I am here because I want to learn how to work with VAVR. How can you help me in guiding me. About functional programming I have knowledge of the basics.
sergio200801
@sergio200801
Apart from the documentation, what resources can you recommend such as repositories, books, etc.
1 reply
dbear496
@dbear496
Is there a way to get a CheckedFunction1 from a CheckedConsumer? Or must I use function1 = (t) -> {consumer.accept(t); return null;}? Bonus points if I can choose my own return value or have the return value come from a Supplier.
11 replies
dbear496
@dbear496
Converting the other way (i.e. getting a Consumer from a Function1 by discarding the result) also seems to be a trouble spot.
dbear496
@dbear496
Though I suppose using Consumers at all is not really the functional way. I recall the vavr guide saying that void return types are ugly.
Evangelos Parchas
@eparchas

Hi all and thanks for the great library! I am trying to write a Stream.unfoldRight but I am getting some compiler errors I cannot seem to understand. Here is the code:

Stream<Tuple2<Point, BigDecimal>> points = Stream.<StreamState, Tuple2<Point, BigDecimal>>unfoldRight(startState, ss -> {
            Option<Tuple2<Tuple2<Point, BigDecimal>, StreamState>> next = ss.next();
            return next;
        });

And this is the error I get:

Type mismatch: cannot convert from Option<Tuple2<Tuple2<Point,BigDecimal>,StreamState>> to Option<Tuple2<? extends Tuple2<Point,BigDecimal>,? extends StreamState>>Java(16777235)

The following however compiles:

Stream<Tuple2<Point, BigDecimal>> points = Stream.<StreamState, Tuple2<Point, BigDecimal>>unfoldLeft(startState, ss -> {
            return Option.some(Tuple.of(ss, Tuple.of(Point.of(1d, 1d), BigDecimal.ONE)));
        });

while if I explicitly assign it to a variable it doesn't:

Stream<Tuple2<Point, BigDecimal>> points = Stream.<StreamState, Tuple2<Point, BigDecimal>>unfoldLeft(startState, ss -> {
            Option<Tuple2<StreamState, Tuple2<Point, BigDecimal>>> some = Option.some(Tuple.of(ss, Tuple.of(Point.of(1d, 1d), BigDecimal.ONE)));
            return some;
        });

I understand this is primarily a Java issue, but any ideas are welcome.

Nirmalya Sengupta
@baatchitweet_twitter
Hello all! Need some help on Set operations. Let us say I have a set like: Set.of(SomeClass("A",1), SomeCLass("B",5), SomeClass("C",7);
I need to update an entry in this: Set.of(SomeClass("A",2),SomeClass("B",5),SomeClass("C",7)
Nirmalya Sengupta
@baatchitweet_twitter
Basically, I am accumulating a new value for the Integer field in SomeClass. Assume that the equals() and hash() have been overridden, using the String field.
What is a proper, idiomatic, functional way to achieve this? Anything like putIfAbsent with a bifunction which does the accumulation?
1 reply
Devin Fee
@dfee

I'm running into an issue between {io.grpc.Context, java.util.concurrent.CompletableFuture, io.vavr.Future}.
It seems that doing a Future.fromCompletableFuture(someCompletableFuture) loses the gRPC Context.

I'm not sure if this is an implementation detail (and shouldn't be relied on), but it seems that someCompletableFuture.thenApply(func1).thenApply(func2)don't suffer from the problem of switching threads (and thus losing context).
I don't know if I can rely on someVavrFuture.map(func1).map(func2) to also happen in the same thread?
i.e. i'm not sure if my problem is just building my initial io.vavr.Future (and then through any downstream maps, the thread (and thus thread context) will be the same), or if i basically can't use vavr Futures because any thread context will go missing.

lastly, i know that my code's public API needs to provide CompletableFutures, so I'll need to call future.toCompletableFuture(). is this another point where my thread context will go missing?

i did find this issue (vavr-io/vavr#1530) that seems to suggest that the same thread will be re-used, but i'm not sure if this is something to be relied on.

hope this channel is still active. thank you!

Devin Fee
@dfee
after a bunch of testing, it seems that Future.onComplete() uses my provided executor, but Future.map() does not. i'm struggling a bit to follow the code into FutureImp however.
Devin Fee
@dfee

30 tests later, and i've narrowed it down to introducing a flatMap(v -> Future.fromCompletableFuture(CompletableFuture.completedFuture(v))) (with any variation of executor supplied, including guava's MoreExecutors.directExecutor and swapping completedFuture for supplyAsync).

what's strange is that it doesn't seem to happen when i just do flatMap(v -> Future.of(directExecutor(), () -> v)).

Devin Fee
@dfee
to make this easier, and increase the likelihood someone can help, i've created a minimal test set demonstrating my problems: https://github.com/dfee/future-test
Devin Fee
@dfee
it seems there is a bug (or a misunderstanding) of the usage of executor provided to Future.fromCompletableFuture as shown here
  @Test
  void testFuture_FromCompletableFuture_ContextExecutor__failure() {
    assertHandler(
        (contextValue) ->
            Future.fromCompletableFuture(
                    Context.currentContextExecutor(EXECUTOR),
                    CompletableFuture.completedFuture(getContextValue()))
                .map(assertReturnValueEquals(contextValue))
                // we should be executing on *our* context executor, but apparently we're not
                .map(assertContextValueIsNull())
                .toCompletableFuture()
                .thenApply(assertContextValueIsNull()));
  }

to contribute to a system I'm building for, i need to ensure that a CompletableFuture has access to the "context value on the thread", and that the CompletableFuture returned also has access to the "context value on the thread".

if i don't use vavr's Future at all (effectively sticking with CompletableFuture.thenApply().thenApply(), then i don't have this issue, though i'm also not able to take advantage of the future monad.

Daniel Dietrich
@danieldietrich

Hi @dfee,

Hi,

by looking at the implementation I don't see a problem with the internal use of the Exector at the moment (which does not necessarily mean there is none ;):

// Future.java

@Override
default <U> Future<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper, "mapper is null");
    return transformValue(t -> t.map(mapper));
}

default <U> Future<U> transformValue(Function<? super Try<T>, ? extends Try<? extends U>> f) {
    Objects.requireNonNull(f, "f is null");
    return run(executor(), complete ->
        onComplete(t -> Try.run(() -> complete.with(f.apply(t)))
                .onFailure(x -> complete.with(Try.failure(x)))
        )
    );
}

static <T> Future<T> run(Executor executor, Task<? extends T> task) {
    return FutureImpl.sync(executor, task);
}

// FutureImpl.java

static <T> FutureImpl<T> sync(Executor executor, Task<? extends T> task) {
    return new FutureImpl<>(executor, Option.none(), Queue.empty(), Queue.empty(), (complete, updateThread) ->
        task.run(complete::with)
    );
}

// constructor
private FutureImpl(Executor executor, Option<Try<T>> value, Queue<Consumer<Try<T>>> actions, Queue<Thread> waiters, Computation<T> computation) {
    this.executor = executor;
    synchronized (lock) {
        this.cancelled = false;
        this.value = value;
        this.actions = actions;
        this.waiters = waiters;
        try {
            computation.execute(this::tryComplete, this::updateThread);
        } catch (Throwable x) {
            tryComplete(Try.failure(x));
        }
    }
}

However, the Executor isn't respected when creating the CompletableFuture:

@Override
default CompletableFuture<T> toCompletableFuture() {
    final CompletableFuture<T> future = new CompletableFuture<>();
    onSuccess(future::complete);
    onFailure(future::completeExceptionally);
    return future;
}

That might be one problem. However, you also see problems during mapping a Future, right? Could you provide a minimal working example that does not use any 3rd library code?

Please create an issue if you think it is a bug. I could translate your example to Scala (which we align to) and see, how it behaves.

Ah, I've found your example. Does the RPC's Context create a ThreadLocal? It would be nice to have a bare example that removes all involved library code.
Daniel Dietrich
@danieldietrich
I looked at the latest Vavr version, did you try your example with the latest alpha version? Just to get sure that your problem still exists...
1.0.0-alpha-4
One more question (just for my 'statistics', I am thinking of lifting the minimum Java version required for Vavr) - which Java version do you use? Are you already on Java 17?
Devin Fee
@dfee
unfortunately, upgrading the dependencies did not solve my problem (using 1.0.0-alpha-4) branch. i am still using Java 8.
as to your other question; unfortunately at $job, we're still using 8.
Devin Fee
@dfee

@danieldietrich more than happy to provide an even more minimal impl. however, i'll need to figure out how to identify /which/ executor i'm using.

unfortunately, i've not identified a great way to do this. perhaps creating executors with a single thread, using a threadlocal variable to "put" markers, and then sweep for those markers at the end of the test?

Daniel Dietrich
@danieldietrich

as to your other question; unfortunately at $job, we're still using 8

thank you!

perhaps creating executors with a single thread, using a threadlocal variable to "put" markers, and then sweep for those markers at the end of the test?

yes, it seems that you want to ensure that you use exactly the same same thread from a pool of threads when doing subsequent computations. it would be good to add a unit test to Vavr, in order to ensure we do not have regressions in the future. Of course, I need to check first, if that fits into the computational model of Vavr, also by verifying how Scala's Future behaves. Having a minimal working example will help to verify that in Scala.

nishantpandit
@nishantpandit
Hi, what is the exact difference between peekOption and headOption and when would you use one over the other?
renanreis
@renanreis_twitter
Hi people, why the PartialFunction interface is been deprecated? The javadoc says it will be deprecated together with the Pattern matching features, but isnt java pattern matching still too immature?
1 reply
Daniel Dietrich
@danieldietrich
yes, maybe the interface will still be useful. In scala, the case syntax is syntactic sugar for creating instances of partial functions. I will think about keeping it
renanreis
@renanreis_twitter
@danieldietrich to memoize functions the lib is using a hashmap and synchronizing it. Are there any reasons for not be using a ConcurrentHashMap for example? If that is something you are considering I could open a PR
Daniel Dietrich
@danieldietrich
@renanreis_twitter in fact, there isn't a specific reason. It would be good to get rid of the synchronization code. I would greatly appreciate your PR! (The generator needs to be changed) Thx!
renanreis
@renanreis_twitter

@danieldietrich Thanks for the quick answer.

Just to clarify, some sort of sync is still needed. Because if the memoized function is shared between threads the cache has to be sync.

I tried using a ConcurrentHashMap to avoid full sync, my changes broke a test about recursion, after 3am, I went to sleep and this morning I found this:

https://blog.jooq.org/avoid-recursion-in-concurrenthashmap-computeifabsent/

Apparently we do not have a solution except from the old sync block.

Daniel Dietrich
@danieldietrich
thank you @renanreis_twitter for your investigation! then we will keep it as-is for now πŸ™πŸΌ