Интересные или уникальные типы в языках программирования? [закрыто]

20

Мы все видели целое число, число с плавающей точкой, строку и случайный десятичный тип. Какие из самых странных, уникальных или полезных типов вы встречали, полезные или нет?

user10008
источник
Привет, user10008, добро пожаловать в Programmers.SE! Вы проверили наш FAQ ? Какое из шести субъективных указаний , по вашему мнению, соответствует вашему вопросу?
4
Кто-нибудь хотел бы написать запись для Лисп?
Марк С
Я думал, что это может быть обманом, но только потому, что мой ответ был бы обманом, поэтому я опубликую ссылку, и, возможно, вы найдете несколько хороших ответов: programmers.stackexchange.com/questions/724/…
Питер Turner
@Mark: я пытался, но типы, вероятно, одна из наименее интересных вещей в Лиспе.
Ларри Коулман
@LarryC Я думал, что это идеальный вопрос для Lisp из-за повсеместного использования списков ! Списки формируют синтаксическое дерево, и это позволяет вам писать функции, которые делают удивительные вещи в вашем коде, я так понимаю. Я изучаю Racket (ранее PLT Scheme ) сейчас. Лисп - единственный язык программирования, которым я по-настоящему заинтересован и заинтересован в изучении.
Марк С

Ответы:

18

Я буду коротким

Maybe a

в Хаскеле.

С помощью этой простой конструкции язык решает проблему сбоев или NullPointerExceptionаккуратно обходит «ошибку на миллион» Тони Хоара :)

Честно говоря, необязательное присутствие проверяется во время компиляции? Это похоже на сон ...

Matthieu M.
источник
1
Или Option, как его называют во многих других языках программирования.
Джонас
@Jonas: Должен признать, мне не нравится это Optionимя. Почему нет Optional! Это может быть потому, что я не являюсь носителем языка, но Optionне передаю «необязательное» значение для меня.
Матье М.
MaybeИмя мило: «Что у вас есть?» «Может быть, Int». Однако действительно интересным является то, что он является и функтором, и монадой, что, попросту говоря, означает, что вы получаете нулевое распространение бесплатно. Вам никогда не нужно ставить нулевые проверки внутри функций или в середине кода; вам нужно только проверить это в самом конце кода, если это вообще необходимо.
Тихон Джелвис
Существует рубинаMaybe для Ruby: lostechies.com/derickbailey/2010/10/10/the-maybe-monad-in-ruby
Джейсон Льюис,
15

Я постоянно увлекаюсь void *. Это, вероятно, симптом чего-то глубоко испорченного во мне.

Пол Натан
источник
2
Да. Боюсь, это именно то, что есть. :) О, +1 за "интересный", а не "уникальный". Objective-C, очевидно, имеет void *и Паскаль / Delphi Pointer.
Фрэнк Шиарар
хаха скорее не тип, но вы не можете утверждать, что он не мощный
user10008
15
Мне просто нравится врожденный пессимизм, который он выражает: «Ты видишь эту вещь там?» «Да, что это?», «Понятия не имею».
biziclop
Я всегда думал, что это смешно, что вы не можете объявить недействительным, но вы можете взять адрес этого. Сдается мне, что с struct s {int A; пустота B; int C; } что адрес B должен быть адресом трещины между A и C. Но нет, не допускается.
Энди Кэнфилд
Вот почему в паскале «указатель» используется для обозначения общего указателя, а не путать с «процедурой».
umlcat
14

У Lua есть встроенный стол, который впечатляет. Он имеет встроенную хеш-таблицу и вектор, и с использованием метатаблиц может стать фундаментальной основой для объектно-ориентированного программирования на процедурном языке.

Каждый индекс таблицы может получить любую из основных языковых структур (число, логическое значение, строка, функция -yes, функции являются типами на lua - и таблицы).

Мачадо
источник
Обратите внимание, что Javascript построен очень похожим образом, а Python построен на той же основе, что и, вероятно, Ruby.
9000
Я думаю, что это также возможно в Perl и PHP, да?
FrustratedWithFormsDesigner
Существует разница между таблицами в lua и хэш-контейнерами на других языках. Существует небольшая разница в реализации способа, которым lua распределяет хеш-значения, что заставляет его таблицы работать почти волшебным образом. Я в основном программирую на python и иногда обнаруживаю, что использую предположения, которые не соответствуют действительности, исходя из моих ожиданий того, как таблицы работают в lua. Конкретным примером этой магии является то, что целые числа хэшируют себе + 1. Это означает, что целочисленные ключи упакованы плотно, и что +0.0 и -0.0 имеют одинаковый хэш (они равны)
SingleNegationElimination
9

Я удивлен, что никто еще не упомянул Монады или Алгебраические Типы данных.

Джейсон Бейкер
источник
Может быть, показать нам примеры :)
Nawfal
8

Лисп имеет два интересных типа: tи nil. Что интересно в них, так это то, что все есть, tа ничего нет nil.

