-
Notifications
You must be signed in to change notification settings - Fork 1k
Rewrote local type inference tour #737
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I think we could drop the word "local" from the title. The number of people who will come in expecting ML/Haskell style global type inference is a small proportion of the overall audience. |
I would suggest adding material that explains that:
(hmm, well, unless this material exists elsewhere in the tour? I haven't checked. if it does, not sure whether we should move it here, or link to it with a note, or what.) |
574cd67
to
4970f64
Compare
OK I made the changes you suggested. |
previous-page: polymorphic-methods | ||
prerequisite-knowledge: unified-types, generic-classes | ||
--- | ||
The Scala compiler can often infer the type of a value so you don't have to declare it explicitly. You'll often see this with variables and return types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of "type of a value", suggest "type of an expression"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and I'm not sure "You'll often see this with variables and return types" really adds any meaning?
``` | ||
def squareOf(x: Int) = x * x | ||
``` | ||
The compiler can infer that the return type is an int so no return type is required. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/an int/an Int
/
The compiler uses the types of the arguments of `MyPair` to figure out what type `A` and `B` are. Likewise for the type of `x`. | ||
|
||
## Parameters | ||
The compiler can never infer method parameter types. However, in certain cases, it can infer anonymous function parameter types when the function is passed as argument. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/can never infer/never infers/ — slightly different shade of meaning
``` | ||
val doubled = Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) | ||
``` | ||
The parameter for map is `f: A => B`. Because we put integers in the Seq, the compiler knows that `A` is `Int` (i.e. that `x` is an int). Therefore, the compiler can infer from `x * 2` that `B` is type `Int`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seq
is missing backquotes around it. unless you just want to use the ordinary noun "sequence"
s/int/Int/ — unless you are really just using it as a noun, in which case "integer" not "int"
|
||
## When _not_ to rely on type inference | ||
|
||
It is generally considered more readable to declare the type of members exposed in a public API. Also, in some situations it can be quite dangerous to rely on Scala's type inference mechanism as the following program shows: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary to call something "quite dangerous" unless it compiles, yet fails at runtime.
I'd suggest: "In some situations, the compiler may infer a type that wasn't the one you intended."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add to your suggestion: "Therefore, we recommended that you make the type explicit for any APIs that will be exposed to users of your code" or something similar.
```tut:fail | ||
object InferenceTest4 { | ||
var obj = null | ||
obj = new Object() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new AnyRef
is more idiomatic Scala than new Object()
It is generally considered more readable to declare the type of members exposed in a public API. Also, in some situations it can be quite dangerous to rely on Scala's type inference mechanism as the following program shows: | ||
|
||
```tut:fail | ||
object InferenceTest4 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the object
wrapper needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly nitpicks
I can take care of getting this over the finish line. |
replaced by #985 |
No description provided.