Change val to something else?


#1

To me, 'var' and 'val' look (optically) almost the same. Theay are both 3 chars wide and start with 'va'. I can image that occasionally they can be confused. What about 'final' or 'const'? Of course, there reasons to have it that way - it's fast to type, but 5 chars instead of 3 will do as well. And, 'val' doesn't sound as opposite of 'var': var stands for 'variable', so something that can not be changed.. is not value but is a 'constant'. 'val' could also imply that something is passed by value..

Could we organise a vote for the best keywords?


#2

Yes, voting is good idea. My proposal is rename "var" to "mutable". The reason is to use more val's in code, this is more safe and comfortable.


#3

A good idea is rename val to const. var - variable const - constant

mutable is a bad name as for me


#4

+1 for 'const'.


#5

+0 (I was fine with "val" as it resembles Scala and I like similarities in languages and the IDE could color "val"/"var" differently but "const" isn't bad either.)


#6

val and var very similar and I can make a mistake when writing.


#7

I think 'val' and 'var' are fine.  I never had a problem with them in Scala.  But if there really has to be a change I agree that 'var' should change to something like 'mutable'.  It should be easier to create final variables than mutable ones.

Chris


#8

Renaming val to const won't work for properties of classes: those properties may be far from constant.

But we could think about renaming var to something else…


#9

In relation to the other thread I posted about var's being SharedObject, I'd rather see var get changed to something like 'mutable', or maybe even 'let x = ...' over changing the val but either way would be acceptable.

However, if we’re looking at changing val/var semantics, has anyone thought about lexically scoped val’s?  Something maybe like:

let (x = 5, name = “Mark”) {
  doSomethingWith(x, “$name was here}”)
}

here, the immutable vars are bound to the context of the closure, this style of construct could also work well for ARM blocks, at the end of the closure call .close() on any let’d variables.

let (reader = BufferedReader(FileReader(File(“foo.txt”)))) {
  // something with reader
}  // reader.close() happens here?


#10

Yes, we are playing with this kind of idea for a long time now, but it doesn't seem to fit very well so far...


#11

What sort of problems do you encounter with it? Or was it more a "it didn't feel right"? I could see you one might end up a lot of nested code quite easily, but that might just serve to yell "refactor" to you :)


#12

First of all, it's hard to make general enough: simple 'let' is good, but what about 'if' and 'custom control structures' like forEach or 'try with resources' that you proposed? Also, having two disconnected ways of defining an immutable variable ('val' and 'let') feels wrong.


#13

My bad - I should have made it clear that I assumed "changing val" implied deprecating/removing val in favour of let.

One generic way I was thinking it could be implemented, from a very naive perspective is that:

let (x = 5, name = “Mark”) {
  ///
}

under the covers generates the equivalent of something like:

class $1(val x: Int, val name: String) : Closure {
fun run() {
  // this has access to immutable, class local vals x and name
  }
}

$1(5, “Mark”).run()

I’ve not looked at how the closures are actualy generated so not sure off hand if this is anything like whats really done currently. Altho, given this isn’t really a closure to pass around, it could just generate a method:

fun $1(x: Int, name: String) : <TypeOfLastStatementReturn> {
  //
  false
}

This would allow for dong “return let(…) {…}”, the conumdrum I just ran myself into is dong:

val foo = let (x = 5, name=“Mark”) {
  // locally scoped x and name, return something
}

In trying to replace val, I’ve just come in full circle :frowning: which maybe implies such lexically scoped vals are separate things entirely.