Ларри Коулман
источник
Ты серьезно? Я не знал этого.
Марк С
Есть ? nilt
Джон Харроп
6

SNOBOL: шаблон (по сути, дерево синтаксического анализатора LL (1), если я правильно помню).

Дэвид Торнли
источник
6

Фортран имеет общие блоки; это один из наименее распространенных типов данных в современных языках, или, скорее, необычный способ эффективного обмена данными.

Фортран 95 имеет интервальные типы и встроенную интервальную арифметику.

Список не был бы полным без монадических типов, найденных в Haskell. Чтобы понять их, нужно немного усилий.

9000
источник
Ах, базы данных UniData / UniVerse также имеют общие блоки на своем внутреннем языке (UniBasic).
Дэн МакГрат
Является ли общий блок блоком кода, который используется различными частями программы?
Марк С
1
@MarkC IIRC - это в основном глобальные данные, но каждая функция, к которой осуществляется доступ, должна прямо указывать, что она идет вверху
jk.
5

В Delphi есть наборы ( см. Также ), которые, я не думаю, реализованы таким же образом в других языках.

Это облегчает хранение многопеременных атрибутов в базах данных: D

Питер Тернер
источник
4

Я полагаю, что это действительно странно, когда я программирую на классической архитектуре, но, безусловно, одним из самых сложных для меня способов сначала обернуть голову был квантовый регистр , который обнаруживается в QCL .

Cercerilla
источник
3

PL / SQL позволяет вам объявлять переменные типа my_table.some_column%type... Я нахожу это чертовски полезным.

А C # позволяет вам объявлять объекты как обнуляемые или нет, хотя я не уверен, что это считается типом.

FrustratedWithFormsDesigner
источник
4
Но cursor%rowtypeеще смешнее: это динамически сформированный тип записи, который отражает, какие столбцы возвращает запрос курсора.
9000
.NET «Nullable» на самом деле (универсальный) тип сам по себе.
Конамиман
3

В моем сердце было слабое место для типов данных Euphoria, когда я был моложе

Он структурирован так:

Object
-> Atom
-> Sequence
  • Atom = одно числовое значение
  • 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}

Дэн МакГрат
источник
7
Это похоже на LISP ...
FrustratedWithFormsDesigner
Фактические типы данных являются единственным битом.
Дэн МакГрат
1
@FrustratedWithForms То же самое, я подумал: «Эй, он сказал:« Атом »! Это похоже на (а) Лисп, но с ненужными разделителями.: P
Марк C
3

Феликс имеет анонимные типы сумм. Тип написан так:

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 единиц. Какая жалость + не ассоциативно :)

Yttrill
источник
2

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
chrisaycock
источник
2

Я обнаружил, что union в C ++ был «причудливым», когда я впервые услышал о них. Я до сих пор не достиг сценария, в котором они являются очевидным выбором для реализации.

mummey
источник
3
Союзы пришли из C. Один хороший пример - структура zval в php.
Мартин Уикман,
2
Я использовал их в эмуляторе Z80, чтобы легко получить доступ к 16-битным регистрам как к целым регистрам (HL, BC), так и к 8-битным регистрам (H, L, B и C). Это отражает то, как они используются в Z80 ASM. Также в «вариантах» - классе, который может содержать значения разных типов (например, int / float) - не уверен, почему я не использовал подклассы, но это имело смысл в то время :)
ggambett
@ggambett: я сделал то же самое для моих программ Z80! Только то, что я также добавил битовое поле для доступа к отдельным флагам в F-регистре.
Конамиман
2

Я все еще пытаюсь обернуть голову тем, что становится многопараметрической функцией в F # и других функциональных языках. В основном, int f (Foo, Bar) становится func f (Foo)

Это двухпараметрическая функция, которая принимает Foo, а Bar и возвращает int на самом деле является функцией с одним параметром, которая принимает Foo и возвращает однопараметрическую функцию, которая принимает bar и возвращает int. Но как-то вы можете вызвать его с двумя параметрами, если хотите. Я написал пост об этом здесь

Майкл Браун
источник
8
Скорее, функция f(Foo, Bar)- это то же самое, что и функция, f(Foo)которая возвращает другую функцию, f'(Bar)которая возвращает значение, которое f(Foo, Bar)будет возвращено. То есть, если вы исправите аргумент «Foo», но не «Bar», у вас есть функция, которая не зависит от «Foo», но все еще зависит от аргумента «Bar». Это типично для функциональных языков; это называется «карри».
9000
2

Регулярные выражения:

Это чрезвычайно мощные, но компактные объекты.
Языки, на которых они встроены, обладают большой способностью манипулировать текстом (давайте не будем слышать слово «парсинг», они не так хороши).

