Glad to be of help and sorry for the bad formatting. :)
Sure thing. Anything to make this clearer. While we're at it: the name and the argument order of the 'IModel#mapWith' method somewhat bug me. The idea is to combine two models using a BiFunction. Wouldn't 'combineWith' be a more apt name? When implementing it I just didn't want to end up with totally awkward ways to combine IModels, and didn't think much about the name. Also due to the argument order longer functions obstruct finding the "other" model a little, in my opinion. A switch would alleviate that. I feel somewhat silly to even ask this, but would it be reasonable to change this? WDYT? ________________________________ Von: Andrea Del Bene <[email protected]> An: [email protected] Gesendet: 16:13 Freitag, 15.Juli 2016 Betreff: Re: Question about IModel#flatMap Thank you for the clarification! If you don't mind I'd like to improve the JavaDoc for these two methods underling the differences between each other. On 15/07/2016 14:51, Matthias Metzger wrote: > Hi, >> - Why "flat" in the name? It sounds a little misleading to me. With >> Stream is quite clear what flatMap does: it gets new streams out of each >> element end merge them into an unique stream. But in this case I don't >> understand what "flat" means. > generally I tend to agree with your argument, but I believe you could make > this case for Optional<T> equally well. To my knowledge in Java and Scala > (not using Scala, so please correct me if I am wrong) 'flatMap' refers to the > general idea of a function, which takes some value inside a 'container' (the > T in Optional<T>, Stream<T> or IModel<T>) and returns a new container with a > new value inside it. But we actually don't care, whether it is a Stream, an > Optional or an IModel. To make this more tangible take a look at the > following method signatures: > > public <R> Optional<R> flatMap(Function<T, Optional<R>> mapper) {...}public > <R> Stream<R> flatMap(Function<T, Stream<R>> mapper) {...} > public <R> IModel<R> flatMap(Function<T, IModel<R>> mapper) {...} > Except for the 'container' type (Optional, Stream or IModel) they have > exactly the same signature.¹ In Haskell this function is called 'bind'. Just > an equally opaque name (in my personal opinion). So, the reason I chose this > name when proposing the ideas, was to align it with other classes in the > ecosystem already using this name for a method with this sort of signature > and behaviour. As for the origin of the name 'flatMap', I have no idea. :) >> - Looking at the test code I see that the main difference between map >> and flatMap is that the first creates a read-only model, while the >> second uses a wrapping model that might be a read/write one. If so >> wouldn't be better to provide a second map method with a WicketConsumer >> as additional parameter? Example: Model.of(person).map(Person::getName, >> Person::setName); > That is certainly possible, but we would lose the ability to return whatever > IModel implementation we want. As it stands now, we are able to return a > MapModel, a ListModel, a LoadableDetachableModel and whatever IModel we can > think of. In the test case it just happens to be a Model, where the setObject > method has been implemented. > > Regards,Matthias > > ¹ We might derive the following general signature for 'flatMap', (ignore > this, if it doesn't make sense, since we cannot actually express this in > Java):public <R, M<R>> M<R> flatMap(Function<T, M<R>> mapper) { ... } > > Von: Andrea Del Bene <[email protected]> > An: [email protected] > Gesendet: 13:22 Freitag, 15.Juli 2016 > Betreff: Question about IModel#flatMap > > Hi guys, > > I need some help with the new method IModel#flatMap as I don't > completely get the idea behind it. I've got two main questions: > - Why "flat" in the name? It sounds a little misleading to me. With > Stream is quite clear what flatMap does: it gets new streams out of each > element end merge them into an unique stream. But in this case I don't > understand what "flat" means. > - Looking at the test code I see that the main difference between map > and flatMap is that the first creates a read-only model, while the > second uses a wrapping model that might be a read/write one. If so > wouldn't be better to provide a second map method with a WicketConsumer > as additional parameter? Example: Model.of(person).map(Person::getName, > Person::setName); > > Cheers. > > Andrea. > > >
