Either Type - Different Approach

36 views
Skip to first unread message

Fernando J. Naranjo Talavera

unread,
Feb 9, 2018, 2:35:16 PM2/9/18
to Functional Java
Hi! I have noticed that #Java has a parameter inference mechanism that can help us workaround some limitations of type erasure and to do things like this.

public final class Either<T1,T2> {
   
public enum L { Left }
   
public enum R { Right }

   
public Either(T1 left , L... _) {...}
   
public Either(T2 right, R... _) {...}
   
...
}

////////////// In use //////////////

new Either<Integer,String>(2);
new Either<Integer,Exception>(new Exception());

You can find a complete, type-safe, immutable implementation of an Either type that uses this approach here:
(as well as some documentation regarding the discovery process of the workaround, etc.)

https://github.com/fejnartal/Either-JavaType

Tony Morris

unread,
Feb 10, 2018, 2:49:59 PM2/10/18
to functio...@googlegroups.com
This looks the same as what is required for writing Either in C#
https://github.com/NICTA/xsharpx/blob/master/src/XSharpx/Either.cs

However, I am unsure of the advantage here?

--
You received this message because you are subscribed to the Google Groups "Functional Java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to functionaljava+unsubscribe@googlegroups.com.
To post to this group, send email to functionaljava@googlegroups.com.
Visit this group at https://groups.google.com/group/functionaljava.
For more options, visit https://groups.google.com/d/optout.

Nebu Pookins

unread,
Feb 10, 2018, 8:30:51 PM2/10/18
to functio...@googlegroups.com
I recommend you don't use "..." to represent "there's some code here, but I've omitted it to keep the example short", because it took me more than a day to realize that sometimes you're using "..." for that meaning, and sometimes you're using "..." for varargs, which made your example very confusing. Ideally, you would post fully compilable Java code to fully convince people there's no "magic handwaving" going on.

Beyond that, that's definitely a neat trick. In production code that's being maintained by a team of developers, I'm not sure the benefit for the problem it's solving for Either (basically avoiding referencing static methods like Either.left(x), Either.right(y)) exceeds the cost of potentially confusion API for your coworkers (coworker: "What am I supposed to pass for the second param?", me: "Nothing", coworker: "???"), but I look forward to seeing this idea developed further and what other applications it can be used for giving additional hints to the type inference system.

--
Message has been deleted
Message has been deleted

Nebu Pookins

unread,
Feb 15, 2018, 1:22:49 AM2/15/18
to functio...@googlegroups.com

I agree that it seems possible to design and implement a language that looks almost exactly like Java, except that it does a bit more type inferencing – allowing some constructions that the current Java language specification forbids.

 

For the specific case of overloading constructors with unrestricted generics, e.g.

 

public class Either<T1, T2> {

  public Either(T1 left) {}

  public Either(T2 right) {}

}

 

... there is a concern that if T1 and T2 were subtypes of each other (or the exact same type), then it may be ambiguous as to which overload you intended. The two reasonable ways to deal with this that I can come up with are:

 

  1. Produce a compile error when someone writes a class that uses constructor overloading in this way (this is the approach Java seems to have taken).
  2. Allow this declaration of overloaded constructors, but produce a compile error when a given usage of the constructor would be ambiguous.

 

I’m not a JVM/bytecode language, but I would be willing to believe there is some aspect involving generic type erasure and backwards compatibility issues that make the 2nd option difficult. For example, there is a reflection API where you can ask for the constructor identified by the argument list having specific types. With type erasure, it seems like it would be difficult to differentiate between these two constructors, and you cannot change that method to return a List of constructors without breaking backwards API incompatibility issues.

 

Sent from Mail for Windows 10

 

From: Fernando J. Naranjo Talavera
Sent: February 14, 2018 8:45 PM
To: Functional Java
Subject: Re: [functionaljava] Either Type - Different Approach

 

Thank you Nebu for the constructive criticism.

It's true that it could solved more conventionally using static methods and private constructors.
What I find most interesting about this code however, is that it proves that the Java language is currently prohibiting some valid constructs.

It proves that the Java language is capable of inferencing the type of this code

new Either<Integer,Exception>(2)


and therefore it should allow overloading the constructor like this (but it doesn't):

public final class Either<T1,T2> {

   
public Either(T1 left) {}
   
public Either(T2 right) {}
}


El domingo, 11 de febrero de 2018, 2:30:51 (UTC+1), Nebu Pookins escribió:

I recommend you don't use "..." to represent "there's some code here, but I've omitted it to keep the example short", because it took me more than a day to realize that sometimes you're using "..." for that meaning, and sometimes you're using "..." for varargs, which made your example very confusing. Ideally, you would post fully compilable Java code to fully convince people there's no "magic handwaving" going on.

Beyond that, that's definitely a neat trick. In production code that's being maintained by a team of developers, I'm not sure the benefit for the problem it's solving for Either (basically avoiding referencing static methods like Either.left(x), Either.right(y)) exceeds the cost of potentially confusion API for your coworkers (coworker: "What am I supposed to pass for the second param?", me: "Nothing", coworker: "???"), but I look forward to seeing this idea developed further and what other applications it can be used for giving additional hints to the type inference system.

On Fri, Feb 9, 2018 at 11:35 AM, Fernando J. Naranjo Talavera <fejn...@gmail.com> wrote:

Hi! I have noticed that #Java has a parameter inference mechanism that can help us workaround some limitations of type erasure and to do things like this.

public final class Either<T1,T2> {
   
public enum L { Left }
   
public enum R { Right }

   
public Either(T1 left , L... _) {...}
   
public Either(T2 right, R... _) {...}
   
...
}

////////////// In use //////////////

new Either<Integer,String>(2);
new Either<Integer,Exception>(new Exception());

You can find a complete, type-safe, immutable implementation of an Either type that uses this approach here:
(as well as some documentation regarding the discovery process of the workaround, etc.)

https://github.com/fejnartal/Either-JavaType

--
You received this message because you are subscribed to the Google Groups "Functional Java" group.

To unsubscribe from this group and stop receiving emails from it, send an email to functionaljav...@googlegroups.com.
To post to this group, send email to functio...@googlegroups.com.

 

--

You received this message because you are subscribed to the Google Groups "Functional Java" group.

To unsubscribe from this group and stop receiving emails from it, send an email to functionaljav...@googlegroups.com.
To post to this group, send email to functio...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages