<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4" face="monospace">The problem you are grappling with
      here is an important one -- optionality.  What you really want to
      say is that some of the components of your record are required
      (like name), and others are optional, and you are using the
      convention of null to mark which components are not present.  And
      you would like for the notion of which components are optional to
      be part of the programming model, so users and compilers alike can
      ensure correct use.  And, you observe that Java is getting nullity
      control, perhaps those can be used to capture optionality in the
      type system as well.<br>
      <br>
      This is all reasonable, and similar ideas have been discussed.  I
      think it is safe to say there are two camps here: one that finds
      the use of nullity control to capture optionality to be a
      pragmatic approach, and another that views it as mixing concerns. 
      There are arguments on both sides of this debate (we don't have to
      have it again here), but I think it's fair to say that this is one
      of the ideas that is on the table.  (This gets especially
      interesting if we are ever able to instantiate objects nominally,
      because then you could say `new Foo(a:1, z: 26)`, and omit b-y if
      they are optional.  (And we're not going to discuss this
      possibility again for quite some time; there are a lot of
      higher-priority things between here and the possibility of
      there.))  <br>
      <br>
      The topic of using (abusing? distorting?) `with` as a way to
      backdoor optional parameters into the language has come up a
      number of times, and we've consistently said "these are not the
      droids you are looking for."  So while we understand the goal
      (instantiating objects without having to specify all non-required
      parameters), and we agree that the goal is valuable, it is pretty
      clear that this is the wrong way to get there, and that the many
      suggestions to use `with` in this manner are an attempt at
      shortcutting the language-design process to get it sooner by
      piggybacking it on something else.  But we don't work this way. 
      If this is a feature worth having, it is feature worth properly
      designing.  <br>
      <br>
      Cheers,<br>
      -Brian<br>
      <br>
      <br>
    </font><br>
    <div class="moz-cite-prefix">On 3/11/2025 10:48 AM, david Grajales
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CADFQZ74apoy257-6xG9ExU7t-+q3LQL0pqeAY_tJh8Y-RqAudQ@mail.gmail.com">
      
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <p><span>Hi Amber team. I would like to share some thoughts
                based on real use cases I am dealing with at work.</span></p>
            <p><span><br>
              </span></p>
            <pre><span>I know</span> is very<span style="font-family:Arial,Helvetica,sans-serif"> likely you have already thought about something like this and I don't know if this would be the best solution for the use case presented. </span></pre>
            <pre><span style="font-family:Arial,Helvetica,sans-serif">My intention is not to propose this as "the solution" but instead just present a personal use-case based on my actual job and a naive solution that crossed my mind in the first 15 minutes. </span></pre>
            <pre><span style="font-family:Arial,Helvetica,sans-serif">So please pay more attention to the use case and "the problem" rather than the proposed "solution" which is actually just a mean to explain the problem</span></pre>
            <p dir="ltr"><br>
            </p>
            <p dir="ltr"><span>Nowadays to create a new record object we
                must set the value to all it fields, even the ones that
                might be null.</span></p>
            <pre><span>record User (String name, String email){}</span>
