What is this? it it a variable name or is it syntax?

What is this? Is it just the name of a var which class establishes? Or is it a reserved word which the compiler knows about?

I ask because I can’t figure out how to shadow its declaration.

class foo {
  def bar(this:Int): Int = {
    this + 1
  }
}

At least IntelliJ gives me funny errors that don’t really make good sense.

Screenshot 2021-01-04 at 13.36.43

It is a reserved keyword. You can define an alias, but not re-define it:

class foo { self => // alias for `this`

  def bar = 1
  def baz(i: Int) = self.bar + i
  def boo(i: Int) = this.bar + i // `this` still works
}

I think it would be pretty hazardous if you could redefine / shadow this.

1 Like

It seems to be impossible to rebind this. However, the error message is misleading.

IntelliJ giving misleading error messages is not something new and it is not even funny anymore.

Using a real compiler you get a better error message: https://scastie.scala-lang.org/BalmungSan/0FUnXgwOSRimSH2Nx5GgGg

5 Likes

Yeah – the hard-and-fast rule (IMO) is, when IntelliJ is saying something weird, run the compiler. IntelliJ has improved considerably over the years, but it is still prone to false positives, false negatives, and confusing errors.

But to the main point: yes, this is strictly defined by the language, and can’t be rebound. It’s a pretty central concept in Scala (and Java, and most other languages in the Java lineage); this is in contrast to some languages where it’s basically just another named pointer.

2 Likes

Yes, I see. That makes sense. Scala inherits a lot of baggage from Java. I understand there are huge costs of re-inventing the wheel simply because some Java baggage is not elegant.

My use case was that two of my methods (the same method in two different classes) is very large, containing a long list of reduction/simplification rules (sort of like algebraic reduction/simplification). In each case this is implemented as a list of 0-ary anonymous functions which each look at this to decide whether it is something that simplifies, and if so returns a simpler form.

I was playing with refactoring this code, because a list of simplification rules can easily be thought of as data, rather than as code—but it is data which is parameterized by this. I wanted to write a function which takes this as argument, that way I could refactor simply by cut-and-paste. But now I see I need to cut-paste and replace references to this with another variable name.

Side note: when refactoring it is often not clear whether it is a good idea. You have to just do it and look at the results, and decide is the code now better or worse. Highly composable code is more easily refactorable, because you can move the code around easily without adding lots of boiler plating.

Amazing how clear things are with a good error message. Bravo!

Hmm… Isn’t “this” (or “self”) a keyword/a binding that cannot be changed in C++, Javascript, Smalltalk,… as well? Just because it doesn’t map to CL(OS), it’s not necessarily just legacy baggage. :wink:

2 Likes

sometimes baggage is good, otherwise you’d have to stuff your undies in a sack when you fly. :wink: