<html><body><div>@Howard<br></div><div><br data-mce-bogus="1"></div><div>my IDE immediately flags a warning for the cast: "unchecked cast from Integer to Output" which is correct and the root of the problem. Unchecked casts are cheating the type system, effectively disabling it at that location and introducing the possibility of type errors. <br></div><div><br data-mce-bogus="1"></div><div>Let's change the main method a bit:<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>public static void main(String[] args) {<br> Double x = Foo.foo();<br> System.out.println(x);<br>}</div><div><br></div><div>No warnings in the main method as everything is ok for the type system: we are calling Foo.foo<Double>() as is inferred correctly by the type checker.<br data-mce-bogus="1"></div><div>But due to the cast we now get a runtime error:<br data-mce-bogus="1"></div><div> Exception in thread "main" <br> java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double</div><div><br data-mce-bogus="1"></div><div>This only could happen because the cast did break the type checker.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Actually it is impossible to write an implementation for<br data-mce-bogus="1"></div><div> static <Output extends Number> Output foo()<br></div><div>because you simply cannot create an instance of Output (where the concrete type value for Output is defined by the caller and so cannot be known to the implementation beforehand; you only know that it will be a subtype of Number but not which; heck, the type used for Output can even be defined by the client and therefore does not even have to exist when you write foo()).<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Interesting side note: you can write an implementation for<br data-mce-bogus="1"></div><div> static <T> T identity(T x)<br></div><div>but only one implementation is possible here, which is strictly following from the types (I'm still assuming pure functions with no access to external state here, of course):<br data-mce-bogus="1"></div><div> static <T> T identity(T x) { return x; }<br></div><div><br data-mce-bogus="1"></div><div>-Thorsten<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div><br>Am 10. März 2016 um 22:34 schrieb Howard Lovatt <howard.lovatt@gmail.com>:<br><br><div><blockquote type="cite"><div class="msg-quote"><div dir="ltr">@Thorsten,<div><br></div><div>No it doesn't, the following Java code:</div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" data-mce-style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div>public class GenericReturnTypes {</div></div><div><div> interface Foo {</div></div><div><div> static <Output extends Number> Output foo() {</div></div><div><div> return (Output)(new Integer(0));</div></div><div><div> }</div></div><div><div> }</div></div><div><div> public static void main(String[] args) {</div></div><div><div> System.out.println(Foo.foo());</div></div><div><div> }</div></div><div><div>}</div></div></blockquote><div> </div><div>Compiles without error or warning, runs, and prints 0.</div><div><br></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"> -- Howard.<br></div></div><br><div class="gmail_quote">On 11 March 2016 at 02:18, Thorsten Seitz <span dir="ltr"><<a href="mailto:tseitz42@icloud.com" data-mce-href="mailto:tseitz42@icloud.com">tseitz42@icloud.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;" data-mce-style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div dir="auto"><div><br></div><div><br></div><div><br>Am 10.03.2016 um 05:35 schrieb Howard Lovatt via swift-evolution <<a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>:<br><br></div><blockquote type="cite"><div><div dir="ltr">I am sure you know the answer for Swift; but in other languages it doesn't, e.g. Java. <div><br></div><div>With Java semantics:<div><br></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" data-mce-style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">func foo<Input, Output>(input: Input) -> Output</span></div></blockquote><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;"><br></span></div><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">Would be the same as:</span></div><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;"><br></span></div><div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" data-mce-style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">func foo(input: Any) -> Any</span></blockquote></div><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;"><br></span></div><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">Because the only constraint on both Input and Output is Any. </span><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">Since the Java compiler erases generics, the two would literally be the same to the JVM!</span></div></div></div></div></blockquote><div><br></div>To the JVM at runtime, but not to the typechecker at compile time. There it works just as in Swift.<div><br></div><div>-Thorsten </div><div><br></div><div><br><blockquote type="cite"><div><div dir="ltr"><div><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">Since Swift doesn't allow overloading on return type and therefore as it stands `</span><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">func foo<Input, Output>(input: Input) -> Output` cannot be implemented, it would be nice if the compiler flagged this as an error and suggested that you meant `</span><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">func foo(input: Any) -> Any`</span><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;">.</span></div></div><div class="gmail_extra"><br clear="all"><div><div> -- Howard.<br></div></div><br><div class="gmail_quote">On 10 March 2016 at 13:07, Joe Groff <span dir="ltr"><<a href="mailto:jgroff@apple.com" data-mce-href="mailto:jgroff@apple.com">jgroff@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;" data-mce-style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><span><br> > On Mar 9, 2016, at 6:02 PM, Howard Lovatt <<a href="mailto:howard.lovatt@gmail.com" data-mce-href="mailto:howard.lovatt@gmail.com">howard.lovatt@gmail.com</a>> wrote:<br> ><br> > Wow, I would never have guessed that syntax :)<br> ><br> > It makes no sense to me to interpret a generic constraint as meaning all instead of any. How could anything either accept or return all possible implementations of something simultaneously, surely it only ever accepts or returns one of all the possible implementations at a time.<br> <br> </span>A type variable in angle brackets always means "all". It's like a function parameter, but at type level—it's in the caller's hands what it gets bound to. You couldn't write a function `func foo<Input, Output>(Input) -> Output` unless that function was able to generate a value of every possible type a caller might pass in for Output, just like you couldn't write e.g. 'absolute value' as taking its result as a second parameter.<br> <span><br> ><br> > If the interpretation for output is that at time 1 it returns one of all the possible implementations at at time 2 returns another - then that is what I want. However I would describe that as returning one of the possible implementations, not all.<br> ><br> > But no doubt you are correct, since you probably wrote that bit of the compiler :(<br> ><br> > More practical points<br> ><br> > 1. My compiler, 7.3 beta (7D152p), rejects the syntax, it doesn't like where inside Any<> saying it expects > to complete generic argument list. When will this be available, so that I can try it out?<br> > 2. Will the declarations inside protocols also change to the Any<...> form or will all the generics remain following the function name rather in a returned Any<...>? Currently -> Any<...> doesn't work in protocols for me.<br> > 3. In the construct Any<Protocol where Type == Type>, i.e. same type name used in protocol and enclosing struct/class/extension, does the left Type refer to the protocol or the enclosing struct/class/extension?<br> > 4. Is there any documentation of all of this?<br> <br> </span>Sorry, this is all possible future syntax and features. It's not implemented today. You'd need to write your own equivalent of the "Any" wrapper by hand right now.<br> <span><span style="color: #888888;" data-mce-style="color: #888888;" color="#888888"><br> -Joe<br> <br> </span></span></blockquote></div><br></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" data-mce-href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></div></blockquote></div><br></div></div></blockquote></div></div></body></html>