Re: Reviewing feedback on patterns in switch

2022-02-16 Thread Mark Raynsford
On 2022-02-16T10:49:19 -0500
Brian Goetz  wrote:

> One thing that we have, perhaps surprisingly, *not* gotten feedback on 
> is forcing all non-legacy switches (legacy type, legacy labels, 
> statement only) to be exhaustive.  I would have thought people would 
> complain about pattern switches needing to be exhaustive, but no one 
> has! So either no one has tried it, or we got away with it...
> 

I tried it and liked it. It didn't go unnoticed. :)

-- 
Mark Raynsford | https://www.io7m.com



Re: Reviewing feedback on patterns in switch

2022-01-28 Thread Mark Raynsford
On 2022-01-25T19:46:09 +
Brian Goetz  wrote:

> We’ve previewed patterns in switch for two rounds, and have received some 
> feedback.  Overall, things work quite well, but there were a few items which 
> received some nontrivial feedback, and I’m prepared to suggest some changes 
> based on them.  I’ll summarize them here and create a new thread for each 
> with a more detailed description.  
> 
> I’ll make a call for additional items a little later; for now, let’s focus on 
> these items before adding new things (or reopening old ones.)  
> 
> 1.  Treatment of total patterns in switch / instanceof
> 
> 2.  Positioning of guards
> 
> 3.  Type refinements for GADTs
> 
> 4.  Diamond for type patterns (and record patterns)

Hello!

I'm a little late to the party, as ever, but is there a specific build I
should be looking at so that I can get a better idea of what the current
state of things are?

-- 
Mark Raynsford | https://www.io7m.com



Sealed interfaces with hidden implementation superclasses

2022-01-04 Thread Mark Raynsford
(Apologies for the possible double post: I tried to post this to
amber-dev@ and the message apparently never made it there. I asked
amber-dev-owner@ but got no response there either).

I've run across some behaviour I didn't anticipate with regards to
sealed interfaces. I suspect that it's expected behaviour, but I
feel like maybe the type system is overly constraining in this
particular case.

Imagine a small UI library with a sealed set of primitive components:

  sealed interface Component permits Button, TextView, ImageView {}
  non-sealed interface Button extends Component {}
  non-sealed interface TextView extends Component {}
  non-sealed interface ImageView extends Component {}

The set of primitive components is sealed because doing so simplifies
other parts of the system; more complex components are just aggregates
of the primitives.

Then, in one or more separate modules, we have some platform-specific
implementation classes:

  final class X11Button implements Button
  final class X11TextView implements TextView
  final class X11ImageView implements ImageView

  final class QNXButton implements Button
  final class QNXTextView implements TextView
  final class QNXImageView implements ImageView

This is all fine so far. The problem occurs when one of those
implementations wants to introduce a private abstract superclass 
that contains shared implementation code but that - importantly - isn't
actually intended to ever be observed on its own outside of the module.

Naturally, that superclass wants to implement Component so that it can
provide implementations of the common methods:

  abstract class QNXComponent implements Component
  final class QNXButton extends QNXComponent implements Button
  final class QNXTextView extends QNXComponent implements TextView
  final class QNXImageView extends QNXComponent implements ImageView

The compiler (rightfully) complains that QNXComponent isn't in
the "permits" list of Component. We can obviously remove
the "implements Component" from QNXComponent, but this then
means adding boilerplate @Override methods in each of QNXButton,
QNXTextView, etc, that call the now-non-@Override methods in
the abstract QNXComponent class.

-- 
Mark Raynsford | https://www.io7m.com



Re: New pattern matching doc

2021-01-16 Thread Mark Raynsford
On 2021-01-15T12:02:41 -0500
Brian Goetz  wrote:

> Maurizio had a clever idea for how to rescue this issue.
> 
> As in (not a serious syntax proposal):
> 
>      try-match (x : big-honking-pattern) {
>      // happy-path code
>      }
>      catch (MatchFailException e) { // checked exception
>      // exception captures which sub-pattern failed
>      }
> 

Hah, synchronicity! Yes, I was drafting an email with a suggestion for
something similar, although i used a __MATCH_OR_DIE expression form
that looked like a cast, and an unchecked exception.

Did I just imagine it, or was there a suggestion for something like
this in the past?:

  var Point(var x, var y) = ...

That would have a similar aspect of assertion (as it does in Haskell,
ML, etc) and would obviously need to have the same "match or die"
semantics.

I think something akin to try-match is perfectly reasonable.

-- 
Mark Raynsford | https://www.io7m.com


Re: New pattern matching doc

2021-01-14 Thread Mark Raynsford
On 2021-01-06T15:52:19 -0500
Brian Goetz  wrote:

> I have pushed
> 
> https://github.com/openjdk/amber-docs/blob/master/site/design-notes/pattern-match-object-model.md
> 
> to the amber-docs repo, which outlines the direction for how patterns 
> fit into the object model.

I've been following along with the discussion on patterns and guards,
and I have a concern that I didn't anticipate: The practicality of
using patterns to _parse_. Mostly, I'm eyeing "A possible approach for
parsing APIs" [0].

The issue, as I see it, is that I'm not entirely sure if a failure to
match in such a large nested structure is going to help me construct
a usable _error message_. As you're certainly aware, about 80% of the
code in any good compiler is devoted to giving error messages that are
actually useful to users. If I get a parse error, for example, I want to
know - down to the level of lines and columns - which part of the input
failed to match expectations.

Is matching a structure like that going to be able to provide useful
error messages if input _doesn't_ match? It seems like it just provides
a binary true/false answer. If it's the case that it won't actually
help with giving useful error messages, then I think that reduces the
applicability of patterns to this particular class of problems. It
follows that it also might mean that the nice things we're putting on
top (such as the composition of patterns) won't actually see practical
use, because people end up writing very simple patterns with at most
one level of nesting.

Now, you know me, I'm the first to try to apply pattern matching and
algebraic data types to any and every problem. I'm a little concerned
about possible over-engineering though.

[0]https://github.com/openjdk/amber-docs/blob/master/site/design-notes/pattern-match-object-model.md#a-possible-approach-for-parsing-apis

-- 
Mark Raynsford | https://www.io7m.com



Re: Unexpected compilation error with generic sealed interface

2020-12-28 Thread Mark Raynsford
On 2020-12-28T11:41:36 -0500
Vicente Romero  wrote:

> Hi,
> 
> I believe this to be the same issue already addressed in [1], which has 
> already been fixed in 16 and should be forward-ported to 17,

Looks like it, yes! Didn't realize the same code had been submitted
there.

To be clear: The original symptom was an actual compiler crash. Now we
just get a compilation error ("I cannot be converted to C"). An
error is obviously better than a crash, but I don't think this code
should result in an error at all.

-- 
Mark Raynsford | https://www.io7m.com



Re: Unexpected compilation error with generic sealed interface

2020-12-28 Thread Mark Raynsford
On 2020-12-27T23:40:50 +0100
Remi Forax  wrote:

> Hi Mark,
> this is an interesting snippet, while i struggle to understand why someone 
> want to write a code like that, I is parametrized by T but the only possible 
> subclass implements I so T is useless here,
> anyway, the compiler should not reject that code so it's a bug.

Hello!

I think the original code was a collection of little functional data
structures (Option, List, etc) to try out the combination of records
and sealed classes.

The code above is the result of removing things one by one until the
result was a minimal example that would trigger the error.

-- 
Mark Raynsford | https://www.io7m.com



Unexpected compilation error with generic sealed interface

2020-12-27 Thread Mark Raynsford
Hello!

A friend of mine handed me this example that fails to compile using
JDK 17 EA 3:

~~
final class SealedExample
{
  private SealedExample()
  {

  }

  // Compiles if you remove `sealed` or if `I` is not generic.
  sealed interface I {
final class C implements I { }
  }

  static void f(final I x) {
if (x instanceof I.C) {

}
  }
}
~~

The error is:

~~
src/main/java/SealedRecord.java:14: error: incompatible types:
I cannot be converted to C if (x instanceof I.C) {
^
1 error
~~

The error goes away if you remove the word "sealed" from the
interface. In her words: "It breaks simple things like Option.".

I can see the reasoning required on behalf of the compiler: You've
handed me an I, and by the definition of I, there's exactly one
class that could yield an I: C.

I'm unsure of whether the compiler should be rejecting these
definitions or not.

-- 
Mark Raynsford | https://www.io7m.com



Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Mark Raynsford
On 2020-07-23T12:20:01 -0400
Brian Goetz  wrote:

> In case I wasn't clear, this was a proposal to proceed on _right now_.  
> There's been no comments so far; should I take that as "perfect, ship it?"

Apologies for my lack of participation in these lists lately. I've been
inundated with non-JDK work over the past six months or so.

That said, I've read this proposal multiple times and I can see nothing
to which to object. Best to interpret my silence as agreement. :)

-- 
Mark Raynsford | https://www.io7m.com



Re: Sealed types

2018-11-30 Thread Mark Raynsford
On 2018-11-30T11:16:51 -0500
Brian Goetz  wrote:
> 
> Yes.  As mentioned before, I expect unsealing a _class_ to be more 
> common than unsealing an _interface_, because classes have more tools 
> with which to defend against rogue subtypes.
>

Sounds good, thanks!

Do you have any documentation on how Scala's opt-in (not transitive)
sealing became a source of bugs? This is news to me, I actually would
have expected the opposite.

-- 
Mark Raynsford | http://www.io7m.com



Re: Sealed types

2018-11-30 Thread Mark Raynsford
On 2018-11-27T17:20:54 -0500
Brian Goetz  wrote:

> Since we’re already discussing one of the consequences of sealed types, 
> let’s put the whole story on the table. These are my current thoughts, 
> but there’s room in the design space to wander a bit.

Is the intention to allow this:

module M;
package x.y.z;
__Sealed interface I { }
class A implements I {}
__Unsealed interface B extends I {}

Then, in another compilation unit:

module N;
package a.b.c;
class C implements B {}

... and then:

module O;
package d.e.f;
I x = new C();
switch (x) {
  case A: ...
  case B: ...
}

The switch should be considered exhaustive, because both A and B are
direct children of the sealed interface I. However, it's possible for
me to add extra subtypes to B because B isn't sealed, and I still get
exhaustiveness without mentioning C explicitly.

I would expect the following *not* to be exhaustive:

module O;
package d.e.f;
I x = new C();
switch (x) {
  case A: ...
  case C: ...
}

I've mentioned modules and packages explicitly above because it's not
clear to me if explicitly unsealed interfaces are permitted to have
implementations in different packages or modules without also losing
exhaustiveness.

-- 
Mark Raynsford | http://www.io7m.com



Re: Intersection types in patterns

2018-10-20 Thread Mark Raynsford
On 2018-10-20T12:42:42 -0400
Brian Goetz  wrote:
> > Is there a situation where you could have reached that case without
> > having a reference to p? If I've understood so far:
> > 
> >  SomeSuperTypeOfPoint q;
> > 
> >  switch (q) {
> >case Point(var x, var y) p: ... // p == q and p : Point
> >  }  
> 
> Yes, you could have gotten there via
> 
> switch (getAnObjectForMe()) { 
> case Point(var x, var y) p: 
> }

That is a good point!

> > So in the Point case there, you could do something with the fields
> > x, y  
> 
> Careful, binding variables — they may be copied from fields, but we don’t 
> know that.  Deconstruction patterns are really like methods that 
> conditionally return multiple values; but methods don’t have to read fields 
> to return a value.

Right.

> > How is the resulting declaration scoped? What if I do...
> > 
> >  SomeSuperTypeOfPoint q;
> > 
> >  switch (q) {
> >case Point(var x, var y) p:  ... // p == q and p : Point
> >case OtherPoint(var x, var y) p: ... // p == q and p : OtherPoint
> >  }  
> 
> This is well handled by the flow-scoping rules (and one of the reasons we 
> chose such a scoping). 

Yes, that's what I suspected.

>  So the first p is in scope for the statements that follow the first
>  case, and similar for the second.  If you fall through from the first
>  to the second, then there are competing overlapping definitions of
>  `p`, and you get an error.  So scoping is not a reason not to do this
>  (you could have collisions on x and y too, which would be handled by
>  the same set of rules), but I think what you’re getting at here is “I
>  don’t see how its needed, you can always pull the switch target into a
>  variable, and cast it.”  

Right, I'm up to speed. I retract my con!

-- 
Mark Raynsford | http://www.io7m.com



Re: Intersection types in patterns

