Slide 1

Slide 1 text

Уроки Kotlin или зачем создавать еще один язык программирования? Роман Елизаров SnowOne, Февраль 2025

Slide 2

Slide 2 text

Обо мне • В индустрии программирования с 2000 года • Разрабатывал всякое высоконагруженное ПО @ Devexperts • Преподаю параллельное программирование @ Санкт-Петербургский ИТМО • Председатель жюри @ Northern Eurasia Contest / ICPC • Руководил дизайном и командой языка Kotlin @ JetBrains • Улучшаю опыт разработчиков @ Yandex (БГ Екома и Райдтеха)

Slide 3

Slide 3 text

ЯЗЫКИ

Slide 4

Slide 4 text

Какие языки сейчас популярны? • PYPL (частота поиска по “xxx tutorial”) 1. Python 2. Java 3. JavaScript 4. C/C++ 5. C# … • RedMonk (GitHub + SO) 1. JavaScript 2. Python 3. Java 4. PHP 5. C# … CSS

Slide 5

Slide 5 text

Популярные языки программирования Pascal 1970 1972 1984 1985 1987 1990 1991 1990 1993 1995 1995 1995 1995

Slide 6

Slide 6 text

21-ый век* 2000 2001 2003 2005 2004 2009 2010 2011 2011 2012 2014

Slide 7

Slide 7 text

Pascal < До 2000 года После 2000 года >

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Разные языки решают разные задачи?

Slide 10

Slide 10 text

Разные языки решают разные задачи? созданы для разного!

Slide 11

Slide 11 text

Пирамида забот программиста Задача

Slide 12

Slide 12 text

Пирамида забот программиста Задача Модель

Slide 13

Slide 13 text

Пирамида забот программиста Задача Модель Алгоритм

Slide 14

Slide 14 text

Пирамида забот программиста Задача Модель Алгоритм Представление

Slide 15

Slide 15 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память

Slide 16

Slide 16 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память Инструкции

Slide 17

Slide 17 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память Инструкции Языки низкого уровня

Slide 18

Slide 18 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память Инструкции Системные языки

Slide 19

Slide 19 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память Инструкции Прикладные языки

Slide 20

Slide 20 text

Пирамида забот программиста Задача Модель Алгоритм Представление Память Инструкции Языки низкого уровня Системные языки Прикладные языки

Slide 21

Slide 21 text

Управление памятью int *a = calloc(n * sizeof(int)); free(a); vector a(n); auto a = make_unique>(n); auto a = make_shared>(n); a = [0] * n val a = IntArray(10)

Slide 22

Slide 22 text

Управление памятью Pascal Ручное Автомат

Slide 23

Slide 23 text

Управление памятью Pascal Ручное Автомат

Slide 24

Slide 24 text

Что программист делает бо́льшую часть времени?

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

“программы должны писаться для того, чтобы их читали люди, и лишь во вторую очередь для выполнения машиной” - Харольд Абельсон, Структура и интерпретация компьютерных программ

Slide 27

Slide 27 text

function updateOrder() function updateOrder(order, address) function updateOrder(order: PlainOrder, address: MailAddress): PlainOrder function updateOrder($1, $2) function updateOrder(order: PlainOrder, address: MailAddress?): PlainOrder Типизация!

Slide 28

Slide 28 text

Типизация Динамическая Статическая Pascal

Slide 29

Slide 29 text

Типизация Динамическая Статическая Pascal

Slide 30

Slide 30 text

Масштабирование разработки

Slide 31

Slide 31 text

Насколько подробные типы нужны?

Slide 32

Slide 32 text

Слишком мало типизации Map items = new HashMap();

Slide 33

Slide 33 text

Слишком много типизации? Map> items = new HashMap>(); items = {}

Slide 34

Slide 34 text

Вывод типов! var items = new HashMap>();

Slide 35

Slide 35 text

Вывод типов! auto items = …

Slide 36

Slide 36 text

Вывод типов! __auto_type items = …

Slide 37

Slide 37 text

Было раньше int count = ... double average = ... List strings = ... Map> items = ...

Slide 38

Slide 38 text

Стало с выводом var count = ... var average = ... var strings = ... var items = ...

Slide 39

Slide 39 text

Стало с выводом var count = ... var average = ... var strings = ... Map> items = ...

Slide 40

Slide 40 text

Типы справа! var count = ... var average = ... var strings = ... var items: Map> = ...

Slide 41

Slide 41 text

Где тип? Слева Справа Pascal

Slide 42

Slide 42 text

Где тип? Слева Справа Pascal

Slide 43

Slide 43 text

А давайте почитаем сам код

Slide 44

Slide 44 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 45

Slide 45 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 46

Slide 46 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 47

Slide 47 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 48

Slide 48 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 49

Slide 49 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 50

Slide 50 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 51

Slide 51 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; }

Slide 52

Slide 52 text

