- PVSM.RU - https://www.pvsm.ru -

Erlang для самых маленьких. Глава 4: Система типов

imageХороший понедельник! Мы продолжаем изучение Erlang для самых маленьких.

В прошлой главе мы разобрались с синтаксисом функций. В этой главе мы познакомимся с системой типов языка.

Динамическая сильная типизация

Если вы читали прошлые главы, то, скорее всего, обратили внимание, что мы нигде не указывали типы переменных и возвращаемых функциями значений. Так же мы не указывали тип данных при сопоставлении с образцом. Например, кортеж {A, B} может принимать значение {someAtom, 100}, {100.0, "Some string"} и т.д.

Если данные будет невозможно сопоставить с указанным образцом, будет сгенерирована ошибка. Это произойдет непосредственно в момент выполнения кода. Это происходит потому что Erlang — динамически типизированный язык. Компилятор не может отловить все ошибки на этапе компиляции. Поэтому многие ошибки генерируются во время выполнения программы.

Почему Erlang не имеет статической типизации? Немало копий было сломано в спорах о том, какая типизация лучше: статическая или динамическая. У каждой есть свои плюсы и минусы. Один из главных минусов динамической типизации — невозможность поиска ошибок, связанных с типами, на этапе компиляции. Из-за этого такие ошибки возникают в рантайме и программа «падает», что снижает общую надежность программного продукта. Но Erlang решает эту проблему другим, более эффективным способом.

Идеология Erlang: «Если оно сломалось — пусть ломается». Язык обладает инструментами, позволяющими изолировать и корректно обрабатывать все ошибки, которые могут возникнуть. Это делает программы на Erlang очень живучими. Классический пример живучести программ на Erlang, который приводят — ПО коммутаторов Ericsson AXD 301 ATM. Этот продукт имеет больше миллиона строк кода и аптайм 99.9999999%. Впечатляет.

В общем, Erlang не стремиться избегать ошибок. Он предлагает правильно их обрабатывать.

Так же Erlang относится к языкам с сильной типизацией. Это значит, что приведения типов нужно производить явно. Если мы будет использовать в одном выражении несовместимые типы данных, то получим ошибку:

1> 10 - "5".
** exception error: bad argument in an arithmetic expression
    in operator  -/2
        called as 10 - "5"

Преобразование типов

Для преобразования типов в Erlang используются функции стандартной библиотеки (находятся в модуле Erlang). Имена этих функций формируются по следующей схеме: <исходный_тип>_to_<небходимый_тип>. Вот полный перечень таких функций:

И пример их использования:

1> erlang:integer_to_list(123).
"123"
2> erlang:atom_to_list(false).
"false"
3> erlang:iolist_to_atom(123).
** exception error: bad argument
    in function  iolist_to_atom/1
        called as iolist_to_atom(123)
