function parameters are not allowed to be `var`

998 views
Skip to first unread message

Shelby Moore

unread,
Sep 8, 2013, 3:31:09 PM9/8/13
to scala-...@googlegroups.com
I didn't find the thread that woky said he would create at scala-debate,
so I am creating one to debate it:

http://stackoverflow.com/questions/9535821/scala-mutable-var-method-parameter-reference

I provided my opinion there.

"I agree with woky and will proceed to scala-debate to support his thread
(if I can find it). It makes no sense to force the verbosity, because
overwriting the value in the input parameter does not make the function
non-pure. Only modifying the data contained in that value that the
parameter references would make the function non-pure, and that applies to
the `val` on the members of the class for the data. This is a language
design error."

Haoyi Li

unread,
Sep 8, 2013, 4:56:20 PM9/8/13
to Shelby Moore III, scala-...@googlegroups.com
There also really isn't any reason they shouldn't be allowed to be lazy vals as well. Look at


for an example of this sort of thing. I don't think anyone can argue that 

def <~ [U](q: => Parser[U]): Parser[T] = { lazy val p = q // lazy argument

is really better or more explicit or less error prone than

def <~ [U](lazy val p: Parser[U]): Parser[T] = {

It even needed a comment to explain to the puzzled future-programmer what was going on!



--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jason Zaugg

unread,
Sep 8, 2013, 5:15:10 PM9/8/13
to Haoyi Li, Shelby Moore III, scala-...@googlegroups.com
On Sun, Sep 8, 2013 at 10:56 PM, Haoyi Li <haoy...@gmail.com> wrote:
There also really isn't any reason they shouldn't be allowed to be lazy vals as well. Look at


for an example of this sort of thing. I don't think anyone can argue that 

This request is tracked as SI-240. [1] There are some unresolved corner cases around how lazy parameters would interact with defaults + currying.

With regards to the original question,  I don't think `var` parameters for methods are a likely addition to the language. Scala left behind one or two of the imperative-oriented features of Java to keep the language a little smaller -- for example we don't have pre-/post-increment.

-jason

Shelby

unread,
Sep 9, 2013, 1:08:49 AM9/9/13
to scala-...@googlegroups.com, Haoyi Li, Shelby Moore III
On Monday, September 9, 2013 5:15:10 AM UTC+8, Jason Zaugg wrote:
With regards to the original question,  I don't think `var` parameters for methods are a likely addition to the language. Scala left behind one or two of the imperative-oriented features of Java to keep the language a little smaller -- for example we don't have pre-/post-increment.

If I am not mistaken, `var` parameters are the default for non-case class constructors. This is another example of lack of regularity in the language. Such inconsistencies cause bewilderment for the programmer. And we saved how many lines in the grammar and in the compiler to make it non-regular for how many targeted millions of programmers (hopefully)?

Also I don't agree it is an imperative feature, but that is a deeper discussion:

http://stackoverflow.com/questions/602444/what-is-functional-declarative-and-imperative-programming/15382180#15382180

"The declarative property is where there can exist only one possible set of statements that can express each specific modular semantic.

The imperative property is the dual, where semantics are inconsistent under composition and/or can be expressed with variations of sets of statements."

Ben Hutchison

unread,
Sep 9, 2013, 3:27:17 AM9/9/13
to Shelby, scala-debate, Haoyi Li
On Mon, Sep 9, 2013 at 3:08 PM, Shelby <she...@coolpage.com> wrote:
On Monday, September 9, 2013 5:15:10 AM UTC+8, Jason Zaugg wrote:
With regards to the original question,  I don't think `var` parameters for methods are a likely addition to the language. Scala left behind one or two of the imperative-oriented features of Java to keep the language a little smaller -- for example we don't have pre-/post-increment.

If I am not mistaken, `var` parameters are the default for non-case class constructors. This is another example of lack of regularity in the language. Such inconsistencies cause bewilderment for the programmer. And we saved how many lines in the grammar and in the compiler to make it non-regular for how many targeted millions of programmers (hopefully)?

I think you are mistaken. Val parameters are the default.

scala> class Foo(s: String) { s = "string" }
<console>:7: error: reassignment to val
       class Foo(s: String) { s = "string" }

-Ben 

martin odersky

unread,
Sep 9, 2013, 3:56:26 AM9/9/13
to Shelby, scala-debate, Haoyi Li

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

martin odersky

unread,
Sep 9, 2013, 3:57:42 AM9/9/13
to Shelby, scala-debate, Haoyi Li
On Mon, Sep 9, 2013 at 7:08 AM, Shelby <she...@coolpage.com> wrote:
On Monday, September 9, 2013 5:15:10 AM UTC+8, Jason Zaugg wrote:
With regards to the original question,  I don't think `var` parameters for methods are a likely addition to the language. Scala left behind one or two of the imperative-oriented features of Java to keep the language a little smaller -- for example we don't have pre-/post-increment.

If I am not mistaken, `var` parameters are the default for non-case class constructors. This is another example of lack of regularity in the language. Such inconsistencies cause bewilderment for the programmer. And we saved how many lines in the grammar and in the compiler to make it non-regular for how many targeted millions of programmers (hopefully)?

You are mistaken. 

 - Martin

 
Also I don't agree it is an imperative feature, but that is a deeper discussion:

http://stackoverflow.com/questions/602444/what-is-functional-declarative-and-imperative-programming/15382180#15382180

"The declarative property is where there can exist only one possible set of statements that can express each specific modular semantic.

The imperative property is the dual, where semantics are inconsistent under composition and/or can be expressed with variations of sets of statements."

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Shelby

unread,
Sep 9, 2013, 8:48:11 PM9/9/13
to scala-...@googlegroups.com, she...@coolpage.com
Okay thanks, but it doesn't really reduce my point, which is that since Scala allows to declare case class constructor parameters `var`, where I;ve read (at Daniel's codecommit and stackoverflow) that case classes are supposed to be ADTs and thus time invariant in the strictest theory of ADTs, I conclude that preventing the same for functions is an inconsistency a.k.a. irregularity.

=====================
P.S. I like to remember details in broadest applicable concepts. Conceptually I thought the case class was supposed to be the ADT and the regular class was supposed to be the general OO non-referentially transparent paradigm, thus I am thinking there is an inconsistency with that concept, given that regular class constructor parameters are not `var` by default. Of course I understand the benefit of immutability and referential transparency (I want to do 90+% of my coding in that paradigm), yet I understand Scala is to be multiparadigm so as to support 100% of needs, thus I would have preferred not to violate the conceptual boundary, unless there was some other compelling reason to do so?

(Ignore if you don't want to read my opinion): It is not that I am against details, it is just that I have high-level semantic details in my head from numerous different areas (e.g. algorithm and economics details around creating a better Bitcoin that changes the way humans harvest energy so we can stop this nonsense of turning the M.E. into chaos in order to protect the centralization of control over energy) that I am working in and interested in. So I want unnecessary inconsistencies out-of-my-way. I don't think this is unique to me, but rather you will find this is the case for most of humanity. Simplicity is beauty. Of my million users commercial projects, two were all about removing hassles and details from the lives of creative people:

http://download.cnet.com/Cool-Page/3000-10247_4-10024827.html
(335,000 confirmed websites by Altavista in 2000, arguably the precursor to friendster and myspace, C++)

(see the ad at the bottom, which I designed at age 21, product had 30% global marketshare on Atari ST, MBs of 68000 asm and C)

It is possible that those who spend most all of their time working on and with Scala, have a warped perspective about the level of details that are inordinate to impose on someone who just wants to use the language effectively but not overly intrude upon their more important high-level details. I think one of my strengths in life is that I have a wide variety of interests and thus I strive always to reduce things to their GENERATIVE essence, so I can do more with more concepts. This has made me successful when targeting the broad population, and I was even involved early with what become Corel Painter which was the world's first and most popular natural media simulation (pressure table) painting with millions of users.

Ken Scambler

unread,
Sep 9, 2013, 9:32:18 PM9/9/13
to Shelby, scala-debate
No need to trot out the CV, your arguments will do fine on their own.

Scala deliberately unifies ADTs and class hierarchies.

You can write operations that pattern match over the operations, or you can add methods to the classes in the hierarchy.  You can leave them as immutable, or encapsulate mutable state within them in a normal OO way.  They are not really supposed to be two different things; it is really just two different styles of using the same thing.

Allowing mutable state within a class is a feature; you can do things with the class that you wouldn't otherwise be able to do.  (Whether you should is another matter, of course :-)  

Allowing a mutable var as a method parameter doesn't unlock any capabilities in the language; it gives you a meaningless choice that buys you nothing, where one option is clearly superior to the other in almost any conceivable situation.

Cheers,
Ken


--

Shelby

unread,
Sep 9, 2013, 10:04:48 PM9/9/13
to scala-...@googlegroups.com, Shelby
On Tuesday, September 10, 2013 9:32:18 AM UTC+8, Ken Scambler wrote:
No need to trot out the CV, your arguments will do fine on their own.

I've been on these forums for I guess going on 2 years. I've never mentioned it before. 

It seems at least one person (Miles Sabin) thought I was trolling and trying to discredit me. I wanted to make it clear from what perspective I come here. I do not come from academia, and I hope that is clear now. I come from the real world of shipping products to millions of eyeballs.

Below you are speaking in academic terminology, e.g. "operations". I can understand it now (from discussions of the Expression Problem), because I've read so much since starting to learn Haskell and Scala, but many (perhaps most) programmers would have no clue what you are writing below.

There are many programmers (in the broadest sense of the taxonomy) which are autodidacts.

Scala deliberately unifies ADTs and class hierarchies.

You can write operations that pattern match over the operations, or you can add methods to the classes in the hierarchy.

In both cases, the Expression Problem is not solved, either you have the fragile base class problem (can't add methods to the base class) or the fragile match-case where you can't add operations (functions or new types), because you can't add new cases to every `match` clause in the universe.

 
  You can leave them as immutable, or encapsulate mutable state within them in a normal OO way.  They are not really supposed to be two different things; it is really just two different styles of using the same thing.

I just don't see any logic about why you mention the Expression Problem.

An ADT should be time-invariant and OO approaches state management on a different semantic level, so why conflate the two concepts?

Allowing mutable state within a class is a feature; you can do things with the class that you wouldn't otherwise be able to do.  (Whether you should is another matter, of course :-)  

I don't see where you have made any cogent argument against my point, which is that for an ADT the class should be immutable according to the theory. If you want to deviate from that, it is a feature. Okay fine. But my point is that for the general OO semantics, there is no such applicable theory, and thus the constructor parameters should be `var` by default and so as to provide a clear boundary between the concepts of a class. 

Allowing a mutable var as a method parameter doesn't unlock any capabilities in the language; it gives you a meaningless choice that buys you nothing, where one option is clearly superior to the other in almost any conceivable situation.

 Allowing a mutable `var` as a regular OO class constructor parameter does unlock capabilities (that are default in Java, C++). So if those were the default, then I would wonder why methods can't be `var` especially when even ADTs are allowed to be `var`.

Okay you are saying that for classes there are significant capabilities unlocked for mutable fields, but there are also capabilities unlocked by making a method parameter re-assignable (it doesn't make anything mutable from the outside as class fields do). So I understand now making method (function) parameters re-assignable by default, because it prevents a silly human error, so we force the user to declare them var to make sure that is their intent. But why force the noise of another identifier by not allowing `var` in the parameter list? I end up prepending underscores on the method parameter which is needless noise.

Sorry inconsistent.

Ken Scambler

unread,
Sep 9, 2013, 10:36:59 PM9/9/13
to scala-debate

I just don't see any logic about why you mention the Expression Problem.

An ADT should be time-invariant and OO approaches state management on a different semantic level, so why conflate the two concepts?

I don't see where you have made any cogent argument against my point, which is that for an ADT the class should be immutable according to the theory. If you want to deviate from that, it is a feature. Okay fine. But my point is that for the general OO semantics, there is no such applicable theory, and thus the constructor parameters should be `var` by default and so as to provide a clear boundary between the concepts of a class. 

Sorry if I was unclear - the point is simply that Scala is designed to unify the two concepts (ADTs/Pattern-matching vs Classes/dynamic dispatch), rather than having separate features and making you choose.  You can mix and match between them.  Your point that "ADTs are ADTs and classes are classes, and never the twain shall meet" might or might not be a good one, but that is not how the language has been designed.

 Allowing a mutable `var` as a regular OO class constructor parameter does unlock capabilities (that are default in Java, C++). So if those were the default, then I would wonder why methods can't be `var` especially when even ADTs are allowed to be `var`.

Okay you are saying that for classes there are significant capabilities unlocked for mutable fields, but there are also capabilities unlocked by making a method parameter re-assignable (it doesn't make anything mutable from the outside as class fields do). So I understand now making method (function) parameters re-assignable by default, because it prevents a silly human error, so we force the user to declare them var to make sure that is their intent. But why force the noise of another identifier by not allowing `var` in the parameter list? I end up prepending underscores on the method parameter which is needless noise.


The effects of a "var" method parameter are invisible outside of the method.   Although they are allowed in C++ and Java, style guides for these languages often forbid directly reassigning arguments because of the potential for confusion and error.   It is never required; code can always avoid it with minor adjustments.

Var as a constructor parameter gives you mutable state in your object, which lets you model identity and change over time in an efficient, but complex, way.  It is useful at times, and occasionally indispensable.

The two cases here are wildly different in their utility as language features.  There's no reason to think that because you provide the useful one, you should also provide the useless one for consistency.

Som Snytt

unread,
Sep 10, 2013, 12:17:06 AM9/10/13
to Shelby, scala-debate
Kind of fun to know what "coolpage" is.


> arguably the precursor to friendster and myspace

That reminds me, I still have a pet on dogster.
Seeing the old faces makes me wish dogster had unlimited undo.  Or I guess I mean, "re-do."


> You are mistaken. 
>
>  - Martin

I would frame that and hang it next to my first LGTM.



--

Shelby

unread,
Sep 10, 2013, 1:42:57 AM9/10/13
to scala-...@googlegroups.com
On Tuesday, September 10, 2013 10:36:59 AM UTC+8, Ken Scambler wrote:
Sorry if I was unclear - the point is simply that Scala is designed to unify the two concepts (ADTs/Pattern-matching vs Classes/dynamic dispatch), rather than having separate features and making you choose.  You can mix and match between them.

And I am not arguing against that flexibility. I just assumed the default for OO classes would be what Java and C++ newbies would expect, as a good forethought not to cause them undue head scratching.
 
  Your point that "ADTs are ADTs and classes are classes, and never the twain shall meet" might or might not be a good one, but that is not how the language has been designed.

I am not implying such. I was writing about the defaults.

The effects of a "var" method parameter are invisible outside of the method.   Although they are allowed in C++ and Java, style guides for these languages often forbid directly reassigning arguments because of the potential for confusion and error.

Agreed. So Scala made the default val. Fine.
 
  It is never required; code can always avoid it with minor adjustments.

If I want to reuse an existing identifier, I can't without creating another identifier. Why do you say it is better to force me to create another identifier than simply adding var to the front of my parameter?

I can't understand why it takes so much explanation to get that simple point across.

Var as a constructor parameter gives you mutable state in your object, which lets you model identity and change over time in an efficient, but complex, way.  It is useful at times, and occasionally indispensable.

Agreed. And I said should be the default for OO classes, but not for ADTs (case classes).
 
The two cases here are wildly different in their utility as language features.  There's no reason to think that because you provide the useful one, you should also provide the useless one for consistency.

Consistency is very important, because it impacts on the level of consternation and misunderstandings out there.

John Nilsson

unread,
Sep 10, 2013, 9:33:53 AM9/10/13
to Ken Scambler, scala-debate
I think the case for reassignable arguments is to constrain the scope of the untreated input. While mutability might be the wrong way to go about it, surley the concept of limited scope is a good thing?

Maybe an option to explore is to extend the default parameter value syntax to support expressing derived from the input?

Example:

import scala.math.Ordering.Implicits._

def bounded[T:Ordering](lower:T, upper:T)(value:T) = lower max value min upper

def someDef(input:Int = bounded(0,10)(value)) = input something or other


BR,
John

Alexandru Nedelcu

unread,
Sep 11, 2013, 2:11:55 PM9/11/13
to Haoyi Li, Shelby Moore III, scala-...@googlegroups.com
On Sun, Sep 8, 2013 at 11:56 PM, Haoyi Li <haoy...@gmail.com> wrote:
> There also really isn't any reason they shouldn't be allowed to be lazy vals
> as well.

Lazy vals are also not allowed in case classes either. And they should be.

--
Alexandru Nedelcu
www.bionicspirit.com

Naftoli Gugenheim

unread,
Sep 18, 2013, 3:15:23 AM9/18/13
to Alexandru Nedelcu, scala-debate, Haoyi Li, Shelby Moore III

+1

Reply all
Reply to author
Forward
0 new messages