Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 27

01/03/2021

Mutable variables: variables that during its lifecycles can be re-assigned.

In the example we can deduct the type of v and s because we initialize the variable immediately.

1: Kotlin Pag. 1 a 27
Difference between && and “and”. The first is lazy; a && b if a is false b is not evaluated. The second is for
eager evaluation, example: if (myNumber != null & myNumber.Value == 7). In this case
the second expression is evaluated too, and we initialize the value to 7

Triple double quotes used for express string constants which spends over many lines. All notation support
templating.

If clause is an expression and each branch returns a value. If( a>b) a else b replace if (a>b) ? a :
b. If our if clause contains in the branch more than one element/statement, the last one is considered the
result of the expression. Switch doesn’t exist; replace with when.

1: Kotlin Pag. 2 a 27
In Kotlin primitive types that are variable that directly contains the value does not exist. Everything is
reference (they have the pointer inside the variable block that points to a block with a value). In Java you
have two types of int (value type) and Int (reference type). All variable contains a pointer and when you
compare two variable you can compare the structural equality (compare the value pointed) or referential
equality (compare the pointers stored inside the element).

In the floating points representation, there are two different representation of the zero (+0 and -0); when
you use == or === both representations are considered equal because both contains the zero number.
Instead with the .equals you consider this distinction.

String case: the 1 2 3 of s2 and s1 are stored in different location. == true because they have the same
content while === is false because they are stored in different places.

Class case: if we tried to compare both instance of the class c1 and c2 we obtain false with === (they are
not in the same location). We obtain false even with == or equal because if we do not override the equals
method, we get the default implementation of equal that is the ===.

Kotlin has a special kind of classed called data class; easy for programmer to store data together in same
container. They have an automatic implementation of the equals method, so in this case d1==d2 is true.

Something similar exists with collection (array list in the example). Even if l1 and l2 live in different memory
address l1==l2 returns true.

1: Kotlin Pag. 3 a 27
Take into account that alphabetical order compare the code point in Unicode behind the letter ( ì is after z).

We can change the order of the function parameter by explicitly the parameter name.

Infix is useful for override operator.

1: Kotlin Pag. 4 a 27
You can specify the type T when calling the generic function; is useful only when the compiler did not
understand the type (it cannot infer the type). In the example we don’t want to have the string type but a
char sequence type; for this reason, we explicit the type.

l.forEach { it -> println(it) } -lo stesso- l.forEach { println(it) }

ForEach is a method that accept only a parameter (the lambda), for this reason we can take out the lambda
e cut off the parenthesis. This will be .forEach( {…} ) to .forEach() {…} to .forEach {…}.

make_generator return a function; this function takes


no parameter and return a string () -> String

g1 is a function which is returned by make_generator.


Each time g1 is invoked return a new string.

Error slide: ${base}_$i

Function g1 is a closure because inside it keep


reference of the string g because is provided at the
time of invocation and the variable i.

1: Kotlin Pag. 5 a 27
Usually, we aspect that local variable i stop to exist when the function make_generator returns; but if the
function does return another one and the returned function contains a reference to the local variable, the
life cycle of the local variable is increased. i remains imprisoned inside the closure and each time invoke g1,
it remembers the value of i. Otherwise g2 is a difference function with a difference instance of i.

We write something that maybe used as if is part of the class, but it can see only the public part of it. The
class that we want to extend because the receiver object and we can use the ‘this’ word to represent it.

‘n’ contains an integer (5), but statically is not an Int but a Number; you cannot invoke isEven(). Only to
subclasses of Int and not super classes of int.

The compiler is detected that we define a function apply to any


string (String.). Inside the body we can access only what is public
and we can refer inside the function to the object that is applied
(receiver in this case is ‘s’) with the classical this keyword.

In this case we want to access to the length method (public) of the


string object ‘s’. ‘This’ in this case is ‘s’.