2018-10-20 Thread Mark Raynsford
On 2018-10-20T11:40:39 -0400
Brian Goetz  wrote:
>
> One area where we have a question about whether to support an optional 
> binding variable is in deconstruction patterns:
> 
>      case Point(var x, var y) p: ...
> 
> Sometimes it is desirable to bind the cast target as well as its 
> components (Scala and Haskell support this with the `var@pattern` 
> syntax.)  Can anyone offer pros/cons here for supporting this based in 
> real-world experience?  (Assume someone has already said "I could 
> imagine how that might be useful.")

Is there a situation where you could have reached that case without
having a reference to p? If I've understood so far:

  SomeSuperTypeOfPoint q;

  switch (q) {
case Point(var x, var y) p: ... // p == q and p : Point
  }

So in the Point case there, you could do something with the fields
x, y (including possibly mutating them) but then pass the sharper-typed
p alias to some other method that can only take Points and not
SomeSuperTypeOfPoints? Is the type of q assumed to be Point in that
case (via the shiny new intelligent typing rules)?

How is the resulting declaration scoped? What if I do...

  SomeSuperTypeOfPoint q;

  switch (q) {
case Point(var x, var y) p:  ... // p == q and p : Point
case OtherPoint(var x, var y) p: ... // p == q and p : OtherPoint
  }

I'm not sure how this would interact with the current
scoping/fallthrough rules.

In Haskell, @ patterns are often needed because of the support for
equational definitions that immediately match upon their arguments. For
example:

  length :: forall a. [a] -> Integer
  length []   = 0
  length (x : xs) = 1 + (length xs)

In other words, there was never a binding in scope that referred to the
original list, only the deconstructed parts. I can't think of any case
in Java where that could happen. I guess what I'm saying is that the
con would be an extra set of syntax rules for something that might not
actually be useful in Java, as it doesn't have these sorts of
equational definitions and AFAIK there should always be a binding in
scope upon which the matching is being performed.

-- 
Mark Raynsford | http://www.io7m.com



Re: Updated pattern match documents

2018-09-10 Thread Mark Raynsford
On 2018-09-07T14:41:12 -0400
Brian Goetz  wrote:

> I've updated the documents regarding pattern matching, and uploaded them 
> here:
> 
> http://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html
> http://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html

I need to give the semantics document another serious read (I don't
care much about syntax, personally), but at first impression, I
particularly like how nullability has been handled. Nullable patterns
seem like a great way to support both null-hostile and null-tolerant
programming.

-- 
Mark Raynsford | http://www.io7m.com



Re: Compile-time type hierarchy information in pattern switch

2018-04-04 Thread Mark Raynsford
On 2018-04-03T12:36:43 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> Here's one that I suspect we're not expecting to recover terribly well 
> from: hierarchy inversion.  Suppose at compile time A <: B.  So the 
> following is a sensible switch body:
> 
>  case String: println("String"); break;
>  case Object: println("Object"); break;
> 
> Now, imagine that by runtime, String no longer extends Object, but 
> instead Object absurdly extends String.  Do we still expect the above to 
> print String for all Strings, and Object for everything else?  Or is the 
> latter arm now dead at runtime, even though it wouldn't compile after 
> the change?  Or is this now UB, because it would no longer compile?

I'm still giving thought to everything you've written, but I am
wondering: How feasible is it to get the above to fail early with an
informative exception/Error?

-- 
Mark Raynsford | http://www.io7m.com



Re: Expression switch exception naming

2018-03-30 Thread Mark Raynsford
On 2018-03-30T16:17:35 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> OK, we have a terminology confusion over the term "exhaustiveness 
> checking."

Got it, I'm up to speed!

> But, your point is taken; *not* having a default in a situation that 
> requires exhaustiveness acts as a type-check on that exhaustiveness, and 
> saying default will then cover up any sins.  I get it.

Yep, that's the bit I'd hate to lose (not that I actually have it right
now :]).

-- 
Mark Raynsford | http://www.io7m.com



Re: Expression switch exception naming

2018-03-30 Thread Mark Raynsford
On 2018-03-30T14:39:30 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> To be clear, I was describing:
>   - We'd always do exhaustiveness checking for expression switches
>   - A default / total pattern always implies exhaustive
>   - We'd additionally consider an expression switch to be exhaustive if 
> all known enums are present _and_ the enum type is in the same module as 
> the switch
> 
> But that's probably too fussy.

