Is everything an object in Scala? - scala

A literal is an object in Scala, so if you store that into a variable such as val x: Int = 5; would this make this an object as well? Everything seems like to be an object in Scala for some reason.

A literal is an object in Scala,
Well. "Literal" is a property of the source code, mostly. As such, the idea of "being an object" doesn't really apply.
What is correct is that every literal evaluates to an object.
So, the literal 1 in a source file is not really an object. It is just part of the source code. But it evaluates to an object, namely an instance of the class scala.Int that represents the mathematical idea of the integer 1.
so if you store that into a variable such as val x: Int = 5; would this make this an object as well?
What do you mean by "this"?
x is not an object, it is a variable. In Scala, like in almost every other language, variables are not objects themselves, rather they are names for objects. (Technically, a variable references an object.)
Int is not an object, either, it is a type. Types aren't objects. It is possible, however, that a type and a term have the same name, and the reason why that works is precisely because types aren't objects and thus there can never be any confusion about whether you are talking about the type or the term.
Now, 5 in this expression is an object, or more precisely, as we have seen above, it is an integer literal with evaluates to an object.

Related

How am I able to change this constant? [duplicate]

I'm really new to Swift and I just read that classes are passed by reference and arrays/strings etc. are copied.
Is the pass by reference the same way as in Objective-C or Java wherein you actually pass "a" reference or is it proper pass by reference?
Types of Things in Swift
The rule is:
Class instances are reference types (i.e. your reference to a class instance is effectively a pointer)
Functions are reference types
Everything else is a value type; "everything else" simply means instances of structs and instances of enums, because that's all there is in Swift. Arrays and strings are struct instances, for example. You can pass a reference to one of those things (as a function argument) by using inout and taking the address, as newacct has pointed out. But the type is itself a value type.
What Reference Types Mean For You
A reference type object is special in practice because:
Mere assignment or passing to function can yield multiple references to the same object
The object itself is mutable even if the reference to it is a constant (let, either explicit or implied).
A mutation to the object affects that object as seen by all references to it.
Those can be dangers, so keep an eye out. On the other hand, passing a reference type is clearly efficient because only a pointer is copied and passed, which is trivial.
What Value Types Mean For You
Clearly, passing a value type is "safer", and let means what it says: you can't mutate a struct instance or enum instance through a let reference. On the other hand, that safety is achieved by making a separate copy of the value, isn't it? Doesn't that make passing a value type potentially expensive?
Well, yes and no. It isn't as bad as you might think. As Nate Cook has said, passing a value type does not necessarily imply copying, because let (explicit or implied) guarantees immutability so there's no need to copy anything. And even passing into a var reference doesn't mean that things will be copied, only that they can be if necessary (because there's a mutation). The docs specifically advise you not to get your knickers in a twist.
Everything in Swift is passed by "copy" by default, so when you pass a value-type you get a copy of the value, and when you pass a reference type you get a copy of the reference, with all that that implies. (That is, the copy of the reference still points to the same instance as the original reference.)
I use scare quotes around the "copy" above because Swift does a lot of optimization; wherever possible, it doesn't copy until there's a mutation or the possibility of mutation. Since parameters are immutable by default, this means that most of the time no copy actually happens.
It is always pass-by-value when the parameter is not inout.
It is always pass-by-reference if the parameter is inout. However, this is somewhat complicated by the fact you need to explicitly use the & operator on the argument when passing to an inout parameter, so it may not fit the traditional definition of pass-by-reference, where you pass the variable directly.
Here is a small code sample for passing by reference.
Avoid doing this, unless you have a strong reason to.
func ComputeSomeValues(_ value1: inout String, _ value2: inout Int){
value1 = "my great computation 1";
value2 = 123456;
}
Call it like this
var val1: String = "";
var val2: Int = -1;
ComputeSomeValues(&val1, &val2);
The Apple Swift Developer blog has a post called Value and Reference Types that provides a clear and detailed discussion on this very topic.
To quote:
Types in Swift fall into one of two categories: first, “value types”,
where each instance keeps a unique copy of its data, usually defined
as a struct, enum, or tuple. The second, “reference types”, where
instances share a single copy of the data, and the type is usually
defined as a class.
The Swift blog post continues to explain the differences with examples and suggests when you would use one over the other.
When you use inout with an infix operator such as += then the &address symbol can be ignored. I guess the compiler assumes pass by reference?
extension Dictionary {
static func += (left: inout Dictionary, right: Dictionary) {
for (key, value) in right {
left[key] = value
}
}
}
origDictionary += newDictionaryToAdd
And nicely this dictionary 'add' only does one write to the original reference too, so great for locking!
Classes and structures
One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference.
Closures
If you assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles
ARC(Automatic Reference Counting)
Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.
Classes are passed by references and others are passed by value in default.
You can pass by reference by using the inout keyword.
Swift assign, pass and return a value by reference for reference type and by copy for Value Type
[Value vs Reference type]
If compare with Java you can find matches:
Java Reference type(all objects)
Java primitive type(int, bool...) - Swift extends it using struct
struct is a value type so it's always passed as a value. let create struct
//STEP 1 CREATE PROPERTIES
struct Person{
var raw : String
var name: String
var age: Int
var profession: String
// STEP 2 CREATE FUNCTION
func personInformation(){
print("\(raw)")
print("name : \(name)")
print("age : \(age)")
print("profession : \(profession)")
}
}
//allow equal values
B = A then call the function
A.personInformation()
B.personInformation()
print(B.name)
it have the same result when we change the value of 'B' Only Changes Occured in B Because A Value of A is Copied, like
B.name = "Zainab"
a change occurs in B's name. it is Pass By Value
Pass By Reference
Classes Always Use Pass by reference in which only address of occupied memory is copied, when we change similarly as in struct change the value of B , Both A & B is changed because of reference is copied,.