1: Kotlin Pag. 6 a 27
HOF may have some troubles because they tend to create closure. The function that accepts like parameter
or the function that return as a result are objects which is allocated onto the heap. Each time the function is
invoke one or more objects are allocated. This may create some overhead when compile to Java 6
bytecode. With Java 8 this problem is less important. With inline you can fix this problem, only for function
with few lines of code.

A is the receiver and inside the body of the function is referred by ‘this’ keyword.

Apply can be used with any type T. Apply accepts a lambda as parameter and this lambda will be invoke and
return the this. This is possible because the add method apply in the context of the element left to the dot
(al). In this case is like we do al.add(…).

1: Kotlin Pag. 7 a 27
To introduce the constructor, we use the special keywork ‘constructor’ instead of the name of the class like
in cpp. Primary constructor is outside the parenthesis. The secondary constructors do have block of code
while the primary one does not have any block of code.

Since the constructor has a parameter s preceding by val,


s is becoming an attribute (read only) of my class. With
var instead you can modify it.

If we drop var before s, you are not able to do c1.s


because s is a parameter pass inside the constructor and
live only inside the function.

The secondary constructor should always delegate to the primary constructor.

This class has two method s and m.

1: Kotlin Pag. 8 a 27
When we define a property like the age and we access his value with obj.age, the default getter is called.

hasStrongPassword is a method.

Usually, properties are automatically stored in a hidden field inside a class instance, but this is not
necessary so we can override some kind of behavior. Particularly this is useful when we want to apply some
common pattern. One of these patterns is the observable property: is a property that whenever is changed
derives an event that can be forwarded to the listeners or a vetoable property that for example prevent a
property for changing if it does not satisfy a constraint.

1: Kotlin Pag. 9 a 27
Kotlin have a support for this via the delegated property. When we introduce a class C with a parameter
_name and property called name. name is the same of _name but when it changes something happens.

We can say that name is provided by an object capable of storing a value for me. This construct tells the
compiler that name is actually a property, but the getter and setter of this property is provided by an object
(delegates) which is return by the function vetoable. This function accepts the initial value and a lambda.

When the function is invoked return the name of the property, old value e new value and the lambda is
going to return a Boolean and such a Boolean is true (I let the change to happen) and false (I don’t let the
change to happen).

This means that such a property name can be changed from outside only provided that the new supply
value is larger than the previous one (in this case alphabetically).

The interesting thigh is that I can use different thighs instead of vetoable; I can use a map. Instead of
providing _name we pass a mutable map accepting a string and a generic class Any. I can say that name is a
string and is provided by the map. The mutable map will use the name of my property as the key of the
name and change the associated value with the new value.

I create a class with two properties both


provided by a map. The map is the actual
place where the value of these two
properties will be stored.

Override the get method to retrieve inside


the map the value associated with the
specific key (c.name search inside the map
the key ‘name’ and returns the value).

Also override the set method. Change the


value inside the map associated with the
key.

Only maps with a string as key can work as a


backing store provider.

1: Kotlin Pag. 10 a 27
This is interesting because if I create another instance of C based on the same m.

At the beginning both is empty, then I assigned beta to c and c2 is changing itself because they are used the
same backing store.

1: Kotlin Pag. 11 a 27
The name is the same, age instead are mutated separately because is not delegated

Basically, when you create you say, “by a given delegate”. You need to provide like a delegated an instance
of the class that has pair of operator function (getValue invoked for fetching the content and setValue
employed for providing the content).

When the compiler sees by MyDelegate, it does override p saying is a string property where the getter
method is actually taken from the instance of class myDelegate created and private. I use that to invoke
getValue or setValue

There are some ready made deleted. An example is the lazy function that takes a lambda and return an
instance of lazy class which is capable of storing a single value that doesn’t allow any modification, you can
only assign to val attributes by lazy. The idea is that computing the value of this property is expenses so we
can delegate to the function only if and when someone want the value.

We can use instead delegate observable that gives us the possibility to manipulate the value and give some
kind of side effect or broadcast and event saying something happened.

1: Kotlin Pag. 12 a 27
In delegate.vetoable that has almost the same syntax of the observable. The only difference is that the
lambda function is not unit in return type but it’s Boolean. If return true the assignment is performed
otherwise nothing changes.

You can create in a class not only method or variable (that refers to this automatically) but also defined
some method or property as static. Static means it doesn’t belong to the specific instance. A static variable
is actually a kind of global variable and the static method doesn’t require an instance of the class, but you
can invoke it simply by the class.

In Kotlin there is no support for static object member. Most of the time we don’t need static method
because we can use simple functions. The presence of this things pollutes the class because you don’t have
any reason to put in that class.

If we create a top-level function of any kind and we see the generated bytecode, we can see that Kotlin will
have generated a class which has the same name as the file in which the function was declared preceding
by the package name. Inside this class there is a public static final method. So the top level function actually
are static method.

There are others situation in which we don’t want specifically top-level function. We need to put some
constraints. For example, we want for the given object only a single instance (singleton). In a situation in
which all method or property need to be static, in Kotlin we can say that is not a class but an object. We can
drop the class keyword and replace with object keyword. Since foo is an object, we can write Food.method.

1: Kotlin Pag. 13 a 27
If we decompile, we can see that the compiler translated such notation of the foo into a Java class that
contains the same method that we have defined like an instance level method. The compiler not only
generate the method inside, but it added couple new thing. One is the constructor made private, then for
any field or propriety static we first access to the instance. There is a public static field called instance that
contains the only instance of this class. This is the only instance because the constructor is private and the
field initialize of the static block that says when the class is loaded in the filesystem, instantiated the class
itself and save the reference, then populate the property with the default value.

When we have object that have only static members, we can simply drop the class name and replace with
object, but there are situation in which you want to have in a class both instance level and class level (that
is static method and properties).

In order to solve this situation, Kotlin introduced a concept that looks strange at the beginning. It tells you
that the static part of the class can be placed inside a companion object. Companion object is just a way
that allows us to mix method which are instance level with method of class levels.

Basically, a companion object is just an object which is refers to all instanced of the class. All instances of
the class will have inside the memory, a pointer to that companion object. Moreover, from the syntactical
point of view, Kotlin let us invoke method and property with a simplified version className.method like is a
static method.

Since is a part of the class, if there is anything inside declared private or protected, the companion object
can see all. You can implement the factory pattern; you have a class, and you want to prevent to directly
instantiation. So, you make the constructor private, and this prevents people for instantiated it, but you
add a static method which is responsible to invoke in a controlled way the constructor. Only this function
will invoke the constructor.

In any situation in which you have to match static and instance level methods and properties, the
companion object is the solution.

1: Kotlin Pag. 14 a 27
Java Syntax Kotlin

In Java we have primitive type and reference type (are those that contain a pointer to somewhere else); a
string is a reference type in Java. In Java you can store the keyword null as a value of the pointer, that
means the string does not contain any content (the object is empty).

This was considered the billion-dollar mistake of the century not because we don’t need to express the fact
that sometimes pointer do not contain a legal value (in a linked list is important to distinguish if the
element has a next element or not). Since whenever you have a reference, this can be invalid, this derive
you a lot of potential thread because of if…else in order to check that you are not trying to dereference a
pointer invalid making the code unreadable. If you don’t do that at runtime you can get errors
(unpredictable ways).

People that design the Kotlin languages choose to improve the type of system distinguishes between those
type which can be null and those that cannot. The basic idea is to augment the type of system. You
distinguish if is null o not with a ‘?’. The compiler control that you never try to assign a null to a variable
without ‘?’.

The Kotlin compiler use logic to prove that is not possible inside a having a
null. Once you know that theoretically you don’t need any check at all. If

1: Kotlin Pag. 15 a 27
you say is nullable the compiler know that the variable is dangerous, and you can’t use b like you use a. You
can’t inspect the property b.lenght without ‘?’.

Safe call operator can be chained because they return ‘Type?’ (es. b? returns int? and you can do .? again).

?: if you want to provide an else branch.

In some situation you may want to consider b as not


null; you pretend b is not null. If you pretend not null
but in some case is null, it breaks at runtime. You need
care when you use this.

The compile promotes String?  String because you check the nullity (ONLY IF IS VAL)

Breaks because is a mutable global variable. May happen that in the current thread when check the null
effectively is not null, but another thread may exist and, in the time, you check the not null, can change the
value of b and in the next expression run an exception. The promotion doesn’t work anymore.

1: Kotlin Pag. 16 a 27
The fact that classes may be nullable or not is a big impact in the inheritance hierarchy of Kotlin classes.
Basically all non-nullable classes in Kotlin do derive from a class called Any which is not java.lang.Object
because in Java object have some method which are relevant and sensible for representing the standard
object orientation thing and also some method like wait and notify which only have a meaning in term of
concurrent execution. Since Kotlin is a multiplatform and can be runner in JavaScript machine also where
thread does not exist, is not possible to have those methods.

Moreover, by default classed cannot be extended; only if the class has an open annotation.

Of course when we create a derived class we have the responsibility to invoke the proper constructor of
the super class; this is done in the syntax with : .

Differently from cpp where multiple inheritance is possible, in Kotlin only single inheritance is allowed.

The class can also implement zero or more interfaces. In the example we defined a class Rectangle and an
interface Polygon with a method draw. In interface we do not have to use the open. Then we create a class
Square which inherits from rectangle and implements polygon. Since I want to extend those class and
override the method I need to use override keyword.

The kotlin type system is at least strange. We have as top most class that is a class that doesn’t extend
anything Any?. This is the top of the hierarchy, it means something that is nullable and which if not null can
be whatever else. Note that any? Is extended by Any and also by all the question mark classes. This is
possible because is legal to store null in a Boolean? Is legal to store in Any?

1: Kotlin Pag. 17 a 27
Boolean extends Boolean?, because is a restricted case; Boolean? Contains Boolean and null.

We have nothing? Does extend all the other. When the compiler found the null keyword in Java, we don’t
have a type, in Kotlin instead the type is Nothing. But Nothing? Is not the bottom, the bottom on hierarchy
is Nothing.

Class nothing has no instance, exist only for a logical point of view in order to allow the compiler to have a
complete type system. Nothing extends whatever class, all possible class are extended by Nothing, but
unfortunately Nothing has no instance. Nothing? Has a instance called null.

Is there because the compiler needs to represent a block of code that can’t be executing, for example when
you found an exception the execution can go over, so the result value of the throw keyword is nothing. The
same if you have a while condition and inside you don’t have a break, the next line after the while are not
reachable.

08/03/2021

The hierarchy system and the inheritance are really


part of the life of Kotlin, but apparently it seems that
somewhat take a secondary path because by default
class cannot be extended. To be extendable, the class
need to be declared as open.

If you have an open class by default its method cannot


be overridden. If you want to override them, you need
to mark the method open as well.

Derived classes need to proceed the overridden method with the override keyword. In Java is only an
annotation while in Kotlin is a mandatory keyword of the language.

The reason you need to do that is because the compiler knowing that something is not mutable can
perform a lot of optimization. The fact that in Java each class or method unless explicit define as final could
be subclasses and overridden, is actually a big mistake in terms of runtime performance. This because the
compiler is obliged to create a virtual invoke that is a special kind of function call that needs to verify at
runtime which is the actual type of the method is invoke. This time for this reason is twice longer.

Since in most situation we don’t want to extend or override nothing, Kotlin classed tend to be more
performance. However, if you need to extend something you can declare classes or method as open.

Of course, when you invoke an overridden function or an open function the bytecode will contain the
virtual invoke and your code is less fast, but this is because you need it.

1: Kotlin Pag. 18 a 27
Kotlin does make dealing with simpler type easier than Java. The quickest way to define a group of property
that need to live together can be achieve defining a class with the keyword Data (like struct of C++).

