I have a question:
What is it mutable field ?
Is it connected with reference ?
If I can create mutable "without" creating record
Thanks in advcane!
Actually, references are implemented in terms of mutable fields:
a reference is just a record with a single (mutable) field named
contents, as you can see in your toplevel:
# let x = ref 1;;
val x : int ref = {contents = 1}
# x.contents;;
- : int = 1
# x.contents <- 2;;
- : unit = ()
# !x;;
- : int = 2
The main way to get mutable fields is to use records, and it is the
way you should prefer. Objects have mutable instance variables. You
can also get the equivalent of references by using one-element arrays.
Related
Could you give an example to this quotation:
A key thing to keep in mind when working with collection interfaces is that read-only collections aren’t necessarily immutable. If you’re working with a variable that has a read-only interface type, this can be just one of the many references to the same collection. Other references can have a mutable interface type
I want to write a function that adds elements to some collection, while creating a val someCollection: List <> in the fun main(). I can do this through the var someCollection: List <> = funAdd(someCollection.toMutable), but can I do it like this without using a variable var?
Example
fun addEl(numbers:MutableList<Int>):List<Int>{
for (i in 1..10){
numbers.add(i)
}
return numbers.toList()
}
fun main(args: Array<String>){
var readOnlyNumbers: List<Int> = emptyList()
readOnlyNumbers = addEl(readOnlyNumbers.toMutableList())
println(readOnlyNumbers.size)
}
Can I avoid using var and reassigment readOnlyNumbers or not?
Here are various ways of rewriting your code without using var:
fun addEl(numbers:MutableList<Int>):List<Int>{
for (i in 1..10) {
numbers.add(i)
}
return numbers.toList()
}
fun main(args: Array<String>){
val readOnlyNumbers: List<Int> = addEl(mutableListOf())
println(readOnlyNumbers.size)
}
or simply
fun createEl(): List<Int> {
return (1..10).toList()
}
fun main(args: Array<String>){
val readOnlyNumbers = createEl()
println(readOnlyNumbers.size)
}
To answer this part:
Could you give an example to this quotation:
A key thing to keep in mind when working with collection interfaces is that read-only collections aren’t necessarily immutable. If you’re working with a variable that has a read-only interface type, this can be just one of the many references to the same collection. Other references can have a mutable interface type
This is simply talking about situations like this:
val mutableList: MutableList<Int> = mutableListOf<Int>()
val list: List<Int> = mutableList
println(list) // []
mutableList.add(0)
println(list) // [0]
Even though list has type List<Int> and not MutableList<Int>, its contents have changed.
Note that this is an example of
I want to write a function that adds elements to some collection, while creating a val someCollection: List <> in the fun main().
as well, but I wouldn't recommend writing this code; go with one of JB Nizet's versions.
I am new to SML, trying to explore SML record and types, specifically how to have function inside a record.
For example, I created below type-
type foo={
var1:int,
f1: int -> int // want to have result of function f1 here
};
Now if I declare record of type 'foo'-
val rec1 = { var1= 10, ....}
I am not getting how to populate the 2nd parameter in the record. f1(10) is giving error.Also, can we declare and define the function inside 'type' like below -
type foo ={
var1:int,
f1 (x)=x+x
};
Please share your opinion.
You need to use a function expression:
val r = {var1 = 10, f = fn x => x}
No, you cannot define the value of a record field in a type definition. But you can define a little helper function as a "constructor":
fun new_foo i = {var1 = i, f = fn x => x+x}
If I have an instance of A, are the instance variables implemented as pointers? In other words, are instance variables accessed by reference, even when using Structs?
class A
#title = "the title"
#my_val = MyStruct.new
end
#my_val is a reference to the instance of MyStruct on the stack. Checkout this example and notice the difference:
struct MyStruct
property x
def initialize(#x : Int32)
end
end
class A
getter my_val = MyStruct.new(10)
end
# mutates a struct (passed by reference)
def method(a : A)
a.my_val.x = 20
end
# does not mutate a struct (passed by value)
def method(s : MyStruct)
s.x = 30
end
a = A.new
p a.my_val.x #=> 10
a.method(a)
p a.my_val.x #=> 20
a.method(a.my_val)
p a.my_val.x #=> 20 (not 30)
I'm learning OCaml, and I'm a bit confused with the immutability of variables. According to the book I'm reading, variables are immutable. So far so good, but why on Earth can I do this:
let foo = 42
let foo = 4242
What am I missing??
I think the best way to explain is with an example. Consider this code (executed in the OCaml REPL):
# let foo = 42;;
val foo : int = 42
# let return_foo () = foo;;
val return_foo : unit -> int = <fun>
# let foo = 24;;
val foo : int = 24
# return_foo ();;
- : int = 42
The above code does the following:
Binds 42 to the name foo.
Creates a function return_foo () that returns the value bound to foo.
Binds 24 to the name foo (which hides the previous binding of foo).
Calls the return_foo () function, which returns 42.
Compare this with the behaviour of a mutable value (created using ref in OCaml):
# let foo = ref 42;;
val foo : int ref = {contents = 42}
# let return_foo () = !foo;;
val return_foo : unit -> int = <fun>
# foo := 24;;
- : unit = ()
# return_foo ();;
- : int = 24
which:
Creates a mutable reference containing 42 and binds it to the name foo.
Creates a function return_foo () that returns the value stored in the reference bound to foo.
Stores 24 in the reference bound to foo.
Calls the return_foo () function, which returns 24.
The name foo is first bound to an immutable value 42 and later it is rebound to another immutable value 4242. You can even bind the same name to variables of different types. In OCaml we are talking not about mutability of a variable, but about a mutability of a value. For example, if you bind foo to an array of values, this would be the same name, but bound to a mutable data, so that the value of a variable can change in time. Finally, each new binding just hides the previous one, so the original foo is still bound to 42, but it is invisible and will garbage collected.
Maybe a little example will clarify the idea:
let example () =
let foo = 42 in (* 1 *)
let foo = 4242 in (* 2 *)
let foo = [|42|] in (* 3 *)
foo.(0) <- 56 (* 4 *)
It might be easier to have the following mental model:
(*1*) +--------+
+----> | 42 |
+------------+ | +--------+
| +----+
| foo +----+ +--------+
| | +----> | 4242 |
+---------+--+ (*2*) +--------+
|
| (*3*) +--------+
+------------> |[| 42 |]|
(*4*) +--------+
On lines 1 and 2 we just bind a variable foo to two different values. On line 3 we bind it to an array that contains one element. On line 4, we change the value, and foo is still bound to the same value, but the value contains different datum.
I hope I didn't confuse you even more ;)
The usual form of let is the let ... in expression, where you define a variable binding, which only exists in the inside of the body of the let. The body of the let is a new scope.
let x = 42 in (* body here *)
Here the "body" of the let is a new scope that is different from the one outside, with all the variables from the outside with an additional local variable x that is only defined in the body of this let.
Now you are talking about lets at the top level of the file. These look a little different syntactically (there is no in), but really they are the same, with the "body" being the rest of the file. So here you can think of the rest of the file after the let as a new scope, with x being a local variable of this scope. So your code is equivalent to this:
let foo = 42 in (
let foo = 4242 in (
(* rest of file *)
)
)
Here your inner let binds a local variable that has the same name as a variable that already exists in the outer scope. That doesn't matter. You are binding a new variable in an inner scope. If it happens to have the same name as a variable in an outer scope, then code in the inner scope referencing that name will refer to the innermost binding. The two variables, however, are completely independent.
In a C-like language, it would be something like this:
{
const int foo = 42;
{
const int foo = 4242;
// rest of code here
}
}
See? There is no assignment to any variables here.
What is difference between plus and plusElement (minus, minusElement) functions over the (immutable) List in practice?
operator fun <T> Collection<T>.plus(element: T): List<T>
fun <T> Collection<T>.plusElement(element: T): List<T>
Besides plus and minus being operators and therefore simplifiable to + and - respectively, I wanted to share an example, that may make it more clear, why plusElement or minusElement may also make sense to use. Basically that's the case when you do not want the overloaded operator methods to be called (e.g. plus(elements : Iterable<T>)), which may be the case when you are dealing with a list of lists.
Maybe the following samples make that clearer. In the samples all variable assignments show the type they got assigned when calling the respective function and contain the result in the comment at the end of the line. The variable ~ending naming convention is the following:
PlusT show calls to plus(element : T)
PlusIterable show calls to plus(elements : Iterable<T>)
PlusElementT show calls to plusElement(element : T)
Samples:
val someEntry = "some entry"
val listOfSomeEntry = listOf(someEntry)
val los : List<String> = listOf("listOfString")
val lsPlusT : List<String> = los.plus(someEntry) // [listOfString, some entry]
val lsPlusIterable1 : List<String> = los.plus(listOfSomeEntry) // [listOfString, some entry]
val lsPlusIterable2 : List<Any> = los.plus(listOf(listOfSomeEntry)) // [listOfString, [some entry]]
val lsPlusElementT1 : List<String> = los.plusElement(someEntry) // [listOfString, some entry]
val lsPlusElementT2 : List<Any> = los.plusElement(listOfSomeEntry) // [listOfString, [some entry]]
val lol : List<List<String>> = listOf(listOf("listOfList"))
// the following is basically not really correct as we are now dealing with a list of lists of strings, but it shows that llPlusT and llPlusIterable lead to the same (in this case probably wrong) result..
val llPlusT : List<Any> = lol.plus(someEntry) // [[listOfList], some entry]
val llPlusIterable : List<Any> = lol.plus(listOfSomeEntry) // [[listOfList], some entry]
val llPlusIterable2 : List<List<String>> = lol.plus(listOf(listOfSomeEntry)) // [[listOfList], [some entry]]
val llPlusElement1 : List<Any> = lol.plusElement(someEntry) // [[listOfList], some entry]
val llPlusElement2 : List<List<String>> = lol.plusElement(listOfSomeEntry) // [[listOfList], [some entry]]
As you can see when using + the overloaded variant plus(elements : Iterable<T>) might be used, which will probably make sense in most cases, but may not make sense in some others, e.g. (most of the times) when dealing with a list of lists. Instead of forcing the + to add a list of lists by using + listOf(anotherList), you may rather want to use plusElement (plusElement(anotherList)) or if you are sure you want to add only a single element, you may want to omit plus in favor of plusElement (probably a very rare and very special use case... that would be reflected with variant llPlusElement1).
Finally the plusElement or minusElement make it really clear from the naming that what you pass reflects 1 single item of the list, whereas + leaves that basically open... (you should see that however from the context, which with a list of list is probably not that clear anyways ;-)). And a disclaimer at the end: that should not mean that you should use a list of lists, but just in case you find something like that you have plus/minusElement at hand ;-)
The first one is an overloaded operator, as indicated by the operator keyword. It allows you to use the + operator with a List<T>.
The second one is a regular function, called in the normal function call style.
Both return a new List<T> with the element appended.
Transcript from the Kotlin REPL:
>>>val a = listOf(1, 2, 3)
>>>a + 4
[1, 2, 3, 4]
>>> a.plusElement(4)
[1, 2, 3, 4]
For more information about Kotlin operator overloading, see https://kotlinlang.org/docs/reference/operator-overloading.html.