Типизация в языках программирования.pptx
- Количество слайдов: 48
Типизация в языках программирования Открытый лекторий летней школы «Слон» Александр Шер Илья Воронцов
Данные l l Всё программирование – про работу с данными: их сбор, преобразование, хранение, анализ Данные в компьютере – это всего лишь набор каких-то байтов
Двоичное представление l l Что такое 0 b 11000110?
Двоичное представление l l l Число 198 Что такое 0 b 11000110?
Двоичное представление l Что такое 0 b 11000110? l l Число 198 ASCII-символ с кодом 198
Двоичное представление l Что такое 0 b 11000110? l l Число 198 ASCII-символ с кодом 198 Число. . . -58
Двоичное представление l Что такое 0 b 11000110? l l l Число 198 ASCII-символ с кодом 198 Число. . . -58 Настройки программы, закодированные битовой маской
Двоичное представление l Что такое 0 b 11000110? l l l Число 198 ASCII-символ с кодом 198 Число. . . -58 Настройки программы, закодированные битовой маской Указатель на ячейку памяти на древнем компьютере с однобайтовой адресацией
Двоичное представление l Данные = байт + “кодировка” (метод интерпретации) l l Тип данных предоставляет метод интерпретации байтов: l l int x = 65; char c = 'A'; (ASCII-код 65)
Двоичное представление l Процессор практически ничего не знает про типы данных, его команды оперируют с “голыми” байтами. l l Например, команда сложения прибавляет к байтам одной ячейки байты из другой ячейки, не заботясь о смысле операции.
Двоичное представление l Процессор практически ничего не знает про типы данных, его команды оперируют с “голыми” байтами. l l Например, команда сложения прибавляет к байтам одной ячейки байты из другой ячейки, не заботясь о смысле операции. l l l char x = 'A'; // код 65 char y = '2'; // код 50 char z = x + y; // код 115 – символ 's'
Двоичное представление l Процессор практически ничего не знает про типы данных, его команды оперируют с “голыми” байтами. l l l Так как целые числа и вещественные представлены в разной “кодировке”, сложение целых чисел и сложение вещественных чисел – РАЗНЫЕ команды. Т. е. можно сложить два набора байтов и получить результаты разные даже по двоичному представлению
Бестиповые языки l l l Машинный код – бестиповый Assembler – бестиповый Brainfuck – бестиповый l +++++[>++++++++++>+<<<< ]>++. >+. +++++++. >++. <<++++++++. >. +++. --------. >+. >.
Всюду обман l В Assembler есть зачатки типизации: l l Нельзя производить операции над ячейками разного размера Add ax, cx – сложение двухбайтовых чисел Add eax, ecx – сложение четырехбайтовых чисел Add eax, ax – не скомпилируется
Типизация. Защита от дурака l l l char z = 'A' + '2'; // код 115 – символ 's' 3. 14 << 2 // битовый сдвиг вещественного числа int arr[10]; cout << arr + 1; // Печать указателя l l Хорошая система типов призвана защитить нас от подобных глупостей
Типизация Откуда программа знает про типы? l
Типизация Откуда программа знает про типы? l Программист явно указывает типы переменных (явная типизация) l l l Pascal, C++, Java, …
Типизация Откуда программа знает про типы? l Программист явно указывает типы переменных (явная типизация) l l Pascal, C++, Java, … Программа сама понимает типы переменных (неявная типизация) l l l Python, Javascript, Clojure, . . .
Явная типизация l l l int x = 4 int y = 2; int z = x + y String s = “Hello”; double sqrt(double x) { … }
Неявная типизация l l l x=4 y=2 z = x+y s = “Hello” def sqrt(x): #. . .
Литералы l l l Как язык с неявной типизацией догадывается про типы переменных?
Литералы l Как язык с неявной типизацией догадывается про типы переменных? l l l S = “Hello” # справа строка, значит и слева строка a = 4; b = 2; # справа число –> слева число c = a + b # число + число –> число print (S + “ world”) # строка + строка –> строка
Литералы l l Литерал – константа в коде (в современных языках определение несколько устарело)
Литералы l Литерал – константа в коде (в современных языках определение несколько устарело) l l Литерал – специальная конструкция языка, которая представляет объект определенного типа и конкретного значения
Классические литералы l Числа: l l l Символы: l l 'x' (не во всех языках такой тип вообще есть) Строки l l 1 1. 0 INF 0 x. FA “Hello worldn” Булевы значения l True/false
Литералы, распространенные в современных языках l Массивы l l Словари l l {name: 'Вася', surname: 'Иванов'} Комплексные числа l l [1, 2, 'Hello'] 1 + 3 i None / null / nil / undefined
Более редкие литералы l Регулярные выражения (Regexp) l l Символы-перечисления (enum, Symbol) l l : white, : red, : black Кортежи l l /^. +@. +. (com|ru|org)$/ (3. 14159, 2. 71828) Анонимные функции l l lambda x: x*x ->(x) { x * x }
Совсем редкие литералы l Числа произвольной длины и точности l l l 1. 0000000015 M 123456789123456789 M Рациональные числа l 2/3
Модификаторы литералов l У многих литералов бывают модификаторы, меняющие способ трактовки: l l r'abcndef' – не учитывать спецсимволы (Python) u'abcndef' – Unicode-строка (Python) 123 ul – unsigned long (C++) /cat/i – не учитывать регистр букв (много где)
Литералы в разных языках Почему не внести во все языки все возможные литералы?
Литералы в разных языках Почему не внести во все языки все возможные литералы? l l Литералы иногда используют синтаксис, который пересекается с синтакисом других языков. И как тогда парсить код? Пример: /cat|dog// – Регулярное выражение с заменой или комментарий? Пример: 1/3 это вычисление или рациональное число?
Литералы в разных языках Гибкость синтаксиса языка не безгранична. К примеру, в большинстве языков невозможно сделать литерал 1/3, т. к. есть оператор деления. Однако, в Lisp нет привычных нам инфиксных операторов, все пишется в польской нотации: (+ 1 4) –> 5; 1 + 4 –> ошибка А раз так, то 1 / 3 не является вычислением и его можно использовать (+ 1/3 1/2) –> 5/6
Системы типов Главный компромисс: l Гибкость и выразительность языка l vs l безопасность языка
Виды типизации l Явная типизация (Java, C++) l l int x = 4; double sqrt(double x) {. . . } l l Неявная типизация (Python, Javascript, C++) l l l x=4 auto x = 4 def sqrt(x): . . .
Виды типизации l Статическая (C++, Java, Pascal) l l l Типы всех переменных известны в момент компиляции double add(double x, double y) { return x + y; } add(1. 5, 2. 5); // 4 add(“Hello”, “ world”); // ошибка компиляции: нет такой функции
Виды типизации l Динамическая (Python, Clojure, Javascript) l Типы переменных известны только в момент исполнения aka Runtime l l l def add(x, y): return x + y add(1. 5, 2. 5); // 4 add(“Hello”, “ world”); // “Hello world” add(“Hello”, 5); // Ошибка времени исполнения
Виды типизации l Динамическая (Python, Clojure, Javascript) l Типы переменных известны только в момент исполнения aka Runtime l l def add(x, y): return x + y add(1. 5, 2. 5); // 4 add(“Hello”, “ world”); // “Hello world” add(“Hello”, 5); l Ошибка времени исполнения!!! l l
Виды типизации l Сильная l l l l 1 == 1 –> true 1 == 1. 0 –> false 1 == '1' –> false '2' + '3' –> '23' '2' + 3 –> Ошибка if (0) –> Ошибка
Виды типизации l Слабая l l l l 1 == 1 –> true 1 == 1. 0 –> true 1 == '1' –> true '2' + '3' –> '23', но в некоторых языках вообще 5 '2' + 3 –> 5 if (0) –> обычно то же что if (false)
Слабая и сильная типизация l Слабая l приводит типы l l Сильная l не приводит типы
Слабая и сильная типизация l Слабая l l приводит типы понимает вас с полуслова l l l Сильная l не приводит типы l заставляет совершать дополнительные действия
Слабая и сильная типизация l Слабая приводит типы l понимает вас с полуслова l ведет себя непредсказуемо Сильная l не приводит типы l заставляет совершать дополнительные действия l надежна l l
Проблемы приведения типов l l l Что из этого безопасно? long x = 400; // 400 имеет тип int (int < long) byte x = 400; // 400 имеет тип int (int > byte)
Проблемы приведения типов l l l Что из этого безопасно? long x = 400; // 400 имеет тип int (int < long) byte x = 400; // 400 имеет тип int (int > byte) l l double x = 400; x == 399
Проблемы приведения типов l l l Что из этого безопасно? long x = 400; // 400 имеет тип int (int < long) byte x = 400; // 400 имеет тип int (int > byte) l l l double x = 400; x == 399 l l 16777217 == 16777216. 0 (для float)
Проблемы отсутствия приведения типов l l l 2 + 1. 5 – какого типа? 2/3 2 / 3. 0
Самая лучшая система типов?
Самая лучшая система типов? l Её нет!