A data class is characterized by the fact that the primary constructor should have a single parameter; they
are created to store information that leave together without having any special behavior. So, it’s common
to say that data classes have inside the primary constructor all the property they need to store and nothing
more.

It is not possible to declare unlabeled parameter in the constructor; so, all parameters must have the var or
val because data class does not have the init method.

The compiler adds a lot of thing to the class, like the implementation of equals and the hashCode that is
conforming to what expecting to compare to piece of data exposing all the attributes contained in the
primary constructor. Everything in the primary constructor will be testing in the equals and will be part of
the solution in computing hashCode. Generate a set of function called component1, … as many as are
parameters of primary constructor used for destructing assignments. It also generates a function name
copy that allows us to create a copy of the data class.

You don’t need to say p1.toString().

1: Kotlin Pag. 19 a 27
In data classed the compiler argument the class providing the component method. Nobody prevents us to
provide function name in that way. So in a plain class you implement the component1, … you can use
destructor assignment.

Copy the property but I want to change the age into 16. It performs a SHALLOW copy (copy only the first
element of the element). P1 however is not changed if you modify p3.

Kotlin allows to create extension function; it’s a way of


declaring a function that looks like a member of a given
class, but actually is a static function with one extra
argument that is the class which is extending.

Also, Kotlin allows generic programming and allows us


to create classes of function that operate with generic
type T.

We can combine the two ideas to create a generic


extension function that is an extension function that
applies to any type T.

The generic extension function can be used for various purposes. The language has some of them called
scoping function. The idea is to cover one particular kind of situation in which we need to either derive a
different value or perform some kind of side effects.

1: Kotlin Pag. 20 a 27
Such a need can be satisfied by using a block of code that perform the necessary modification and side
effect, but by using scoping function you get a more concise and general way to deal with such kind of
situation. Scoping function comes together with a lambda that is in charge to perform the transformation.

There are situations in which you want to transform an object into something else. For example, I would
like to transform my person into its hashCode. Of course I can write p1.hashCode() and immediately I get
the hashCode. But if you want to concatenate the name of the class and the hashCode and you need to
write:

But that may not be so convenient especially if you need to repeat it a lot of time.

We are creating a generic function which can be applied to whatever and is implemented in terms of run
generic scoping function. Run applied a lambda that accepting. You can eliminate the t. also because run
function will run inside the t class.

Run inside accept a lambda that get the object in which run is applied as this ( T.() ) as parameter and the
value that return by the lambda will be return by run. Run transform something into something else
applying the lambda.

Let is similar, the difference is that the object on which let is applied is visible inside the lambda not as this
but as a default parameter that is ‘it’ if omitted.

Run and let are similar, they different the way in which operate on the left side -> (one this and other it). In
both cased return what the lambda returns.

1: Kotlin Pag. 21 a 27
Apply is similar but apply the lambda and return the object on the left -> side. No provide side effect, the
object as parameter returns like it was passed.

Self: Is the object to the left (example T ).

With() is similar to the let and takes top level lambda and propagates a parameter T to the lambda itself as
it.

Kotlin as a very restricted type of system, try to infer the type as such as possible and doesn’t allow to make
wrong assignment (assign a thing that is not a legal derivation on what is on the left-hand side). Sometimes
we need to verify if a given variable does contain one specific type.

In the example we have a view (a generic class) and we want to check whether inside there is a ImageView
class (more specific that view). If we enter inside if automatically the variable inside the if is casted to the
class we checked. This works also if we have negative checks.

Sometimes instead we want to cast an object from one type to another type. Kotlin does support a pair of
operator ‘as’ and ‘as?’. The ‘as’ operator throw an exception if the cast fails, while ‘as?’ return null.

