-
Notifications
You must be signed in to change notification settings - Fork 19
Require type ascriptions on implicits #11
Comments
This is also slated for Typesafe Scala (don't know the ticket). |
@jdegoes http://scala-lang.org/news/roadmap-next mentions it:
For the Don Giovanni release (estimated to be released in 2018). |
Right now I think this might be a problem for some people, where it's very-hard-or-impossible to explicitly write the type that would be arrived at through inference (and which one needs). @milessabin is this right? Or am I making this up? I seem to remember someone mentioning it. |
@non I had originally used the CaseBuilder return type from Shapeless as an example of a type that would be tedious to type (vs. Shapeless's DSL which will infer the type), but @milessabin said he'd still be happy to force type ascriptions. |
Alright. It certainly gets a 👍 from me personally! |
It'd have to be behind a compiler flag to maintain source compatibility anyway, so tricky type users do not have to use the flag. |
I think this would lead to all kinds of busywork, and I don't consider myself an especially "tricky" type creator.
There's a nice straightforward function, with a type which cannot even be written down because there's no stable path through which to reach it. So you have to unroll the context bound, invent a meaningless name, look up what the type member is called, and now that's a few more bits you get to change in multiple places. Thanks, Compiler.
There are a bunch of variations on this. I thought the idea was to make it easier to use types to accomplish things, not to exclude concise syntax and make me repeat everything three times, java style. I'm super well aware of the problem people are trying to address by requiring explicit types, but shifting busywork onto the humans is giving up. There are three benefits to writing the type down which I can think of, other than the artifact-of-the-implementation implicit visibility issue, which I'll ignore here because it's a fairly ridiculous ad hoc "maybe this will work" rule. Maybe I'm overlooking other benefits.
Writing all the types down is a rigid and costly way to achieve these things. I know how much friction it creates because I already try to write all my implicit return types down (since I lack the mechanisms I'm about to describe) and it's a fuck-ton of friction. I propose these are better.
|
This would need some tool support. In the end, you still want type inference, but it doesn't need to be run in the compiler but in the "IDE" (or equivalent), or the tool @paulp is proposing.
In Haskell, at least you get to write down the function, ask for its type and paste it in later. But I did see code where I decided against adding the signatures.
That's a rather nice idea, and I think you might want that for public APIs anyway. A tool for that should have an option for limiting it to implicits, maybe even by default, but that policy choice shouldn't be imposed by the tool. Could MIMA be configured or patched for that, so that it ignores forward compatibility? (I think this mechanism would have to be in a SBT plugin, but the discussion doesn't have a better home than this). |
@non all implicit result types in shapeless are explicit. I've been advocating this for years, so a definite :+: from me. Needs a flag for backwards compatibility though ... with the flag it should give a deprecation warning I think. |
Fix in progress as #68. |
Calls to synthetic case class apply methods are inlined to the underlying constructor invocation in refchecks. However, this can lead to accessibility errors if the constructor is private. This commit ensures that the constructor is at least as accessible as the apply method before performing this tranform. I've manually checked that other the optimization still works in other cases: scala> class CaseApply { Some(42) } defined class CaseApply scala> :javap -c CaseApply Compiled from "<console>" public class CaseApply { public CaseApply(); Code: 0: aload_0 1: invokespecial #9 // Method java/lang/Object."<init>":()V 4: new #11 // class scala/Some 7: dup 8: bipush 42 10: invokestatic #17 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer; 13: invokespecial #20 // Method scala/Some."<init>":(Ljava/lang/Object;)V 16: pop 17: return }
Jon's anonymous implicit idea also made me think that we should require types on implicits.
i.e. this is invalid:
This is valid:
The text was updated successfully, but these errors were encountered: