Skip to content

Rewrote implicits section of the tour #746

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

Closed
wants to merge 1 commit into from

Conversation

travissarles
Copy link
Contributor

No description provided.

@travissarles travissarles changed the title Rewrote implicit parameters tour Rewrote implicits section of the tour Mar 29, 2017
@travissarles travissarles mentioned this pull request Mar 29, 2017
33 tasks
printGreeting("Franchesca") // Hello, Franchesca
printGreeting("Fred")(new Greeting("Good day")) // Good day, Fred
```
The `implicit val standardGreeting` is a value that can be supplied as an argument to an implicit parameter automatically. In the method `printGreeting`, the parameter `greeting` is implicit. This means that the caller can either supply an argument normally or skip it. With `greet("Franchesca")`, the compiler doesn't see a greeting but it notices that `greeting` is an implicit parameter so it searches the current scope for an implicit `Greeting` and finds `standardGreeting`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first sentence is a little hard to understand. I would explain it the other way around--don't explain the implicit val standardGreeting until after you explain that greet("Franchesca") doesn't have the second parameter so it goes looking for an implicit parameter. Then you can say that standardGreeting is found because it is an implicit val.

```
The `implicit val standardGreeting` is a value that can be supplied as an argument to an implicit parameter automatically. In the method `printGreeting`, the parameter `greeting` is implicit. This means that the caller can either supply an argument normally or skip it. With `greet("Franchesca")`, the compiler doesn't see a greeting but it notices that `greeting` is an implicit parameter so it searches the current scope for an implicit `Greeting` and finds `standardGreeting`.

This becomes useful when you have a lot of similar arguments to function calls throughout your program. However, implicits can make code more difficult to understand because it's not always obvious where they're defined if you import them from another module with a wildcard (e.g. `import MyPredef._`).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is absolutely not the main problem I have with implicits. The primary problem is that they hide an argument that can impact your program, making it less obvious what your methods depend upon because the method call doesn't show you that anything is going on! The secondary problem is that once you realize a method actually has an implicit parameter, it can sometimes be difficult to track down where it is because it might be from a wildcard import, not something you typed in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a newbie, just knowing to say import cats._ is the hard part.

val number: Int = 5
square(number) // 25.0
```
This typecasting happens because of the method `implicit def int2double(x: Int): Double = x.toDouble` defined in `Predef` (a set of convenience methods in scope by default). When the compiler sees that `square` expects a `Double` but we pass an `Int`, it searches the scope for an `implicit` function that can do the conversion.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conversion of number types are a special case. I'd pick another example.

## Implicit conversion


An implicit conversion happens the type check fails for an argument and an implicit conversion is found.
Copy link

@Ichoran Ichoran May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to explain what counts for executing an implicit conversion: an implicit def that converts a single argument of one type to another type; or an implicit val of a function that does the same thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here I need to explain two ways implicit conversions happen:
-An implicit def that converts a single argument of one type to another type
-An implicit val of a function that does the same thing

The implicit method `function2ActionListener` takes a function which accepts an ActionEvent. It then returns an `ActionListener` with the aforementioned function as its `actionPerformed`. Now when we call `button.addActionListener` (which accepts an `ActionListener`) with an anonymous function of type `ActionEvent => Unit`, the compiler looks for an implicit conversion function which can convert the type to `ActionListener`.

This removes a lot of the boilerplate because we can use an anonymous function. However, because implicits are often defined outside of the package, it can be difficult to debug. Therefore they are best used in libraries.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about implicit classes?

@SethTisue
Copy link
Member

needs rebase

@SethTisue SethTisue removed their request for review October 10, 2017 20:17
@jvican
Copy link
Member

jvican commented Jan 9, 2018

@SethTisue There are many of these sections that still need some work. What do you think about creating an Scala Contributors thread and ask the Community for help getting these through the finish line?

@SethTisue
Copy link
Member

yes, good idea

@jvican
Copy link
Member

jvican commented Jan 9, 2018

@NthPortal
Copy link
Contributor

I'm not sure when the example was written, but at this point in time, the Swing example doesn't actually require the implicit conversion. Since ActionListener is a SAM, the function will get turned into the appropriate lambda anyway in 2.12 (Scastie).

@jvican
Copy link
Member

jvican commented Jan 11, 2018

I'm not sure when the example was written, but at this point in time, the Swing example doesn't actually require the implicit conversion. Since ActionListener is a SAM, the function will get turned into the appropriate lambda anyway in 2.12 (Scastie).

Indeed, the example needs to be changed.

@mghildiy
Copy link
Contributor

So what I understand of this commit is as follows:
-File 'implicit-conversions.md' has been deleted
-File 'implicit-parameters.md' has been deleted
-A new file 'implicit.md' has been created which explains concept of implcit type conversions in Scala

@jvican
Copy link
Member

jvican commented Jan 14, 2018

Yeah, the most important part of this tutorial is the content of the new addition, which has to be clear for beginners while being complete and covering all the implicit semantics in Scala.

@mghildiy
Copy link
Contributor

mghildiy commented Jan 14, 2018 via email

@SethTisue
Copy link
Member

superseded by #998

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

Successfully merging this pull request may close these issues.

7 participants