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

Rewrote local type inference tour #737

Closed
wants to merge 1 commit into
base: master
from

Conversation

@travissarles
Collaborator

travissarles commented Mar 17, 2017

No description provided.

@travissarles travissarles referenced this pull request Mar 18, 2017

Closed

Rewrite tour of Scala #733

33 of 33 tasks complete

@travissarles travissarles self-assigned this Mar 21, 2017

@travissarles travissarles moved this from In PR to Ready to Merge in Rewrite Tour of Scala Mar 21, 2017

@SethTisue

This comment has been minimized.

Show comment
Hide comment
@SethTisue

SethTisue Mar 21, 2017

Member

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.

Member

SethTisue commented Mar 21, 2017

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.

@SethTisue

This comment has been minimized.

Show comment
Hide comment
@SethTisue

SethTisue Mar 21, 2017

Member

I would suggest adding material that explains that:

  • method parameter types are never inferred
  • but parameter types of anonymous functions can sometimes be inferred from context

(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.)

Member

SethTisue commented Mar 21, 2017

I would suggest adding material that explains that:

  • method parameter types are never inferred
  • but parameter types of anonymous functions can sometimes be inferred from context

(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.)

@travissarles

This comment has been minimized.

Show comment
Hide comment
@travissarles

travissarles Mar 22, 2017

Collaborator

OK I made the changes you suggested.

Collaborator

travissarles commented Mar 22, 2017

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.

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

instead of "type of a value", suggest "type of an expression"

@SethTisue

SethTisue Mar 24, 2017

Member

instead of "type of a value", suggest "type of an expression"

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

and I'm not sure "You'll often see this with variables and return types" really adds any meaning?

@SethTisue

SethTisue Mar 24, 2017

Member

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.

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

s/an int/an Int/

@SethTisue

SethTisue Mar 24, 2017

Member

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.

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

s/can never infer/never infers/ — slightly different shade of meaning

@SethTisue

SethTisue Mar 24, 2017

Member

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`.

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

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"

@SethTisue

SethTisue Mar 24, 2017

Member

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:

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

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."

@SethTisue

SethTisue Mar 24, 2017

Member

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."

This comment has been minimized.

@jvican

jvican Jan 11, 2018

Member

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.

@jvican

jvican Jan 11, 2018

Member

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()

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

new AnyRef is more idiomatic Scala than new Object()

@SethTisue

SethTisue Mar 24, 2017

Member

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 {

This comment has been minimized.

@SethTisue

SethTisue Mar 24, 2017

Member

is the object wrapper needed here?

@SethTisue

SethTisue Mar 24, 2017

Member

is the object wrapper needed here?

@SethTisue

mostly nitpicks

@SethTisue SethTisue assigned SethTisue and unassigned travissarles Jan 9, 2018

@SethTisue

This comment has been minimized.

Show comment
Hide comment
@SethTisue

SethTisue Jan 9, 2018

Member

I can take care of getting this over the finish line.

Member

SethTisue commented Jan 9, 2018

I can take care of getting this over the finish line.

@SethTisue

This comment has been minimized.

Show comment
Hide comment
@SethTisue

SethTisue Jan 11, 2018

Member

replaced by #985

Member

SethTisue commented Jan 11, 2018

replaced by #985

@SethTisue SethTisue closed this Jan 11, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment