New to Scala! Confused with syntaxes here

Hi all,
I am new to scala and eager to be comfortable working with Scala.
I am looking at some code that is written by somebody else to understand scala and logic of the code they wrote so as I will get used to it.

And these 2 lines are pretty tricky to me, so can you please explain to me about _ value and two assignments one after another? Thank you so much

private var _cartLineItems:java.util.List[CartLineItem] = _

def setCartLineItems(items:java.util.List[CartLineItem]) = _cartLineItems = items

Seems to me that this code was written by someone trying to “Java-fy” Scala. See there is no reason for _ there. The setXXXX method is a setter to pass a value to the private field.

If you know java this is the same as a java bean definition.

In scala you need to ask more questions than just shove code in a Java bean and don’t care anymore. For example, does this attribute is necessary to class to function properly? Then require it on constructor. Does this class needs equals and hashCode ? Then make it a case class

This could be translated like:


case class Cart(lineItems: List[CartLineItem])

Note that this method you showed uses Java’s collection, not Scala’s so to you use it you’ll need to convert. The point is Scala is not hard, but people bring “baggage” from other languages and try to do like they used to, since Scala is so general it allows it, but is not idiomatic thus causing more confusion.

2 Likes

Thank you so much for your point! I am not sure if the class needs equals and hashcode.

Do you mean
def setCartLineItems(items:java.util.List[CartLineItem]) = _cartLineItems = items

is same as

void setCartLineItems(List items)
{
_cartLineItems = items;
}

And what does this _ assigned mean?
private var _cartLineItems:java.util.List[CartLineItem] = _
Is it same as
private List _cartLineItems=null;

Best regards,
cici

If you are trying to learn Scala, I suggest you steer clear of this kind of crap code unless you have no choice in the matter.

3 Likes

Yes.

Yes.

This is just a piece of java code using java collections, translated into scala syntax.

1 Like

In this case the underline is just a character in the name of a variable is does not have any syntax value.

2 Likes

Thank you so much all for your valuable suggestions and helping me understand the code.
I have to understand what are these codes doing in urgency because it is related to my work and I have to write test classes and bug fixes for existing codes. So, I might get syntax related questions again. I think the developer was used to Java and asked to start writing in Scala immediately.
For sure, I will consider your points when I learn Scala properly.
Thank you once again.

Best,
cici

1 Like

In Python (IIRC), a leading underscore is used in variable names to indicate that it is supposed to be a private (or protected?) variable. That convention is used because Python (at least Python 2, not sure about 3) has no way within the language to indicate that a variable is private or protected. Whoever wrote that code may have a Python background.

2 Likes

The prefix underscore actually appears in the official Scala style guide for mutable private fields because Scala doesn’t use get and set.

https://docs.scala-lang.org/style/naming-conventions.html#accessorsmutators

2 Likes

I haven’t got reading glasses yet, but I think the question was about the underscore on the RHS of the initializer, which means “default value” or null. Folks wind up disliking the idiom, because it’s really a null assignment and because everyone says what does that mean? including the person who was asked to debug the null pointer exception.

1 Like

It isn’t clear which underscore he is asking about initially, though I think all of them. Russ specifically mentioned the leading underscore in reference to Python, saying it was likely code written by a Python programmer. I was replying to point out that leading underscores on member variables are actually accepted Scala style to distinguish a private member from the method used to access it.

The default value use of underscore is likely the more challenging one for a novice to understand. For me the problem is that it means you are using a var. I also wouldn’t use it here because we know the type. However, there are cases where you want the default value for a parametric type, and then the underscore is helpful

class Foo[T] {
  private var default:T = _
  // Code that needs a default value of type T.
}

Because the type of T is unknown, it could be null, but it could also be 0, 0.0, false, etc. This is the cleanest approach that I have seen to getting such a value in a case like that.

In case you do want set/get methods like what appears in Java code, you can have simple ones created automatically with @scala.beans.BeanProperty. https://www.scala-lang.org/api/current/scala/beans/BeanProperty.html

1 Like

I had a PR to turn off the warning on my preferred idiom, but Seth Tisue shot it down. Maybe he’s right, or maybe he just doesn’t want me to have any fun. Anyway, I’d have more fun explaining it to new users:

scala> class C[A] { private var x: A = x ; def c = x }
<console>:11: warning: variable x in class C does nothing other than call itself recursively
       class C[A] { private var x: A = x ; def c = x }
                                       ^
defined class C

scala> new C[Int].c
res0: Int = 0

Also, the warning isn’t even right. Hey, Seth, the warning isn’t even right!

There was another fun property of the idiom:

scala> class C[A](z: A) { x = z ; private var x: A = x ; def c = x ; def c_=(a: A) = x = a  }
<console>:11: warning: variable x in class C does nothing other than call itself recursively
       class C[A](z: A) { x = z ; private var x: A = x ; def c = x ; def c_=(a: A) = x = a  }
                                                     ^
<console>:11: warning: Reference to uninitialized variable x
       class C[A](z: A) { x = z ; private var x: A = x ; def c = x ; def c_=(a: A) = x = a  }
                          ^
defined class C

scala> val n = new C[Int](42) ; n.c 
n: C[Int] = C@2e29f28e
res2: Int = 42

scala> n.c = 17
n.c: Int = 17

That is, it preserves the previously assigned value, like underscore syntax, but unlike an explicit assignment with a smarmy null.asInstanceOf[A].

All it needs is a killer application, or maybe just a good story, like, “My students were falling asleep in coding class until I showed them this one stupid trick!”

1 Like

Hello again!
Can you please help me understand this line?
register[CarAppConfig](Map(“LoyaltyProgramEnabled” -> true))

register[CarAppConfig](
   Map(“LoyaltyProgramEnabled” -> true)
)

The first line here is calling the method register, which takes a type parameter (CarAppConfig). We pass a single parameter to the method, which is a Map from String to Boolean:

The initializer for Map takes tuples of keys and values. The arrow -> is syntactic sugar for a 2-tuple, usually used with such Map initializations, as you can read it as “LoyaltyProgramEnabled maps to true”. The following code would be equivalent: Map(("LoyaltyProgramEnabled", true)) (note the extra pair of parentheses).

As you seem to come from a Java background, the equivalent there would be creating a new Map and then call map.put("LoyaltyProgramEnabled", true) on it.

1 Like

Thank you so much crater2150.

register method accepts argument of type CarAppConfig, but why is map passed to register?

Can’t really tell from the code here. Is register from a library?
Two possible explanations I can imagine are:

  1. CarAppConfig is just an alias for a Map (something like type CarAppConfig = Map[String, Boolean])
  2. There is some implicit conversion defined for it.

You will probably find the answer by examining the file where CarAppConfig is defined

Or possibly register creates a CarAppConfig from a Map[String, Any]…