<span>var userWithoutEmail = new User ("name", null)</span></pre>
            <p dir="ltr"><span>This is good since it forces us to set
                all fields to a valid state and null can be a valid
                state. This is useful for things like JSON
                serialization; null fields in JSON are usually not
                serialized, which saves some bandwidth, in very large
                JSON structures that only have an small set of mandatory
                fields, this is very common in banks that happens to be
                international, since they usually use the same Core for
                all countries but each country may have different
                requirements (for example in some countries it's
                mandatory for people to provide 2 lastnames but in other
                countries usually you only have one lastname).</span></p>
            <p dir="ltr"><span>To achieve this I usually do the opposite
                of withers, let me introduce you to the "withouts"</span></p>
            <pre><span>record User (String name, String email){</span>
<span>  </span>
<span>   public static withoutEmail(String name){</span>
<span>     </span>
<span>      return new User(name, null);</span>
<span>   }</span>
<span>}</span>
<span>var userWithoutEmail = User.withoutEmail(name);</span></pre>
            <p dir="ltr"><span>The example is very basic for explanatory
                purposes and for a record with only 2 fields this can be
                an overkill, but for bigger records it makes a lot of
                sense, specially if only few fields between dozens are
                actually mandatory.</span></p>
            <p dir="ltr"><span>Why not use a class instead?
                Serialization. records' serialization uses the record
                constructor, which means it's safer since you can make
                format and safety validations in the data before the
                record is built.</span></p>
            <p dir="ltr"><span>nowadays to make sure all the mandatory
                fields are set, I do something like this.</span></p>
            <p dir="ltr"><span>record User (String name, String email){</span><br>
              <span> User{</span><br>
              <span> if(name == null) </span><br>
              <span> throw new IllegalArgumentException("name field it's
                mandatory");</span><br>
              <span> }</span><br>
              <span>}</span><span></span></p>
            <p dir="ltr"><span><br>
              </span></p>
            <p dir="ltr"><span>With derived record creation (or
                something equivalent but for direct creation) and
                nullability it would be possible and very handy to be
                able to declare optional fields that would compile to
                null (or zero in case of primitives)</span></p>
            <p dir="ltr"><br>
              <b><strong>Please ignore the straw man syntax from here.</strong></b></p>
            <pre><span>record User (String name!, String email? ){}</span>
<span>User userWithoutEmail with { name : "name"}</span></pre>
            <p dir="ltr"><span>This would make this feature in java to
                behave similar to TypeScript's interfaces, which are
                used to model data</span></p>
            <pre><span>export interface User {</span>
<span>   name: String!</span>
<span>   email: String?</span>
<span>}</span></pre>
            <p dir="ltr"><br>
              <span>To me one of the most useful use cases of this would
                be for writing unitary tests and mocks. </span></p>
            <p dir="ltr"><span>when writing tests sometimes you want to
                test the behaviour of your contracts (the domain
                objects) when they carry only the bare required fields,
                if one has very large json objects to try out but only a
                small set of mandatory fields usually it's easier to
                write down the json string and pass it to jackson or
                gson, with this we could use the domain object directly.</span></p>
            <p dir="ltr"><br>
              <span>Regular test if the domain object has many optional
                fields</span></p>
            <pre>
<span>record Message (String id, String document, String name, String lastname, String email.... (another 20 fields)){}</span>


<span>var request = </span>
<span>"""{</span>
<span>  id: "XXXXXXX",</span>
<span>  document: "NNN-NNNNN"</span>
<span>}"""</span></pre>
            <pre>
</pre>
            <pre><span>var message = gson.fromJson(request, Message.class);</span>
<span>var res = method2Test(message);</span>
<span>// put your favorite assertion here//</span></pre>
            <pre><span>
</span></pre>
            <pre><pre>this has the issue you don't have help from the compiler in case you want to represent different scenarios (formatting data, invalid fields, etc)</pre><pre>this is why I usually do "whitouts" for this kind of records.</pre><pre>
</pre><pre>record Message (String id, String document, String name, String lastname, String email.... (another 20 fields)){</pre><pre>  public Static Message minimalRequest(String id, String document){</pre><pre>     return new Message (id, document, lastname, email, null, null...);</pre><pre>   // so I have to write all those nulls once</pre><pre>   }</pre><pre>}</pre><pre>var request = Message.minimalRequest(.....);</pre><pre>var res = method2Test<span style="font-family:Arial,Helvetica,sans-serif">(message);</span></pre><pre>// put your favorite assertion here//</pre></pre>
            <p dir="ltr"><br>
              <span>With optional fields in records there could be
                changed for something like this.</span></p>
            <pre><span>record Message (String id, String document, String name?, String lastname?, String email? .... (another 20 nullable fields)){}</span>

<span>Message request  with {id: "XXXXXXXX"; document: "NNN-NNNNNN"}</span>
<span>var res = method2Test(message);</span>
<span>// put your favorite assertion here//</span></pre>
            <pre>I hope this presented use-case it's useful</pre>
            <pre>Best regards!</pre>
            <p dir="ltr"><span></span></p>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>