<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Thanks for taking a look Nir, I really appreciate it :)</p>
    <div class="moz-cite-prefix">On 26/10/2025 13:56, Nir Lisker wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div>When I need to combine observable values I usually do
          something like:</div>
        <div><br>
        </div>
        Bindings.createDoubleBinding(() -> 
        width.get() / height.get(), height, width);
        <div><br>
        </div>
        <div>which is much less cumbersome than subclassing (although a
          bit less performant I think). It works for an arbitrary number
          of observables (including) observable lists/sets/maps too:</div>
      </div>
    </blockquote>
    <p>You're right, I forgot about the existence of the Bindings class,
      and the helpers it has added for these cases.  I barely use it
      since the addition of fluent bindings.  That version is a lot more
      compact and a bit more workable.</p>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com">
      <div dir="ltr">
        <div><br>
        </div>
        <div>Bindings.createDoubleBinding(() ->  list.getFirst() /
          height.get() * map.get("A"), height, list, map); // assume
          this makes sense somehow</div>
        <div><br>
        </div>
        <div>ReactFX, which is the go-to library for such extension, has
          a 'combine' method that work like this:</div>
        <div><br>
        </div>
        <div>Val.combine(height, width, (h, w) -> w / h);<br>
        </div>
      </div>
    </blockquote>
    <p>I'm aware of this, and it is something to be considered as an
      addition.  It is similar to the argument where there is a
      `Subscription.combine` and `subscription.and`, one being static
      and the other being a fluent method.  I think however we shouldn't
      be relying on ReactFX too much anymore these days (I haven't used
      it in years now).  The primary reason for that is that ReactFX had
      to introduce new property classes which are limited in how well
      they can interop with existing JavaFX code.  With the fluent
      bindings additions the need for ReactFX is limited.  That is not
      to say ReactFX doesn't offer anything interesting anymore :)<br>
    </p>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com">
      <div dir="ltr">To assess the proposal, I tried to write your JEP
        examples with the current JavaFX.
        <div><br>
        </div>
        Multi-stage chain (not sure how you mapped to a Point3D from a
        Point2D and a number):
        <div><br>
        </div>
        ObjectBinding<Point2D> point2d =
        Bindings.createObjectBinding(() -> new Point2D(x.get(),
        y.get()), x, y);<br>
        ObjectBinding<Point3D> point3d =
        Bindings.createObjectBinding(() -> new
        Point3D(point2d.get().getX(), point2d.get().getY(), z.get()),
        point2d, z);
        <div><br>
          Combining chains:</div>
        <div>
          <div style="padding:0px 2px">
            <div style="">
              <p style="margin:0px"><br>
                ObjectBinding<Point2D> point1 =
                Bindings.createObjectBinding(() -> new
                Point2D(x.get(), y.get()), x, y);</p>
              <p style="margin:0px">ObjectBinding<Point2D> point2
                = Bindings.createObjectBinding(() -> new
                Point2D(x.get(), y.get()), x, y);<br>
                ObjectBinding<Line2D> line =
                Bindings.createObjectBinding(() -> new Line2D(point1,
                point2), point1, point2); // Line2D is not a JavaFX
                class</p>
              <br>
              Using a default value:</div>
            <div style=""><br>
            </div>
            ObservableValue<Point2D> point1 =
            Bindings.createObjectBinding(() -> new Point2D(x.get(),
            y.get()), x, y).orElse(Point2D.ZERO);</div>
        </div>
        <div style="padding:0px 2px"><br>
        </div>
        <div style="padding:0px 2px"><br>
        </div>
        <div style="padding:0px 2px">Some observations:</div>
        <div style="padding:0px 2px">Bindings returns a Binding rather
          than an ObservableValue and also has primitive specialization
          versions that have their unique methods (add, subtract...).
          These methods, however, can be replicated with fluent bindings
          and they also have the "known" subtle GC issue for the
          intermediary values.</div>
      </div>
    </blockquote>
    Yes, I don't think we should cater to primitive specializations.
    Bindings tend to be high level enough (often eventually tied to a
    UI) that it makes little sense to "optimize" these at the cost of 8x
    more variants. The GC issues are often insidious, and my problems in
    that area have largely disappeared with the addition of the fluent
    bindings and subscribe API's.  This is why I'm hesitant to use API's
    from the Bindings class, and why I think FX should offer
    alternatives in that area.<br>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com">
      <div dir="ltr">
        <div style="padding:0px 2px">Also, static imports can make these
          calls less ceremonious: createObjectBinding(() -> new
          Point2D(x.get(), y.get()), x, y);<br>
        </div>
      </div>
    </blockquote>
    Static imports are not really a plus for any argument in my view :) 
    Compare AssertJ and Hamcrest to see what I mean.<br>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com">
      <div dir="ltr">
        <div style="padding:0px 2px"><br>
        </div>
        <div style="padding:0px 2px">The proposal is more ergonomic
          with its fluency for a couple of values, but I'm not sure it
          solves enough problems that the current mechanism can't.</div>
      </div>
    </blockquote>
    <p>It is an extension on the fluent API, it doesn't introduce
      anything that isn't possible currently, just like `map` and
      `flatMap` didn't introduce anything new, nor did `subscribe`.  It
      is intended to be a more discoverable, fluent and modern API, and
      to fill a gap where one has to go from the fluent binding model to
      a static helper class model as soon as you go from mapping just
      one source to needing two or more sources.<br>
    </p>
    <p>--John<br>
    </p>
    <blockquote type="cite"
cite="mid:CA+0ynh9NHeF=-7tLyGjtj6BbK-VVe8UtoR3deKGkxjTf29d=XQ@mail.gmail.com"><br>
      <div class="gmail_quote gmail_quote_container">
        <div dir="ltr" class="gmail_attr">On Sun, Oct 26, 2025 at
          11:59 AM John Hendrikx <<a
            href="mailto:john.hendrikx@gmail.com" moz-do-not-send="true"
            class="moz-txt-link-freetext">john.hendrikx@gmail.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">JEP:
          <a
href="https://gist.github.com/hjohn/611acb65769b68a845b8919c62a3e99a"
            rel="noreferrer" target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">https://gist.github.com/hjohn/611acb65769b68a845b8919c62a3e99a</a><br>
          <br>
          Hi everyone,<br>
          <br>
          I'd like to propose an extension to the fluent bindings API on<br>
          ObservableValue (map, flatMap, orElse) which were introduced
          in JavaFX<br>
          19 over 3 years ago.<br>
          <br>
          The API currently is very powerful when dealing with a single<br>
          observable, but lacks support when dealing with multiple
          observables. <br>
          For example, let's say you want to compute a width/height
          ratio.  You<br>
          could write this:<br>
          <br>
              ObservableValue<Double> ratio = width.map(w -> w
          / height.get());<br>
          <br>
          ... but you'll quickly find that such an observable will not
          update<br>
          itself when height changes, only when width changes.<br>
          <br>
          The go-to solution for this is currently:<br>
          <br>
              DoubleBinding ratio = new DoubleBinding() {<br>
                  { bind(width, height); }<br>
          <br>
                  protected double computeValue() { return width.get() /<br>
          height.get(); }<br>
              }<br>
          <br>
          My proposal would extend ObservableValue with a new `with`
          method that<br>
          returns an intermediate stage that can be easily converted
          back to an<br>
          ObservableValue:<br>
          <br>
              ObservableValue<Double> ratio =
          width.with(height).map((w, h) -> w /<br>
          h);  // yields a ratio that updates whenever w or h changes<br>
          <br>
          Or for example:<br>
          <br>
               ObservableValue<Point> point =
          x.with(y).map(Point::new);  //<br>
          yields a Point that updates whenever x or y changes<br>
          <br>
          The intermediate stage would not be an observable value
          itself.  This<br>
          limits the API surface, and makes this proposal fairly
          lightweight and<br>
          much easier to implement.<br>
          <br>
          Please see the JEP for the full proposal.  I look forward to
          your feedback!<br>
          <br>
          --John<br>
          <br>
          <br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>