4. /29
Kotlin
Introduction
● Statically typed
● Compiles to JVM byte codes or JavaScript
● JVM version is Java compatible both ways
● Intended for industrial use
o Designed for READABILITY
o Relies simple (but powerful) abstractions
o Performance is a priority
o Tooling matters
● Open Source (Apache 2)
o http://github.com/JetBrains/Kotlin
6. /29
Kotlin
Java
type
Kotlin type
byte kotlin.Byte
short kotlin.Short
int kotlin.Int
double kotlin.Double
boolean kotlin.Boolean
Mapped types
Kotlin treats some Java types specially. Such types are
not loaded from Java “as is”, but are mapped to
corresponding Kotlin types. The mapping only matters
at compile time, the runtime representation remains
unchanged. Java’s primitive types are mapped to
corresponding Kotlin types (keeping platform types in
mind):
java.lang.Object kotlin.Any!
int[] kotlin.IntArray!
7. /29
Kotlin
Basic syntax
● You do not need ; to break statements.
● Comments are similar to Java or C#, /* This is comment */ for multi line comments and // for single line
comment.
● Unlike Java, you do not need to match your file name to your class name.
● Like JavaScript, you can create functions outside classes. So there is no need to stuff your functions as static
members of classes like what you do in C# or Java.
● Kotlin has string templates, which is awesome. e.g. "$firstName $lastName" for simple variable name or
"${person.name} is ${1 * 2}" for any expressions. You can still do the string concatenation if you like e.g.
"hello " + "world", but that means being stupid.
● It has no tuple although Kotlin's data classes is an option to use in place of tuple.
● Use function literals to filter and map collections: basic functional programming inside
8. /29
Kotlin
Variable semantic
● There are two keywords for variable declaration, var and val.
● Use var when the variable value is to be modified and val where the variable value will not change after first
assigned.
● This val is similar to readonly keyword in C# or final keyword in Java.
● val variable must be initialized at declaration.
● Unlike Java or C#, you declare the type of a variable after the name, e.g. var firstName : String
● Number primitive types are as follows: Double, Float, Long, Int, Short, Byte. There is no automatic conversion
between types. You have to explicitly convert them.
● More primitive types: Char, String, Boolean.
● All variable declarations in Kotlin must be initialized.
9. /29
Kotlin
Identifiers
4 types of identifiers supported by Scala:
● ALPHANUMERIC IDENTIFIERS
● OPERATOR IDENTIFIERS
● LITERAL IDENTIFIERS
10. /29
Kotlin
ALPHANUMERIC IDENTIFIERS
● An ALPHANUMERIC IDENTIFIERS starts with a letter or underscore,
which can be followed by further letters, digits, or underscores.
● '$' character is a reserved keyword
Legal alphanumeric identifiers:
age, salary, _value, __1_value
Illegal identifiers:
$salary, 123abc, -salary
12. /29
Kotlin
Semantic
- arrays the index used in an array selection expression must be of
integer type
- expressions the two operands to logical && must both be bool type, the result
is bool type
- functions the type of each actual argument in a function call must be
compatible with the formal parameter
- classes if specified, the parent of a class must be a properly declared class
type
- interfaces all methods of the interface must be implemented if a class states
that it implements the interface
13. /29
Kotlin
Semantic (easy stuff)
Class names can be used before being defined
• We can’t check class names
– using a symbol table
– or even in one pass
• Solution
– Pass 1: Gather all class names
– Pass 2: Do the checking
15. /29
Kotlin
Example AST rules
● Before processing e, add definition of x to current
definitions, overriding any other definition of x
● – Recurse
● – After processing e, remove definition of x and restore
old definition of x
for (x : Char in “abc”){ ( x )
Expressions…. ( e )
}
16. /29
Kotlin
Symbol table operations
● addSymbol(x) push x and associated info, such as
x’s type, on the stack
● findSymbol(x) search stack, starting from top, for
x. Return first x found or NULL if none found
● removeSymbol() pop the stack
● enterScope() start a new nested scope
● findSymbol(x) finds current x (or null)
● addSymbol(x) add a symbol x to the table
● checkScope(x) true if x defined in current scope
● exitScope() exit current scope
17. /29
Kotlin
Recall to symbol tables for resolving
fun main(args: Array<String>) {
if (args.size == 0) {
println("Provide a name")
return
}
println("Hello, ${args[0]}!")
//String Interpolation to cut down ceremony.
}
18. /29
Kotlin
Method declaration
● Method names have complex rules
● A method need not to be defined in the class in which it
is used, but in some parent class
● Methods may also be redefined (overridden) (Hard point)
19. /29
Kotlin
Type checking
Type checking computes via reasoning:
If E1 and E2 have certain types, then E3 has a certain type
(e1 : Int AND e2: Int) IMPLIES e1 + e2: Int
We work with hypotheses and conclusions.
So we create type rules.
Ex: is add minus
20. /29
Kotlin
Type checking
Type checking proves facts e: T
– Proof is on the structure of the AST
– Proof has the shape of the AST
– One type rule is used for each AST node
• In the type rule used for a node e:
– Hypotheses are the proofs of types of e’s subexpressions
– Conclusion is the type of e
• Types are computed in a bottom-up pass over the AST
21. /29
Kotlin
Type environment before type check
The type environment gives types to the free
identifiers in the current scope
• The type environment is passed down the AST from
the root towards the leaves
• Types are computed up the AST from the leaves
towards the root
22. /29
Kotlin
Subtyping
Consider:
if e0 then e1 else e2
• The result can be either e1 or e2
• The type is either e1’s type or of e2’s type
• The best we can do is the smallest supertype larger than the type of e1 or e2
23. /29
Kotlin
Subtyping
lub(X,Y), the Least Upper Bound of X and Y, is Z if
– X ⩽ Z AND Y ⩽ Z
Z is an upper bound
– X ⩽ Z’ AND Y ⩽ Z’ IMPLIES Z ⩽ Z’
Z is least among upper bounds
so the least upper bound of two types is their
least common ancestor in the inheritance tree
25. /29
Kotlin
Typing methods
prelude: A method foo and an object foo can coexist in the
same scope
• In the type rules, this is reflected by a separate mapping
M for method signatures
M(C,f) = (T1,. . .Tn,Tn+1)
means in class C there is a method f
f(x1:T1,. . .,xn:Tn): Tn+1 the last one is type of return st
26. /29
Kotlin
Polymorphism (Self type)
class Count {
val i = 0;
fun inc() : Count {
i++
return this
}
};
inc() should return “dynamic type”
class Stock extends Count(var name:String)
{
};
fun main(args: Array<>String){
val a = Stock(“test”)
a = (new Stock).inc (); // fail
… a.name …
};
27. /29
Kotlin
Polymorphism (Self type)
– So, we must redefine inc for each of the subclasses, with a specialized return
type
● Introduce the keyword SELF_TYPE to use for the return value of such
functions
SELF_TYPE is not a dynamic type
– It is a static type
– It helps the type checker to keep better track of types
– It enables the type checker to accept more correct
programs
28. /29
Kotlin
Semantic
Else one Hard aspect:
1) Lamda expressions as new feature of the language:
val positiveNumbers = list.filter {it > 0}
Правила редукции типовых и без типовых лямбда исчислений
Область видимо-сти. Операционная семантика, виды редукций.
Представление термов без использования имён (индексы де Брауна)
Безопасность, продвижение, сохранение.
Простое типизированное лямбда-исчисление: Типы функций.
Отношение типизации. Свойства типизации. Соответствие Карри–Говарда(введения
устранения, при совпадении вычисление).
Стирание типов и типизируемость
Big amount of java programmer. Because it’s well suitable and maintained so JAva platform is very nice ecosystem.
Java platform and Java language there is huge gap.
So for the java programers 10 лет, за монитором наблюдали за языком.
Монитор развивался а язык нет.
Kotlin —
современный статически типизированный объектно-ориентированный язык программирования, компилируемый в байт-код Java и в JavaScript.
Kotlin полностью совместим с Java и предоставляет дополнительные возможности, упрощающие повседневную работу программиста и повышающие продуктивность. Kotlin сочетает в себе лаконичность, выразительность, производительность и простоту в изучении.
Designing a Type Checker
When designing a type checker for a compiler, here’s the process:
1. identify the types that are available in the language
2. identify the language constructs that have types associated with them
3. identify the semantic rules for the language
String fake class String.last(): Char this[]
Checks of many kinds . . . coolc checks:
1. All identifiers are declared
2. Types
3. Inheritance relationships
4. Classes defined only once
5. Methods in a class defined only once
6. Reserved identifiers are not misused
And others . . .
• The requirements depend on the language
val people = hashMapOf<String, Int>()for ((person, age) in people) { println("${person} in ${age} years old")}
Скормить байткоду java создание массива и присваиванию ему метода, к примеру, set то все пройдет нормально.
Но после запуска там не будет никакой ошибки он просто там сдохнет незаметно и все