```

Проверка типов

Большинство типов данных в Erlang можно отличить визуально. Списки заключаются в квадратные скобки, кортежи в фигурные, а строки в двойные кавычки и т.д. Благодаря этому обеспечивается простейшая проверка типов. Например, паттерн для сопоставления [x|xs] может быть сопоставлен только со списком. В противном случае операция закончится неудачей.

Но таких элементарных проверок недостаточно. Зачастую нужно проверить, к какому типу относится та или иная переменная. Для этого в Erlang есть ряд функций, которые принимают один аргумент (иногда больше) и если его тип соответствует ожидаемому, возвращают true, иначе false. Эти функции можно использовать в охранных выражениях и проверяемый ими тип понятен из их названия.

Интересный момент: в Erlang нет функции, которая возвращала бы тип переданной переменной (на подобии type_of()). И на первый взгляд это может показаться странным, медь одна универсальная функция удобнее, чем куча узконаправленных. Ответ на этот вопрос кроется в идеологии языка: программа должна делать только то, что описано явно. Все остальное должно привести к ошибке. Более подробно данный подход будет рассматриваться в главе, посвященной обработке ошибок.

Эти типы данных можно комбинировать между собой при помощи списков и кортежей для создания более гибких и универсальных типов.

Что бы быть до конца честным, нужно упомянуть о том, что в Erlang есть возможность явно указывать типы. Этому функционалу будет выделена целая глава, поэтому тут про него рассказывать не будут.

Заключение

В этот раз получилось кратко и по делу. Тема простая, но осветить ее нужно.
Любые замечания и дополнения жду в комментариях. Об ошибках и опечатках, пожалуйста, сообщайте в личку.

Автор: HaruAtari

Источник [51]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/65493

Ссылки в тексте:

[1] Глава 1: Типы данных, переменные, списки и кортежи: http://habrahabr.ru/post/195542/

[2] github: https://github.com/HaruAtari/Erlang-for-the-little-ones/blob/master/01/README.md

[3] Глава 2: Модули и функции: http://habrahabr.ru/post/197364/

[4] github: https://github.com/HaruAtari/Erlang-for-the-little-ones/tree/master/02/README.md

[5] Глава 3: Базовый синтаксис функций: http://habrahabr.ru/post/211815/

[6] github: https://github.com/HaruAtari/Erlang-for-the-little-ones/tree/master/03/README.md

[7] atom_to_binary/2: http://www.erlang.org/doc/man/erlang.html#atom_to_binary-2

[8] atom_to_list/1: http://www.erlang.org/doc/man/erlang.html#atom_to_list-1

[9] binary_to_atom/2: http://www.erlang.org/doc/man/erlang.html#binary_to_atom-2

[10] binary_to_existing_atom2: http://www.erlang.org/doc/man/erlang.html#binary_to_existing_atom-2

[11] binary_to_list/1: http://www.erlang.org/doc/man/erlang.html#binary_to_list-1

[12] bitstring_to_list/1: http://www.erlang.org/doc/man/erlang.html#bitstring_to_list-1

[13] binary_to_term/1: http://www.erlang.org/doc/man/erlang.html#binary_to_term-1

[14] float_to_list/1: http://www.erlang.org/doc/man/erlang.html#float_to_list-1

[15] fun_to_list/1: http://www.erlang.org/doc/man/erlang.html#fun_to_list-1

[16] integer_to_list/1: http://www.erlang.org/doc/man/erlang.html#integer_to_list-1

[17] integer_to_list/2: http://www.erlang.org/doc/man/erlang.html#integer_to_list-2

[18] iolist_to_binary/1: http://www.erlang.org/doc/man/erlang.html#iolist_to_binary-1

[19] iolist_to_atom/1: http://www.erlang.org/doc/man/erlang.html#iolist_to_atom-1

[20] list_to_atom/1: http://www.erlang.org/doc/man/erlang.html#list_to_atom-1

[21] list_to_binary/1: http://www.erlang.org/doc/man/erlang.html#list_to_binary-1

[22] list_to_bitstring/1: http://www.erlang.org/doc/man/erlang.html#list_to_bitstring-1

[23] list_to_existing_atom/1: http://www.erlang.org/doc/man/erlang.html#list_to_existing_atom-1

[24] list_to_float/1: http://www.erlang.org/doc/man/erlang.html#list_to_float-1

[25] list_to_integer/2: http://www.erlang.org/doc/man/erlang.html#list_to_integer-2

[26] list_to_pid/1: http://www.erlang.org/doc/man/erlang.html#list_to_pid-1

[27] list_to_tuple/1: http://www.erlang.org/doc/man/erlang.html#list_to_tuple-1

[28] pid_to_list/1: http://www.erlang.org/doc/man/erlang.html#pid_to_list-1

[29] port_to_list/1: http://www.erlang.org/doc/man/erlang.html#port_to_list-1

[30] ref_to_list/1: http://www.erlang.org/doc/man/erlang.html#ref_to_list-1

[31] term_to_binary/1: http://www.erlang.org/doc/man/erlang.html#term_to_binary-1

[32] term_to_binary/2: http://www.erlang.org/doc/man/erlang.html#term_to_binary-2

[33] tuple_to_list/1: http://www.erlang.org/doc/man/erlang.html#tuple_to_list-1

[34] is_atom/1: http://www.erlang.org/doc/man/erlang.html#is_atom-1

[35] is_binary/1: http://www.erlang.org/doc/man/erlang.html#is_binary-1

[36] is_bitstring/1: http://www.erlang.org/doc/man/erlang.html#is_bitstring-1

[37] is_boolean/1: http://www.erlang.org/doc/man/erlang.html#is_boolean-1

[38] is_builtin/3: http://www.erlang.org/doc/man/erlang.html#is_builtin-3

[39] is_float/1: http://www.erlang.org/doc/man/erlang.html#is_float-1

[40] is_function/1: http://www.erlang.org/doc/man/erlang.html#is_function-1

[41] is_function/2: http://www.erlang.org/doc/man/erlang.html#is_function-2

[42] is_integer/1: http://www.erlang.org/doc/man/erlang.html#is_integer-1

[43] is_list/1: http://www.erlang.org/doc/man/erlang.html#is_list-1

[44] is_number/1: http://www.erlang.org/doc/man/erlang.html#is_number-1

[45] is_pid/1: http://www.erlang.org/doc/man/erlang.html#is_pid-1

[46] is_port/1: http://www.erlang.org/doc/man/erlang.html#is_port-1

[47] is_record/2: http://www.erlang.org/doc/man/erlang.html#is_record-2

[48] is_record/3: http://www.erlang.org/doc/man/erlang.html#is_record-3

[49] is_reference/1: http://www.erlang.org/doc/man/erlang.html#is_reference-1

[50] is_tuple/1: http://www.erlang.org/doc/man/erlang.html#is_tuple-1

[51] Источник: http://habrahabr.ru/post/230551/