method vs function
lahosken opened this issue · 6 comments
They're not quite the same. But the difference can trip you up.
The difference is subtle; I don't think a tutorial's a great place to explain it. I watched a bunch of n00bs try to learn this in a live class and get confused. I'm a n00b myself, and when I tried to apply the method-vs-fn things I learned in that class I discovered that, uhm, I hadn't understood the explanation so well myself.
So maybe say: there's a difference, but most of the time you don't care. Here are some situations where it matters; if you're confused and you're in one of these situations and you're using a [function|method] try using "the other one".
And we can link to a longer explanation for folks who really want it.
Possible sample code to show differences
class C {
var acc = 0
def inc = { acc += 1 }
val finc = { () => acc += 1 }
def invoke(f: () => Unit) { f() }
}
c invoke c.inc // fail
c invoke c.finc // triumph
c inc // calls c.inc()
c finc // the function c.finc
I would explain it by saying that a function is an instance of FunctionX.
In your example:
finc is a member of C, its type is Function0[Unit], so it's a function
inc is a method of C
Note that you can easily extract a function from a method, by using "_", but not the opposite.
I would explain it by saying that a function is an instance of FunctionX.
Oh man we show methods to these kids pretty early on in Scala School. I worry that if we point them at scala.Function0, they'll panic and run away to become JS programmers or shepherds or something. I was thinking of leaving that for the linked-to fuller explanation.
Ahh. But the only reason your example doesn't work is because of ... another corner of the language! Optionality of parens. Try this:
class C {
var acc = 0
def inc() = { acc += 1 }
val finc = { () => acc += 1 }
def invoke(f: () => Unit) { f() }
}
and c invoke c.inc
works due to the compiler's eta-expansion.
I think any time you try to explain methods vs. functions you're going to end up in a corner like this.
I think that it's fine to say: "methods and functions are largely interchangeable. Here's a link to an article explaining their differences"
Yeah.
Ideally, that link would be accompanied by something like
"If you see [confusing behavior] happening, it could be because you got accustomed to playing with functions but are now playing with a method. They're largely interchangeable; there are some subtle differences you can read about at [article link]."
Then, a few days later when a student sees [confusing behavior], they wouldn't freak out. Instead, they would think "Oh hey, I think I heard about this."
Right now, I'm just guessing at good candidates for what [confusing behavior] folks are likely to get confused by first. Maybe there isn't a single one that folks tend to hit first. In which case, trying to plant a mnemonic trigger in their brains ain't gonna work so well.
Added an aside about this on the Basics page