Мартин Йорк
источник
2
Вполне возможно разобрать многие простые грамматики с регулярными выражениями. Например, довольно просто анализировать INI-файл с минимумом логики поверх набора регулярных выражений. Ошибка, которую делают многие люди, заключается в попытке проанализировать с ней очень сложные грамматики (например, XML / HTML).
Мэтью Шарли
@Mark C: вершина - это ответ (с рекордным результатом 4320 голосов). Вы не можете
Мартин Йорк
Да, это было для юмора. Это пришло мне в голову, когда я прочитал комментарий Мэтью.
Марк С
2

Горстка языков в функциональной семье имеет класс типов, известных как Unity. Отличительной особенностью типов Unity является то, что они не содержат информации, они являются типами с нулевым битом. Тип единства (в некоторых вариантах) также является его единственным значением или (в большинстве других) имеет только одно значение (которое само по себе не является типом).

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

Unity также является способом, которым большинство таких языков описывают Enums, позволяя новому типу быть любым из определенного набора других типов или описывать, возможно, типы, значения, которые могут быть значениями типичного типа (скажем, целое число) или иметь значение, которое представляет собой нет значения.

Некоторые языки, которые не используют богатство пользовательских типов единства, все еще имеют единство в них, в той или иной форме. Например, Python имеет по крайней мере три типа единства, NoneType, NotImplementedType, и EllipsisType. Интересно, что первые два означают что-то вроде «Нет значения», но третий используется в комплексных значениях (в частности, в выражениях слайсов) для представления интересных частных случаев.

Другие интересные примеры единства включают NULLв sql и undefinedв javascript, но не voidв C или C ++. voidвыходит из строя. Даже если оно описывает значение без информации, но фактическое значение не может иметь тип void.

SingleNegationElimination
источник
Я думаю, что вы имеете в виду «тип устройства».
Джейсон Бейкер
2

symbolТип Руби немного необычен. По сути, это строка, реализующая шаблон синглтона. Или что-то. До сих пор я обнаружил, что наилучшее использование символов для отслеживания состояний и передачи имен функций.

philosodad
источник
Также как ключи к карте для O (1) сравнения ключей.
Джереми Хейлер
Ну, это не так уж необычно. Ruby унаследовал его от Smalltalk, который унаследовал его от Lisp. Я думаю, что у Scala это тоже есть. Фактически, почти каждая языковая реализация (компилятор или интерпретатор) имеет внутреннюю таблицу символов, Lisp, Smalltalk и Ruby просто предоставляют ее программисту.
Йорг Миттаг
1

COBOL. По сути только два основных типа данных, строки и числа, но вы должны точно указать , как они расположены в памяти, например PIC S9(5)V99 COMP-3.

dan04
источник
Я могу победить это. BCPL имеет один тип данных - слово; см. en.wikipedia.org/wiki/BCPL
Стивен С.
Существуют разные типы номеров (COMP, COMP-1, COMP-2, COMP-3).
Дэвид Торнли
Звучит ужасно. Можете ли вы уточнить, что означают эти детали?
Марк С
S= подпись, 9(5)= 5 цифр, V= неявная десятичная точка, 99= еще 2 цифры, COMP-3= BCD + знак nybble.
Ден04
1

Клипер имел «блоки кода», которые были похожи на анонимные методы. Их можно передавать и оценивать по мере необходимости, как правило, в форме обратного вызова. Вы часто используете их для выполнения вычислений на лету при представлении таблиц данных.

GrandmasterB
источник
0

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;

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

mouviciel
источник
0

Clojure интересен тем, что имеет мета-концепцию «абстракций», которые пронизывают язык. Примеры:

  • Коллекции
  • Последовательности (ленивые и не ленивые)
  • Функции высшего порядка
  • Мультиметоды
  • протоколы
  • Управляемые ссылки
  • макрос
  • различные другие .....

В некоторой степени абстракции доводят « принцип единой ответственности » до крайности. Вы должны составить их, чтобы получить желаемую функциональность, но вы можете быть чрезвычайно гибкими в том, как склеивать их вместе.

Например, если вам нужна система ООП на основе классов с наследованием, вы можете относительно быстро создать одну из этих основных абстракций.

На практике сами абстракции разрабатываются таким образом, что возможны несколько реализаций, например, через специальные интерфейсы, такие как clojure.lang.ISeq для последовательностей или clojure.lang.IFn для функций более высокого порядка.

На эту тему есть интересное видео: Искусство абстракции

mikera
источник
0

Если вам нужен язык с уникальным типом, отправляйтесь в BCPL . Этот язык имеет только один тип данных, слово, являющееся фиксированным числом битов для языковой реализации.

uɐɪ
источник
0

Googles Go имеет тип «Канал», который является совершенно уникальным.

Brainlag
источник
1
Каналы не уникальны. У многих языков они есть. У Феликса они были за 10 лет до существования Google :) У Окамла они были за 10 лет до появления Феликса.
Иттрилл
И был еще как минимум один язык, у которого были каналы до появления Окамля. По-прежнему один из наименее доступных типов в языках программирования.
Brainlag