That seems rather unpleasant: If my API returns values of a sealed type
and I expect API consumers to match on/switch on values of that type
(consider something like Scala's Either type), it'd be very nasty if
they didn't get exhaustiveness checks just because the consumers live
outside of my module.

Perhaps I've misunderstood and that wasn't what was intended?

Additionally... If we're tying things to modules, what will happen to
OSGi? The module system there isn't integrated with the JPMS in any
sense yet. I suppose you could sort of argue that the entire OSGi
system lives in the unnamed module, but ...

-- 
Mark Raynsford | http://www.io7m.com



Re: Expression switch exception naming

2018-03-28 Thread Mark Raynsford
On 2018-03-28T14:15:33 +0100
Gavin Bierman <gavin.bier...@oracle.com> wrote:
>
> A worry here might be that other future features might want to raise this 
> exception, and the name will be less applicable. Perhaps 
> "UnexpectedValueException"?

Is this really a worry? I mean, it's not really as if unchecked
exception types are in short supply. I'd be in favour of adding more
and more specific exceptions so that instances of them indicated
*exactly* what went wrong (rather than "one of these several different
language constructs went wrong in some way").

-- 
Mark Raynsford | http://www.io7m.com



Re: break seen as a C archaism

2018-03-15 Thread Mark Raynsford
On 2018-03-15T14:50:45 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> > If you are reconsidering options, reconsider "yield", meaning
> >"break current context with this value".  
> 
> Still feeling a little burned by first time we floated this, but willing 
> to try another run up the flagpole

Silly idea, but... *puts on fireproof suit*:

  "finally x;"

-- 
Mark Raynsford | http://www.io7m.com



Re: Record construction

2018-03-14 Thread Mark Raynsford
On 2018-03-14T13:10:16 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> One possibility, as discussed, is to attach these as their own thing: 
> "require x > 0", which is code that is narrowly targeted enough to lift.
> 
> Another is to raise the Preconditions library to more than just a 
> library...

To me, it seems like the former would be better in general: A
boolean-valued expression, transformed to a string in a similar manner
to assertions in order to provide a nice error message. I think the
bytecode would probably need to wrap any exception raised by the
expressions in an IllegalStateException that distinguishes it from
an exception raised due to the check failing (I think a check raising
its own exception should be considered to be a bug).

I'd personally not want to see any particular precondition library have
elevated status. Various libraries are designed to work in different
environments. For example, I wrote a small thing that I tend to use
everywhere now that's designed to be zero-allocation in the case of
non-failing checks:

  https://io7m.github.io/jaffirm/

If, for example, the Preconditions library didn't make this guarantee,
then I'd be hesitant to use preconditions on records at all in any
code that did want that zero-allocation guarantee. The point is less
about one API being preferred over another, and more about making sure
that people actually do put validation everywhere because we can give
assurances that the performance is good.

> Either way, though, I think better support for DBC is an orthogonal 
> feature; I don't think it significantly constrains our ability to 
> deliver a records feature without it.

Probably not, no. I must admit that the handling of non-null record
arguments prompted me to bring this up (because adding
Objects.requireNonNull() to every class I ever write adds up to a lot
of boilerplate). I need to go back and read up on the current status of
null handling, but I feel like it'd be nice if it could be handled via
a generic "requires" mechanism along with all of the other checks - if
we don't have a more terse way to say "this field must never be null"
in the field declaration, of course!

-- 
Mark Raynsford | http://www.io7m.com



Re: Record construction

2018-03-14 Thread Mark Raynsford
On 2018-03-14T10:55:54 -0400
Brian Goetz <brian.go...@oracle.com> wrote:
>
> The constructor syntax
> 
>      record Point(int x, int y) {
>      Point {
>      }
>      }
> 
> is proposed as a shorthand for an explicit default constructor:
> 
>      record Point(int x, int y) {
>      Point(int x, int y) {
>      }
>      }
> 

One small thing: Could the contents of this constructor be lifted into
JavaDoc? The fact that preconditions are supposed to appear in
documentation is something that seems to be sadly lacking in almost all
of the "design by contract" systems for Java. If I write a constructor
like:

 record Point(int x, int y) {
   Point {
     Preconditions.mustBeNonNegative(x);
 Preconditions.mustBeNonNegative(y);  
   }
 }

It'd be nice if those statements could be made visible in the JavaDoc.

I think this was covered slightly in some of the other discussion about
"requires", but it fizzled out (unless I missed something).

-- 
Mark Raynsford | http://www.io7m.com



Re: [patterns] AND patterns, OR patterns, fall though

2017-11-04 Thread Mark Raynsford
On 2017-11-04T18:20:44 -0400
Brian Goetz <brian.go...@oracle.com> wrote:

> In theory, patterns can be combined with AND and OR to produce new patterns,

The OR patterns do indeed look good. I'd have to play with a prototype
to see what works and what doesn't though.

-- 
Mark Raynsford | http://www.io7m.com



Re: PM design question: Scopes

2017-11-04 Thread Mark Raynsford
On 2017-11-03T10:44:51 +
Gavin Bierman <gavin.bier...@oracle.com> wrote:
> 
> switch (o) {
> case int i : ... // in scope and DA
>  ... // in scope and DA
> case T i :   // int i not in scope, so can re-use
> }
> ... // i not in scope
> +ve Simple syntactic rule
> +ve Allows reuse of pattern variable in the same switch statement.
> -ve Doesn’t make sense for fallthrough
>
> NOTE This final point is important - supporting fallthrough impacts on what 
> solution we might choose for scoping of pattern variables. (We could not 
> support fallthrough and instead support OR patterns - a further design 
> dimension.)

I'm strongly in favour of this one. In my experience and opinion,
fallthrough was a mistake in C and it was a mistake to copy it in Java.
In some 15 years and close to a million lines of code, I have never once
felt the need to fall through a switch case. If fallthrough didn't
exist, I'm not sure that there'd even be a question that this was the
"right" choice... It essentially makes each branch of the switch
appear to match the scoping rules for lambdas.

From a pedagogical standpoint, all of the other languages I know of
that have implemented pattern matching never had any kind of
fallthrough in the first place, so it'd likely benefit Java to match
them (no pun intended!). I'm thinking of people who learned pattern
matching via something like ML being able to write Java
switches/matches without having to make the mental gear change of
inserting these annoying "break" statements everywhere.

Is there actually a significant amount of code out there that uses
switch case fallthrough? I mean, I know you have to assume that there
is in the interest of preserving backwards compatibility, but I'm
curious if there are actually any metrics on this. I've never even seen
fallthrough in any code in the wild... I was under the impression that
modern IDEs warn against fallthroughs by default.

-- 
Mark Raynsford | http://www.io7m.com



Re: Data classes

2017-11-02 Thread Mark Raynsford
On 2017-11-02T11:05:33 -0400
Brian Goetz <brian.go...@oracle.com> wrote:

> > In the proposal, you discuss about adding keywords like "non-final, 
> > unfinal, mutable", i.e. considering that there can be a different set of 
> > keywords for data class declaration which is different from the one we have 
> > on fields. In that spirit, we can have a flag like nullable, maybenull, etc 
> > to specify that the compiler will not generate a requireNonNull inside the 
> > principal constructor and that equals or hashCode do not need nullchecks.  
> 
> Not really a fair comparison.  The keywords suggested like "non-final" 
> are not adding new concepts; they are merely making explicit something 
> that was previously implicit.  They are more akin to allowing the 
> "package" keyword to describe the default accessibility of class fields, 
> rather than a new feature. Non-nullability, on the other hand, is indeed 
> a new feature.  And, it is not a simple property of fields (well, it 
> could be, but I suspect users would find that to an unsatisfying 
> interpretation of "support for non-nullity.")

I think it would be better to get non-nullability language-wide first
as a separate feature.

-- 
Mark Raynsford | http://www.io7m.com



Re: Data classes

2017-11-02 Thread Mark Raynsford
On 2017-11-01T14:53:40 -0400
Brian Goetz <brian.go...@oracle.com> wrote:

> At the following URL, please find a writeup containing our current 
> thoughts on Data Classes for Java:
> 
>  http://cr.openjdk.java.net/~briangoetz/amber/datum.html
> 
> Comments welcome!
> 
> We'll be making a prototype available soon for folks to play with.

This looks great!

One thing springs to mind with the accessors: Is it possible that the
generated accessor methods could participate in the implementation of
interfaces? For example:

  interface Vector
  {
double x();
double y();
double z();
  }

  __data class Vector3 (double x, double y, double z)
implements Vector { }

The Vector3 type would automatically get x(), y(), and z() methods
based on the field declarations. This may imply, of course, that the
fields are public by default.

I don't see any obvious reasons why this couldn't work, but you've
almost certainly thought further than I have on the subject.

-- 
Mark Raynsford | http://www.io7m.com



Re: My lambda leftovers

2017-10-06 Thread Mark Raynsford
On 2017-10-06T13:16:19 +0200
Remi Forax <fo...@univ-mlv.fr> wrote:
>
> - allow void to be converted to Void (by returning null)
>   

This may not be *too* bad as long as it's strictly limited to Void,
because presumably a compliant program should never have had an
observable non-null value of type Void.

What I was wondering is if it might be time to introduce a strictly
non-null single-valued Unit (value) type. This would unfortunately be
incompatible with existing Void-typed methods...

-- 
Mark Raynsford | http://www.io7m.com