Мы все видели целое число, число с плавающей точкой, строку и случайный десятичный тип. Какие из самых странных, уникальных или полезных типов вы встречали, полезные или нет?
Мы все видели целое число, число с плавающей точкой, строку и случайный десятичный тип. Какие из самых странных, уникальных или полезных типов вы встречали, полезные или нет?
Ответы:
Я буду коротким
Maybe a
в Хаскеле.
С помощью этой простой конструкции язык решает проблему сбоев или NullPointerException
аккуратно обходит «ошибку на миллион» Тони Хоара :)
Честно говоря, необязательное присутствие проверяется во время компиляции? Это похоже на сон ...
Option
имя. Почему нет Optional
! Это может быть потому, что я не являюсь носителем языка, но Option
не передаю «необязательное» значение для меня.
Maybe
Имя мило: «Что у вас есть?» «Может быть, Int». Однако действительно интересным является то, что он является и функтором, и монадой, что, попросту говоря, означает, что вы получаете нулевое распространение бесплатно. Вам никогда не нужно ставить нулевые проверки внутри функций или в середине кода; вам нужно только проверить это в самом конце кода, если это вообще необходимо.
Я постоянно увлекаюсь void *
. Это, вероятно, симптом чего-то глубоко испорченного во мне.
void *
и Паскаль / Delphi Pointer
.
У Lua есть встроенный стол, который впечатляет. Он имеет встроенную хеш-таблицу и вектор, и с использованием метатаблиц может стать фундаментальной основой для объектно-ориентированного программирования на процедурном языке.
Каждый индекс таблицы может получить любую из основных языковых структур (число, логическое значение, строка, функция -yes, функции являются типами на lua - и таблицы).
Я удивлен, что никто еще не упомянул Монады или Алгебраические Типы данных.
Лисп имеет два интересных типа: t
и nil
. Что интересно в них, так это то, что все есть, t
а ничего нет nil
.
nil
t
SNOBOL: шаблон (по сути, дерево синтаксического анализатора LL (1), если я правильно помню).
Фортран имеет общие блоки; это один из наименее распространенных типов данных в современных языках, или, скорее, необычный способ эффективного обмена данными.
Фортран 95 имеет интервальные типы и встроенную интервальную арифметику.
Список не был бы полным без монадических типов, найденных в Haskell. Чтобы понять их, нужно немного усилий.
Я полагаю, что это действительно странно, когда я программирую на классической архитектуре, но, безусловно, одним из самых сложных для меня способов сначала обернуть голову был квантовый регистр , который обнаруживается в QCL .
PL / SQL позволяет вам объявлять переменные типа my_table.some_column%type
... Я нахожу это чертовски полезным.
А C # позволяет вам объявлять объекты как обнуляемые или нет, хотя я не уверен, что это считается типом.
cursor%rowtype
еще смешнее: это динамически сформированный тип записи, который отражает, какие столбцы возвращает запрос курсора.
В моем сердце было слабое место для типов данных Euphoria, когда я был моложе
Он структурирован так:
Object
-> Atom
-> Sequence
Sequence = последовательность объектов
-- examples of atoms:
0
98.6
-1e6
-- examples of sequences:
{2, 3, 5, 7, 11, 13, 17, 19}
{1, 2, {3, 3, 3}, 4, {5, {6}}}
{{"jon", "smith"}, 52389, 97.25}
{} -- the 0-element sequence
Смотрите: Справочное руководство
Примечание: «jon» - это краткий способ записи последовательности значений ASCII. Например, так "ABCDEFG"
же, как{65, 66, 67, 68, 69, 70, 71}
Феликс имеет анонимные типы сумм. Тип написан так:
typedef il = int + long;
как это было бы в теории. Значения безобразны:
case 0 of il (1)
case 1 of il (2L)
за исключением, возможно, за единицу суммы, такой как 3 = 1 + 1 + 1
case 0 of 3
case 1 of 3
который, к сожалению, использует нулевой подсчет происхождения для «C совместимости». Анонимные суммы необходимы для структурно типизированных алгебраических типов, например:
(1 + T * li) as li
является списком T (с единственной связью). Все другие языки, которые мне известны, требуют номинально типизированных сумм, где как самому типу, так и конструкторам должны быть заданы имена.
Сокращение 3, используемое выше, мило, в библиотеке есть следующее:
typedef void = 0;
typedef unit = 1;
typedef bool = 2;
и это обозначение:
T ^ 3
является массивом статической длины 3 .. 3 - не целое число, а сумма 3 единиц. Какая жалость + не ассоциативно :)
q / kdb + имеет встроенные таблицы. Поскольку это язык программирования и база данных, ориентированная на столбцы в одном, нет необходимости в LINQ или ORM.
Например, можно создать таблицу, подобную этой (назначение выделяется, :
а не =
как в большинстве языков):
people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)
Теперь я могу посмотреть на свой стол:
q)show people
name age GPA
--------------
Joe 17 3.5
Amy 15 3.8
Sarah 18 3.33
И я могу запросить это:
q)select from people where GPA>3.4
name age GPA
------------
Joe 17 3.5
Amy 15 3.8
Я обнаружил, что union в C ++ был «причудливым», когда я впервые услышал о них. Я до сих пор не достиг сценария, в котором они являются очевидным выбором для реализации.
Я все еще пытаюсь обернуть голову тем, что становится многопараметрической функцией в F # и других функциональных языках. В основном, int f (Foo, Bar) становится func f (Foo)
Это двухпараметрическая функция, которая принимает Foo, а Bar и возвращает int на самом деле является функцией с одним параметром, которая принимает Foo и возвращает однопараметрическую функцию, которая принимает bar и возвращает int. Но как-то вы можете вызвать его с двумя параметрами, если хотите. Я написал пост об этом здесь
f(Foo, Bar)
- это то же самое, что и функция, f(Foo)
которая возвращает другую функцию, f'(Bar)
которая возвращает значение, которое f(Foo, Bar)
будет возвращено. То есть, если вы исправите аргумент «Foo», но не «Bar», у вас есть функция, которая не зависит от «Foo», но все еще зависит от аргумента «Bar». Это типично для функциональных языков; это называется «карри».
Это чрезвычайно мощные, но компактные объекты.
Языки, на которых они встроены, обладают большой способностью манипулировать текстом (давайте не будем слышать слово «парсинг», они не так хороши).
Горстка языков в функциональной семье имеет класс типов, известных как Unity. Отличительной особенностью типов Unity является то, что они не содержат информации, они являются типами с нулевым битом. Тип единства (в некоторых вариантах) также является его единственным значением или (в большинстве других) имеет только одно значение (которое само по себе не является типом).
Они полезны, хотя, потому что они являются выдающимися типами. Поскольку вы не можете неявно преобразовать один тип единства в другой, вы можете применить статическую проверку типов к работе очень эффективным и выразительным образом.
Unity также является способом, которым большинство таких языков описывают Enums, позволяя новому типу быть любым из определенного набора других типов или описывать, возможно, типы, значения, которые могут быть значениями типичного типа (скажем, целое число) или иметь значение, которое представляет собой нет значения.
Некоторые языки, которые не используют богатство пользовательских типов единства, все еще имеют единство в них, в той или иной форме. Например, Python имеет по крайней мере три типа единства, NoneType
, NotImplementedType
, и EllipsisType
. Интересно, что первые два означают что-то вроде «Нет значения», но третий используется в комплексных значениях (в частности, в выражениях слайсов) для представления интересных частных случаев.
Другие интересные примеры единства включают NULL
в sql и undefined
в javascript, но не void
в C или C ++. void
выходит из строя. Даже если оно описывает значение без информации, но фактическое значение не может иметь тип void
.
symbol
Тип Руби немного необычен. По сути, это строка, реализующая шаблон синглтона. Или что-то. До сих пор я обнаружил, что наилучшее использование символов для отслеживания состояний и передачи имен функций.
COBOL. По сути только два основных типа данных, строки и числа, но вы должны точно указать , как они расположены в памяти, например PIC S9(5)V99 COMP-3
.
S
= подпись, 9(5)
= 5 цифр, V
= неявная десятичная точка, 99
= еще 2 цифры, COMP-3
= BCD + знак nybble.
Клипер имел «блоки кода», которые были похожи на анонимные методы. Их можно передавать и оценивать по мере необходимости, как правило, в форме обратного вызова. Вы часто используете их для выполнения вычислений на лету при представлении таблиц данных.
VHDL имеет физические типы. Литерал такого типа включает в себя как значение, так и единицу измерения. Вы также можете определить субъединицы. Например, предопределенный физический тип time
:
type time is range <machine dependant> to <machine dependant>
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
Ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
Вместе с перегрузкой операторов вы можете определять очень интересные вещи.
Clojure интересен тем, что имеет мета-концепцию «абстракций», которые пронизывают язык. Примеры:
В некоторой степени абстракции доводят « принцип единой ответственности » до крайности. Вы должны составить их, чтобы получить желаемую функциональность, но вы можете быть чрезвычайно гибкими в том, как склеивать их вместе.
Например, если вам нужна система ООП на основе классов с наследованием, вы можете относительно быстро создать одну из этих основных абстракций.
На практике сами абстракции разрабатываются таким образом, что возможны несколько реализаций, например, через специальные интерфейсы, такие как clojure.lang.ISeq для последовательностей или clojure.lang.IFn для функций более высокого порядка.
На эту тему есть интересное видео: Искусство абстракции
Если вам нужен язык с уникальным типом, отправляйтесь в BCPL . Этот язык имеет только один тип данных, слово, являющееся фиксированным числом битов для языковой реализации.
Googles Go имеет тип «Канал», который является совершенно уникальным.