1: Kotlin Pag. 22 a 27
When we perform the cast inside the if or else block, we
get a promotion of the type only if the compiler can
guarantee that the field is not been mutated since the
last is check. This mean always happen to local val
variable because immutable. For var local variables
smart cast will be applied if between the check and the
usage there is not modification and the compiler
controls that the variables are not capture in any
mutable lambda (lambda which has the capability to
mutate it). Instead for var properties smart cast never
happen because are by default sharable and accessible
by other threads.

The Kotlin standard library provide a set of powerful classes that makes the manipulation of standard
algorithms extremely fine and easy to do. Typically, we can extend functionality offered by
JavaListCollection with some abstraction.

We distinguish between collection that contains immutable objects and MutableCollection which allows
other elements to be added or removed.

At the root of the hierarchy, we have a general interface called iterable; general because takes a type T
which is label as out meaning that it would be returned by function contains there. Iterable means we can
inspect the content of that specific element one at the time by using an iterator.

Immediately below iterable we have collection that represent the group of elements without any particular
guarantee and collection is split into list and sets. List can contain many elements repeated and the order
has a meaning while set has no repetition and the order is not known.

From iterable derived mutable iterable which is something that can support inserting and deletion and
from this we have mutableCollection and the MutableList and MutableSet.

Note that an ArrayList a subclass of mutableList.

1: Kotlin Pag. 23 a 27
In order to simplify the creation of this kind of collection,
Kotlin offers us a group of Helper function to make easy
to manipulate lists.

Kotlin provide us a set of function in order to process the content of a collection. We need to be proficient
to use this kind of method. FlatMap is similar but may return a list a list that can be longer or shorter than
the original; don’t return elements but collection so the 1->n relation.

L1 is a list of list because chuncked returns a list.

1: Kotlin Pag. 24 a 27
Kotlin has another approach for dealing with multiple values, sequences. Sequences provide an iterable
container, so it’s still you can iterate but operate lazily. Allow potentially to deal with infinite elements. The
difference between sequences and collection is that when we operate in collection invoking filter, maps,
etc., all the elements in the source collection is process and a new collection is produced. We need to keep
all the elements inside even if we don’t need them later on.

Instead with sequences we can perform the same operation but in a lazy way that is we describe the
processing chain and until we ask for any kind of result, no actual computation takes place. When we
perform the final collection at that point the operation starts backward asking the first element which is
evaluated, and process and we don’t take the next one until we get the first result. Not intermediate
container except for some operation like reducer.

1: Kotlin Pag. 25 a 27
With listOf I need to always need a representation of the collection as a whole. With sequences what I get
is the creation of a function which has a next method which inject a new value until no more is there. When
I say filter, nothing happens a part of creating a new function which internally refers to the previous part
and exposes next. So, filter returns a new function. The same for the map. At the end nothing happens but I
build a chain of function.

When I start iterating across this; map ask to next to a first element that ask to filter that ask to the initial
sequence. Next of the sequence return 1, and filter says is acceptable and return to map that transform 1
to A1. Maps ask to another; filter doesn’t like 2 and asks another value. This until we don’t have elements.

We don’t store intermediate value but we setup a computation that is a chain of function computation.
Very useful with a lot of elements and when the filter for example is selective (a lot of elements don’t pass)
and we don’t waste memory.

We can create infinite sequence given a function.

We could not store this collection because is potentially infinite.

We have a further version of creating a sequence. We can define our sequence as a partial computation;
we defined a lambda function that return intermediate value by using the suspended lambda using the
yield. Yield returns the initial value and the coming back.

1: Kotlin Pag. 26 a 27
We can see supply lambda is executing temporarily. When I assigned letter to s nothing happens, then I
enter the sequence by interate and the sequence println this and the return Alpha without use return but
using Yield operation. This means we want to return something, but we didn’t finish (we don’t return and
return Alpha but then continue). We suspend the function and return the value, we return to the function
and we continue to do the other things.

Once done with the sequence the lambda returns the iteration return null meaning there is no more values.

Sequences: only with the second println we trigger the execution. Before we create only the function chain.

1: Kotlin Pag. 27 a 27

You might also like