Is int type in Dart a value type or reference type?

The int type in Dart has default value of null. null is an object of type Null class. (as per Dart documentation). Also, in Dart, int derives from class Object.
Hence,
int i = 10;
print(i.runtimeType is Object); // returns true
This makes me believe that int is not a value type like in other languages (such as C#) but a reference type.
If I am correct, then-
int i = 10;
means i is a reference variable holding the reference to an int object 10.
Is this correct? If not, I would appreciate if a link to the description in the documentation is shared.
Till now, I've been unable to find any proper explanation and hence have come to this conclusion myself.
Thanks.
Yes, Dart's int type is a "reference type".
Dart does not have value types at all, all values are instances of a class, including integers. (At least technically, function values makes their classes very hard to see.)
Integers are immutable and pretends to be canonicalized.
If a and b are int values and a == b, then identical(a, b) is guaranteed to be true, so a and b looks like they are the same object, but it's unspecified whether that's because they really are the same object, or because identical just cheats and does == for integers.
That means that you can largely treat int as a "value type". Whether it is copied on assignment or parameter passing, or you are passing a reference to the same object, is impossible to tell apart. The language ensures that, because it allows the implementations to do whatever is more efficient.
In practice, some integers are unboxed inside functions, some integers are stored as a value in the reference itself, and some are real objects.
(That's also one of the reasons you can't use an Expando with an int).
(In the current Dart language, all types annotations are nullable, meaning that you can assign null to int x;. With the upcoming Null Safety feature, that changes. Types will only be nullable if you write them as such, so int x = 1; would not accept a null value, but int? x; would. And null is an object too, the only instance of the class Null.)
int is a value type in the sense that if you pass int value into a function and change the value of a parameter inside function, it won't affect outer scope.
void add(int inner) {
inner += 1;
}
int outer = 0;
add(outer);
print(outer); // 0, unchanged
But int is still a class even though its name starts from lowercase letter. There was a huge discussion about its naming and lots of people consider it an inconsistency.
Yes int is a class (it even extends num) and therefor has common methods to use on. But one the other side it is different than "normal" classes since you don't have to use a constructor like
int i = int(3);
See int's class documenation https://api.dart.dev/stable/2.8.4/dart-core/int-class.html
Everything in Dart is an object, int, double or num may look like keywords but they are built-in abstract classes. Since they are abstract classes which means they can not be instantiated, they do not start with an uppercase letter.
try this line,
print('2 is instance of "int" class :\t${ 2 is int}');
this will result in true.
And regarding your concern about 'null' :
In Dart, like JavaScript and Python, everything that a variable can hold is an object including null. Every object including null is an instance of some class and all these classes inherit from Object class.
your can refer this link for more info.
Hope this helps.

Add objects from case class in Scala

So, I am new to programming and this might be a very rookie question.
I need to add elements to an object. How is this done?
scala> case class test (
a: String,
b: String,
c: Int,
d: Int
)
var teamData_Temp = test(lol, lel,1, 2)
var teamData_All = teamData_Temp
Then let's say that teamData_Temp becomes teamData_temp = test(kok,kek,3,4) at some point in the script
How do I produce teamData_All = (test(lol,lel,1,2),test(kok,kek,3,4)) ???
Scala is a statically typed language. This means that although variables declared with var can be replaced with a new value, the type of that variable cannot change over the lifetime of the program. The type of teamData_All in your script is test while the type of teamData_All that you are trying to change it to is Tuple2[test, test] (or equivalently (test, test)). These are incompatible types.
If you want to have teamData_All be growable, you have to specify that sort of behavior upfront when declaring the variable, e.g. by making it a list of type List[test]. Then you could have one line set teamData_All = List(test(lol,lel,1,2)) and then have another line set teamData_All = List(test(lol,lel,1,2),test(kok,kek,3,4)).
The reason why this is necessary for a statically typed language is because if you make references to teamData_All in multiple places in your code, there is no way for the compiler to statically, i.e. before running your code, know what the type of teamData_All is at a given point, since you might have changed its type. This makes it impossible for the compiler to make its usual guarantees (e.g. making sure you're only calling methods on things that actually have that method defined).

For an object in scala to be immutable what is required?

Is the answer to this :
Instantiation of the object uses 'val' instead of 'var'.
Each member variable of the object being created is also 'val' instead of 'var'. This is to prevent users updating an object value after its set.
An object is immutable if there is no way for the user of that object to mutate it. This means that it must have no public methods that reassign any of its member variables or mutate any objects referred to by those variables. If all the object's members are vals this ensures the former (i.e. they can't be reassigned), but not the latter (i.e. if the objects referred to by those variables are themselves mutable, they can still be mutated by calling mutating methods on them even if they're referred to only by vals).
Also note that even if the members are declared as vars, the object can still be immutable if none of the object's methods actually reassign the variables (or call mutating methods on them) - assuming of course, they're private.
So having only val members is neither necessary nor sufficient for an object being immutable. Whether the object is referred to by a val or a var (or both) makes no difference in that matter.
#sepp2k nicely and correctly explains the criteria for an object being technically immutable. One subtle point missing from his answer is that not all member variables correspond to externally visible state. A member may also be e.g. a cached internal value to store some local, hard to compute data which is not directly visible from outside (thus qualified as private[this] in Scala). An object can have such a var member e.g. to store a computed hash value. It can even be accessible via a public getter - as long as the behaviour of the accessor is purely functional, i.e. it always produces the same value for each invocation on the same object (except that it returns faster when reusing the internally cached value).
The Scala compiler is aware of this distinction so it can help one to implement an immutable class correctly, even when using mutable state internally. This is important when generic type variance comes into play. Namely, the compiler allows a generic type parameter to be covariant even if the class contains reassignable fields of this type - as long as these fields are private[this], ensuring that one cannot have a reference to a containing object that has a statically weaker type than the type the object was defined with (which would be a precondition for variance to cause type errors).
This is explained in more detail, with a code example, in section 19.7 of Programming in Scala.

Question about Scala variable Mutability

I understand that val keyword determines the underlying variable is a Immutable type (Cannot be reassigned later time). Now i come across a paragraph in programming in scala (Chapter 3, Next steps in scala - parameterize arrays with types), it states
val greetStrings: Array[String] = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "world!\n"
These three lines of code illustrate
an important concept to understand
about Scala concerning the meaning of
val. When you define a variable with
val, the variable can’t be reassigned,
but the object to which it refers
could potentially still be changed. So
in this case, you couldn’t reassign
greetStrings to a different array;
greetStrings will always point to the
same Array[String] instance with which
it was initialized. But you can change
the elements of that Array[String]
over time, so the array itself is
mutable.
so its valid to change the elements of array. And its invalid if we define like this
greetStrings = Array("a","b","c")
It satisfies the below statement
When you define a variable with
val, the variable can’t be reassigned,
but the object to which it refers
could potentially still be changed.
but if i declare something like this
val str = "immutable string"
By the definition given in the book
what it means object to which it refers could potentially still be changed in the above line of code ??
Declaring a val does not guarantee or even imply an immutable type. It only declares what you might call in Java a final variable. The identifier cannot be re-assigned, but the value may be of a mutable type.
In your example of a string value, you have both a val and an immutable type, String. So this identifier is neither re-assignable nor modifiable (immutable).