Почитаем код… Map totalWeight(List orders) { var result = new HashMap(); for (var order : orders) { for (var item : order.getItems()) { var sum = result.get(item.getWarehouse()); if (sum == null) { sum = 0.0; } result.put(item.getWarehouse(), sum + item.getWeight()); } } return result; } Императивный стиль

Slide 53

Slide 53 text

Лучше Map totalWeight(List orders) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect( groupingBy(OrderItem::getWarehouse, summingDouble(OrderItem::getWeight))); }

Slide 54

Slide 54 text

Лучше Map totalWeight(List orders) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect( groupingBy(OrderItem::getWarehouse, summingDouble(OrderItem::getWeight))); }

Slide 55

Slide 55 text

Лучше Map totalWeight(List orders) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect( groupingBy(OrderItem::getWarehouse, summingDouble(OrderItem::getWeight))); }

Slide 56

Slide 56 text

Лучше Map totalWeight(List orders) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect( groupingBy(OrderItem::getWarehouse, summingDouble(OrderItem::getWeight))); }

Slide 57

Slide 57 text

Лучше Map totalWeight(List orders) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect( groupingBy(OrderItem::getWarehouse, summingDouble(OrderItem::getWeight))); }

Slide 58

Slide 58 text

Лучше fun totalWeight(orders: List): Map = orders .flatMap { it.items } .groupingBy { it.warehouse } .fold(0.0) { acc, item -> acc + item.weight } Функциональный стиль

Slide 59

Slide 59 text

Make val not var Функциональный стиль? Значения Переменные

Slide 60

Slide 60 text

Переменные или значения по умолчанию Меняем Неизменно Pascal

Slide 61

Slide 61 text

Переменные или значения по умолчанию Меняем Неизменно Pascal

Slide 62

Slide 62 text

Null reference “I call it my billion-dollar mistake. It was the inven2on of the null reference in 1965. At that 2me, I was designing the first comprehensive type system for references in an object oriented language ALGOL W. My goal was to ensure that all use of references should be absolutely safe, with checking performed automa2cally by the compiler. But I couldn't resist the tempta2on to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabili2es, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.” Sir Tony Hoare

Slide 63

Slide 63 text

Зло null имеет много имен NULL nullptr nil Pascal None null nil

Slide 64

Slide 64 text

Null-safety Unsafe Safe Pascal

Slide 65

Slide 65 text

Null-safety Unsafe Safe Pascal

Slide 66

Slide 66 text

Эволюция к более лучшим языкам • Больше null-safety • Больше функционального подхода • Больше неизменяемых значений • Больше строгой типизации • Больше автоматического управления памятью

Slide 67

Slide 67 text

Эволюция к более лучшим языкам • Больше null-safety • Больше функционального подхода • Больше неизменяемых значений • Больше строгой типизации • Больше автоматического управления памятью СТОП

Slide 68

Slide 68 text

Нельзя удобно запихать всё в один язык! Задача Модель Алгоритм Представление Память Инструкции Языки низкого уровня Системные языки Прикладные языки

Slide 69

Slide 69 text

Но ведь в 2025 году уже мы знаем как делать языки лучше и они у нас есть! Ведь правда?

Slide 70

Slide 70 text

Основные бэкенд языки БГ Екома и Райдтеха в Яндекс

Slide 71

Slide 71 text

Нельзя так просто взять и переписать весь legacy код

Slide 72

Slide 72 text

Миграция на более современные языки ?

Slide 73

Slide 73 text

Миграция на более современные языки ? Carbon

Slide 74

Slide 74 text

Языки-наследники это компромисс! • ЗА • Получаем доступ к готовой экосистеме • ПРОТИВ • Наследуем много исторических проблем

Slide 75

Slide 75 text

Примеры из Котлина: массивы fun main(args: Array) { println(args[0]) } 😀

Slide 76

Slide 76 text

Примеры из Котлина: массивы fun main(args: Array) { args[0] = "Mutable!" println(args[0]) } 😞

Slide 77

Slide 77 text

Примеры из Котлина: строки fun main() { val s = "😭" println(s.encodeToByteArray().size) !// 4 println(s.length) !// 2 } 😭

Slide 78

Slide 78 text

Примеры из Котлина: инициализация и наследование abstract class Parent { abstract val kind: String init { println("Initializing $kind") } } class Child : Parent() { override val kind = "Child" } 😱

Slide 79

Slide 79 text

Сделать новый язык с чистого листа без исторического наследия Унаследовать Java экосистему со всеми её библиотеками, инструментами и … недочетами

Slide 80

Slide 80 text

Эволюция к более лучшим языкам • Больше null-safety • Больше функционального подхода • Больше неизменяемых значений • Больше строгой типизации? • Больше автоматического управления памятью

Slide 81

Slide 81 text

Где предел сложности типов? a: Vec>>>

Slide 82

Slide 82 text

AI

Slide 83

Slide 83 text

Эволюция языков программирования Модернизация Замещение Изобретение

Slide 84

Slide 84 text

Спасибо. Вопросы?