I am a beginner in Kotlin and going through for loop
Simple code sample:
for (i in 1..5) print(i)
Please can someone advise me why we do not specify the counter/iterator variable type "i" with the keyword var / val. Since "var /val" is the standard way to declare variables in Kotlin.
This is simply how the for loop syntax is designed. I cannot speak for the designers, but I believe that's a design decision to avoid unnecessary bloat, and maybe confusion.
You cannot use an existing variable as the loop variable. The loop variable is scoped to the loop, and shadows existing ones from outer scopes. So it's kind of implied that you're declaring a new variable here, even without a keyword (however I have to admit that the shadowing behaviour would be clearer if we had to write the val/var keyword here).
Also, the loop variable is actually a val inside the loop's body (it cannot be reassigned), but it can feel like a var because it changes for each loop turn and is technically declared outside the loop's body. In effect, it's like a new val declared in the loop's body with a new value for each loop iteration.
So your example code can be thought of as:
var temp = 1
while (temp <= 5) {
val i = temp
println(i)
temp++
}
That's probably why the designers decided to not put any keyword here: it's unnecessary, and both val and var would be confusing in their own way.
Related
I replaced it with Val and the texts did not go away.
Edit: Changing it manually fixed it. But why "var" is it giving an error?
"Variable is never modified so it can be declared using 'val'"
In many languages, compile time validation yields information about the mutability of variables. Variables that do not change value during the execution of a function are invariables. In Kotlin (and some other languages) it is highly recommended to mark those invariables as such (by using the keyword val instead of var).
If you use val, then this has two consequences.
The obvious one is, that the value cannot change any longer. If you try to assign a new value later on, the compiler will yield a compile time error, and you must either assign the new value somewhere else, or change the val back to var. This ensures, that the original value is not accidentally changed.
{
val pi = 3.141d
for (...
pi = 3 // This will not compile
)
}
The less obvious effect is, that any reader of the scope will immediately see that the value will never change during the scope's existence. This is a great benefit in readability, as it signals any reader that variable changes happen elsewhere.
{
val myMessage = "..."
...
// Here I can be sure that myMessage is still "..."
}
It is therefore useful to mark invariables as val, as it helps read and understand the code and adds to safety in execution.
In Kotlin, var denotes a variable that can be reassigned different values, while val denotes a variable that cannot.
If you never reassign a var, it's better to show that you don't need this by using val instead. The compiler can do better optimizations and in particular smart casts with vals.
As a rule of thumb: if the compiler doesn't force you to use var, use val.
If I have the following variables
my $a = 0;
my $*b = 1;
state $c = 2;
our $d = 3;
I can easily determine that $*b is dynamic but $a is not with the following code
say $a.VAR.dynamic;
say $*b.VAR.dynamic;
Is there any way to similarly determine that $c is a state variable and $d is a package-scoped variable? (I know that I could do so with a will trait on each variable declaration, but I'm hopping there is a way that doesn't require annotating every declaration. Maybe something with ::(...) interpolation?)
In the case of the package-scoped variable, not too hard:
our $foo = 'bar';
say $foo.VAR.name ∈ OUR::.keys
where we're using the OUR pseudopackage. However, there's no such thing as a STATE pseudopackage. They obviously show up in the LEXICAL pseudopackage, but I can't find a way to check if they're a state variable or not. Sorry.
To my knowledge, there is no way to recognize a state variable. Like any lexical, it lives in the lexpad. The only thing different about it, is that it effectively has code generated to do the initialization the first time the scope is entered.
As Elizabeth Mattijsen correctly noted, it is currently not possible to see whether a variable is a state variable at run time. ... at least technically at runtime.
However, as Jonathan Worthington's comment implies, it is possible to check this at compile time. And, absent deep meta-programming shenanigans, whether a variable is a state variable is immutable after compile-time. And, of course, it's possible to make note of some info at compile time and then use it at runtime.
Thus, it's possible to know, at runtime, whether a variable is a state one with (compile-time) code along the following lines, which provides a list-state-vars trait that lists all the state variables in a function:
multi trait_mod:<is>(Sub \f, :$list-state-vars) {
use nqp;
given f.^attributes.first({.name eq '#!compstuff'}).get_value(f)[0] {
say .list[0].list.grep({try .decl ~~ 'statevar'}).map({.name});
}
};
This code is obviously pretty fragile/dependent on the Rakudo implementation details of QAST. Hopefully this will be much easier with RAST, but this basic approach is already workable and, in the meantime, this guide to QAST hacking is a helpful resource for this sort of meta programming.
This question already has answers here:
Example of when should we use run, let, apply, also and with on Kotlin
(6 answers)
Closed 3 years ago.
We can write the code with or without let as follows.
var str = "Hello World"
str.let { println("$it!!") }
OR
var str = "Hello World"
println("$str!!")
What is the Actual use of let?.Is that more memory efficient or more readable?
let is one of Kotlin's Scope functions which allow you to execute a code block within the context of an object. In this case the context object is str. There are five of them: let, run, with, apply, and also. Their usages range from but are not exclusive to initialization and mapping.
They are all very similar but they differ in terms of how the context object is referenced and the value that is returned. In the case of let the context object is referenced by the it keyword as opposed to the this keyword. The return value is whatever is returned from the lambda code block. Other scope functions like apply will return the context object instead.
Because let returns whatever the lambda block evaluates to, it is most suited to performing a mapping of some kind:
var upperStr = str.let { it.toUpperCase()}
apply is a more suited function for what you are doing.
To answer your question as to which code is more preferable, it really depends on what you are using the scope function for. In the above case there is no reason to use let. If you are using IntelliJ it will give a warning saying the call to let is redundant. Readability here is a matter of preference, and may be preferred.
The let function is useful when you wish to perform a null safe operation on an Object by using the the safe call operator ?. When doing this the let code block will only be executed if the object is not null. Another reason to use let is if you need to introduce new variables for the operation but you want to confine them to the scope of the let block. This is true for all scope functions, so I reiterate that let is best used for a mapping operation.
Edit: The let function should incur no additional cost. Normally we would expect the lambda/Code-block to be compiled to a Function object but this is not the case for an inline function in Kotlin for which the compiler will emit code not dissimilar to the second code example you have given. See the documentation for more information.
One of usages you can check nullable types
var str: String? = null
str?.let { println("$it!!") }
it's equal
if (str != null) {
System.out.println(str);
}
in Java, but shorter and more useful
let takes the object it is invoked upon as the parameter and returns the result of the lambda expression.
Kotlin let is a scoping function wherein the variables declared inside the expression cannot be used outside.
One of the examples would be here :
fun main(args: Array<String>) {
var str = "Hello World"
str.let { println("$it!!") }
println(str)
}
You can find more information on Kotlin let function here
I really want to know why Kotlin use the word val to stand for constant?
If var means variable.val means what ? val means var + l or val is only one word for short?
In the Kotlin Documentation,we only have the following words.
Read-only local variables are declared using val keyword. Mutable
local variables are declared using var keyword.
This question is not only to make sense of the word val,but also Remind the WORD MAKER to tell us why they name the word,this is not a little thing,this will make us more comfortable to learn the new knowledge,we want to learn and make sense of everything.
For example,many people want to know why Swift use the word let or Why Objective-C use the .m filename extension?
I think the official documentation or response is really important,any guess or assuming is not really helpful,because it's not convictive,the confused will be still the confused.
I also asked this question in the official forum:
https://discuss.kotlinlang.org/t/why-kotlin-use-the-word-val-to-stand-for-constant/4491
Some references:
https://discuss.kotlinlang.org/t/change-val-to-something-else/1180/13
val means value
This is a read-only value.
var is a mutable value
const would on the other hand be not 100% correct. The value PI (3.14..) is a constant. Its value never changes. The value of x in this line val x = random.nextInt() will (hopefully) always be different, but you want the value not to be modified in the function. So the keyword val is quite appropriate.
val keyword is only one word. abbreviation for val not found anywhere. Your question explains what is val.
Read-only local variables are declared using val keyword. Mutable
local variables are declared using var keyword.
Here is a site explains why val is Read-only and not immutable.
http://blog.danlew.net/2017/05/30/mutable-vals-in-kotlin/
val does not mean immutable, val means read-only. That means that
you're not allowed to explicitly write to a val, but it doesn't
guarantee that they're immutable
https://artemzin.com/blog/kotlin-val-does-not-mean-immutable-it-just-means-readonly-yeah/
Kotlin allows you declare get() of the val which breaks immutability
of the property and leaves only read permission for external "users".
Kotlin's syntax is inspired by Scala. In Kotlin several ideas are taken from Scala besides the syntax. Kotlin also adds things on its own and does certain things very differently than Scala (i.e., no implicit conversion in Kotlin compared to Scala). Long matter short: You have to ask the Scala guys why they chose the keyword combination var and val.
val from value.
var from variable.
value - a property such as number assigned to or calculated for a variable, constant or expression(wiki)
variable - a symbolic name associated with a value and whose associated value may be changed(wiki)
When you write out a for loop in javascript like so:
for (var i = 0; i < 10; i++) {
//code
}
is the variable "i" considered global or local? It's not in a function so I'm assuming it's global? Is it wrong then to add another for loop further down the page using the same iterator "i"? Should you name the variable something else?
If the code is in the global scope (i.e. not in a function), then the variable is global.
If you reuse the variable further down in the code, then just omit the var. Declaring the same variable again doesn't cause a problem, but it looks like you are not aware that the variable already exists.
Reusing variables can sometimes make the code harder to follow, but on the other hand in your case it helps to keep the number of global variables down.