How to talk about companion objects vs regular objects?
Asked Answered
A

8

35

I am teaching Scala for the first time and my students are finding the deliberate "punning" involved in companion objects very confusing. Consider the following example:

class Stack {
  ... methods such as push/pop
}

object Stack {
  ... factory method(s) and possibly others
}

The confusion comes in when I use verbal phrases such as "a stack object" or "stack objects" or especially "the stack object". My students have difficulty understanding whether I mean the singleton object Stack or objects of the Stack class.

I'm looking for alternative ways to verbalize such things that beginners can understand more easily. I've considered always referring to objects of the Stack class as "Stack instances" or "instances of Stack", but it seems crazy when trying to teach OO not to be able to call these things objects. I've been trying to ALWAYS use the phrase "singleton object" or "companion object" when talking about the singleton object Stack, but the syntax of Scala is working against me there because it only uses the word "object".

In this case, I could rename the singleton object StackFactory instead of Stack, but that's only an option for my own classes, not for the thousand and one companion objects already built into Scala.

Edit:

Sorry, I wasn't clear enough in my question. The main confusion happens NOT when referring to the companion object. In that case, as several people have noted, it is easy enough to use to a phrase such as "the companion object". Instead, the main confusion happens when referring to ordinary instances. Then, if I say "a stack object" (meaning some stack instance) or "the stack object" (meaning this particular instance), some fraction of the students will think I mean the companion object -- even though I did not use the word companion or singleton.

And I can see perfectly well where the confusion comes from, because the word "object" appears in the program text only with the companion object.

Anchoress answered 19/9, 2012 at 14:30 Comment(2)
Historically Scala has called singleton objects 'modules'. Perhaps it helps to know that others struggle as well with the nomenclature.Batts
How about "the (Stack) companion"?Heidi
V
8

This issue in Scala is certainly not without irony, but even in the Java space there can be naming issues regarding java.lang.Object, its instances, its class and instances of its class.

For Scala I propose the following terminology:

  • Call instantiated objects “instances”
  • Call objects “objects”

In the end, I would say that the idea of OO includes objects (in the sense of modules and composition) as much as objects (in the sense of instances).

Regardless of how you decide, consistency is key, especially for teaching.

Vlf answered 19/9, 2012 at 14:56 Comment(3)
These two rules (call instantiated objects instances, call objects objects) would substantially decrease confusion WITHIN Scala, but might increase confusion when those students move on to other OO languages.Anchoress
I agree with Chris Okasaki, I think that solution adds more confussion. I would stick to what's generally used in "Programming Scala" that calls objects to every instance and companion object to, well, companion objects...Pillowcase
I also agree with Chris. According to general OO priciples 'object' is basically an instance of a class, so every OO language should stick to this naming. "Instantiated objects" is redundant, because there can't be "non-instantiated" objects.Frier
F
19

I think Stack singleton (if it stands alone) or Stack companion (if it comes with a class) is the best way to name object Stack. The Scala Language Reference calls them modules. But modules have by now been too much associated with run-time entities (as in OSGI) to be comfortable with that.

Fontaine answered 19/9, 2012 at 20:21 Comment(0)
F
17

I think using the phrase "companion object" should be clear enough.

Frier answered 19/9, 2012 at 14:56 Comment(2)
It can even be shortened to just "companion", as in "the Stack companion".Fourpence
This is pretty idiomatic usage and as @Fourpence remarks, "the companion" is often enough.Den
V
8

This issue in Scala is certainly not without irony, but even in the Java space there can be naming issues regarding java.lang.Object, its instances, its class and instances of its class.

For Scala I propose the following terminology:

  • Call instantiated objects “instances”
  • Call objects “objects”

In the end, I would say that the idea of OO includes objects (in the sense of modules and composition) as much as objects (in the sense of instances).

Regardless of how you decide, consistency is key, especially for teaching.

Vlf answered 19/9, 2012 at 14:56 Comment(3)
These two rules (call instantiated objects instances, call objects objects) would substantially decrease confusion WITHIN Scala, but might increase confusion when those students move on to other OO languages.Anchoress
I agree with Chris Okasaki, I think that solution adds more confussion. I would stick to what's generally used in "Programming Scala" that calls objects to every instance and companion object to, well, companion objects...Pillowcase
I also agree with Chris. According to general OO priciples 'object' is basically an instance of a class, so every OO language should stick to this naming. "Instantiated objects" is redundant, because there can't be "non-instantiated" objects.Frier
R
7

I'd go for

  • "Stack" == the class Stack
  • "Stack's companion" == companion object of the Stack class
  • "A Stack" == an instance of the class Stack
Rung answered 19/9, 2012 at 21:13 Comment(0)
M
4

I think your solution sounds good. "The Stack singleton" very clearly denotes the fact that you're talking about a singleton object rather than a whole class of objects. As for the names working against you, explain that object declares a single object (singleton), whereas class is a template for a whole class of objects (class instances).

One other thing you should probably make sure is that object Stack is not an instance of class Stack. If the students don't understand that point then they'll probably have a harder time making the distinction between the singleton Stack and instances of class Stack.

In this case, I could rename the singleton object StackFactory instead of Stack, but that's only an option for my own classes, not for the thousand and one companion objects already built into Scala.

Note that if you rename the object then it's no longer a companion object. Classes and their companion objects have special permissions granted by the Scala compiler to access each other's private members. If you change the name of the singleton so that it doesn't match the class then there's no longer any indicator to the compiler that it's a companion object and it loses the companion privileges.

Milk answered 19/9, 2012 at 15:3 Comment(0)
S
3

If you're really good about being consistent you can also refer to the instances of class Stack as "Stack instances", but that might require a bit much habit twisting. Other than that, "the Stack companion object" or "object Stack", never "the Stack object".

Stammel answered 19/9, 2012 at 15:9 Comment(1)
Right, so I try very hard to be consistent in how I refer to the companion object. But (A) students aren't always so consistent in what they say, and (B) when I do talk about "a stack object" (ie, a stack instance) some of them will still think I'm talking about the companion object.Anchoress
P
2

Maybe my proposal is a bit naive, but I would just call

  • stack class: to the stack class itself (I told you it was naive)

  • a stack / a stack instance / a stack object: an instance of the stack class

  • stack companion / stack companion object / stack singleton / stack factory (in case you use it for that purpose): the companion object of the stack class.

(In fact, in Odersky's "programming scala" the term most often used is "companion object", which I think is pretty clear...)

I would also stress the difference between a stack instance and the stack companion, it's a common source of confusion.

and regarding the confusion of your students, I would empathize how important is for a university student to be careful and consistent with the use of terminology, you could also provide some quiz or exercises to tell the difference between each of these concepts.

Sometimes terminology is better learnt by using it.

Pillowcase answered 21/9, 2012 at 3:21 Comment(0)
C
1

If you want a singleton object to be a companion of a class or trait, it must have the same name (and package and source file).

Companions can access each others private members, e.g. a factory in the companion object can still create instances of a (companion) class with a private constructor.

Castellated answered 20/9, 2012 at 5:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.