4
votes

Hey I have the following piece of code:

var z:Array[String] = new Array[String](4);
z(0) = "Dave"; 
z(1) = "Joe";
z(2) = "Jim";
z.apply(3) = "Roger";

The last line here is giving a compile time error saying - "missing arguments for method apply in class Array; follow this method with `_' if you want to treat it as a partially applied function"

This does not make sense to me, as I have read that when you apply parentheses surrounding one more values to a variable, Scala will transform the code into an invocation of a method named apply on that variable. So if the following line:

z(2) = "Jim";

gets converted to

z.apply(2) = "Jim";

Then why does the line

z.apply(3) = "Roger";

give me a compile time error?

I am new with Scala so any help would be great thanks!

2
Interesting question, since the Array#apply docs state: Indices start at 0; xs.apply(0) is the first element of array xs. Note the indexing syntax xs(i) is a shorthand for xs.apply(i).Kevin Meredith
What you are doing gets de-sugared to update, not apply. The docs for update are similar: Indices start at 0; xs.update(i, x) replaces the ith element in the array. Note the syntax xs(i) = x is a shorthand for xs.update(i, x).Shadowlands

2 Answers

7
votes

This call:

z(2) = "Jim";

Gets translated to

z.update(2, "Jim")

apply doesn't work when you try to assign the value.

Update

You can check it by yourself. Run in the console: scala -print, and type val ar = Array(1, 2, 3)

Then, when you type next line ar(2) = 5, it will show you the generated code. It's a bit complicated (the interpreter adds a lot of stuff for it's own purpose), but you will be able to find this (or similar) line:

    $line3.iw.ar().update(2, 5);
2
votes

The Scala Language Specification - Section 6.15 covers this thoroughly:

An assignment f(args) = e with a function application to the left of the = operator is interpreted as f.update(args, e), i.e. the invocation of an update function defined by f.

So in other words, the compiler changes assignment syntax on the mutable array z from

z(i) = "Name" to z.update(i, "Name")

z.apply(3) = "Roger" isn't covered by this specific rule, so it doesn't work.


Assignment syntaxes from the spec include:

assignment      expansion

x.f = e         x.f_=(e)
x.f() = e       x.f.update(e)
x.f(i) = e      x.f.update(i, e)
x.f(i, j) = e   x.f.update(i, j, e)