[HN Gopher] Making Lenses Practical in Java
___________________________________________________________________
Making Lenses Practical in Java
Author : goostavos
Score : 33 points
Date : 2023-01-15 20:19 UTC (2 hours ago)
(HTM) web link (chriskiehl.com)
(TXT) w3m dump (chriskiehl.com)
| javaunsafe2019 wrote:
| I just use Kotlin. Never looked back.
| Garlef wrote:
| Sure. But what does that have to do with lenses?
| tsimionescu wrote:
| The problem this is trying to resolve is creating copies of a
| complex immutable class with some deep fields changed. I do have
| to wonder for a case like this if using a mutable object with a
| deep copy function wouldn't be a better solution, rather than
| adding extra magic to do it more easily as possible...
|
| Edit: The code in the article would become something like
| pendingOrders.map(order -> { copy = order.DeepCopy();
| copy.getApproval() .getConfirmation()
| .setUpdatedOn(LocalDateTime.now())); return copy;
| } )
|
| (of course, we could also get rid of the getters and setters and
| replace them with direct field access, if we take the data class
| concept seriously)
| ImprobableTruth wrote:
| The issue is that this potentially copies a lot of unnecessary
| information. Also, if you depend on object identities
| (reference equality), deep copying will recreate objects even
| if they aren't supposed to change. Furthermore, if you want to
| chain two update functions, you'll deep copy parts of the
| object twice times.
|
| Lenses are "smart" in the sense that they only copy what's
| necessary.
| ivan_gammel wrote:
| A business method on order would do the same without any
| unnecessary overhead and ensuring proper encapsulation and
| consistency of the state that cannot be achieved with getters
| and setters. pendingOrders.map(order ->
| order.approvalConfirmationUpdated(now())
| kitd wrote:
| I believe the intention is to allow operations on
| multilayered business objects to be composable. So your
| _approvalConfirmationUpdated()_ method may actually be made
| up of a sequence of smaller operations, each of which I
| might want to use elsewhere in the application. Lenses
| allow this to happen succinctly, and works better with eg
| the Java streams API.
| ivan_gammel wrote:
| I got that, my point is that such composability is rarely
| better than good old OOP with encapsulation. Enumerating
| all possible state transitions on object interface leads
| to better design than procedural programming (and
| composable operations are procedural programming).
| fedeb95 wrote:
| I don't agree on the fact that lombok has brought us out of the
| dark ages. We used to use it, but it has some drawbacks. One of
| them, it's an additional dependency. This, for a simple thing
| such as pojo, seems a bit overkill to me. The additional amount
| of time used to write some cose isn't worth the risk of
| additional bugs hidden in having one more dependency.
| marginalia_nu wrote:
| Record classes arguably do a lot of the same thing without the
| drawbacks.
| wtetzner wrote:
| The biggest thing missing from records that Lombok provides
| is withers.
| gardenfelder wrote:
| https://github.com/chriskiehl/Deoplice
| Twisol wrote:
| For want of context, this is the library described in the
| article.
| [deleted]
| _old_dude_ wrote:
| I believe this is a case where a named tuple of functions, a
| record, is better than an interface. public
| record Lens<A, B>(Function<A, B> get, BiFunction<A, B, A> with) {
| public <C> Lens<A, C> compose(Lens<B, C> inner) {
| return new Lens<>( inner.get.compose(get),
| (a, c) -> with.apply(a, inner.with.apply(get.apply(a), c)));
| } } Lens<Confirmation, LocalDateTime>
| $updatedOn = new Lens<>(Confirmation::updateOn,
| Confirmation::updateOn);
| ploppyploppy wrote:
| Jesus just use Kotlin.
___________________________________________________________________
(page generated 2023-01-15 23:00 UTC)