Есть ли объектно-ориентированный статический типизированный язык с несколькими типами переменных? - PullRequest
5 голосов
/ 12 сентября 2010

Мне нравится читать о теориях программирования, поэтому не могли бы вы сказать мне, существует ли какой-либо объектно-ориентированный статический типизированный язык, который позволяет переменным иметь несколько типов?Пример в pesudocode:

var value: BigInteger | Double | Nil

Я думаю о способе вызова методов для этого объекта.Если объект значение имеет тип BigInteger |Двойной язык может позволить пользователю вызывать только общие методы (озеро плюс, минус), но когда тип равен BigInteger |Двухместный |Nil тогда у объекта Nil нет методов плюс и минус, поэтому мы ничего не можем сделать с этим объектом, потому что он имеет только несколько общих методов (например, toString).идея, как должны работать вызовы методов для переменных с несколькими типами в статически типизированном объектно-ориентированном языке?

Ответы [ 6 ]

8 голосов
/ 12 сентября 2010

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

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

Обратите внимание, что используемый вами синтаксис 1018 *обычно используется для обозначения типов объединения , которые являются двойственными типами пересечения.Типы пересечений обычно пишутся A & B & C.

5 голосов
/ 12 сентября 2010

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

Хотя это уже возможно: относительно элегантно в структурной системе типов (тип a является подтипом типа b, если a имеет все, что имеет b), просто указав тип для значения, являющегося структурным подтипом BigInteger и Double и Nil и немного менее элегантно в системе именительного типа (тип a является подтипом типа b в том и только в том случае, если он наследует от него, прямо или косвенно) путем указания общего предка всех трех (если все иначе не удается, object). Конечно, нам нужно идти рекурсивно - какой тип toString? И какой тип (Integer | Double | BigInteger).+?!? Это далеко не тривиально (на самом деле, поиск решения сделал мою голову немного болит). Я не могу сказать, если это невозможно, но ни одна система типов, основанная на языке OO, не является достаточно сложной для возможного решения.

Суть в том, что было бы действительно здорово , если бы появился какой-то свист и разобрался с проблемами, которые он поднимает. Вероятно, не стоит усилий ...

Редактировать: Знаете ли вы алгебраические типы данных ? Они похожи на вашу идею (но намного старше;)) в том, что алгебраический тип данных состоит из нескольких типов и, следовательно, может содержать, например, BigInteger, Double и Nil - фактическое значение является одним из них, и тег (как в tagged union ) говорит о том, какой. Но чтобы использовать значение, хранящееся в алгебраическом типе данных, вы должны использовать сопоставление с шаблоном для его безопасного извлечения. Эта концепция очень мощная и все же достаточно "простая", чтобы ее можно было понять инструментами - например, вывод типа и статическая проверка типов.

1 голос
/ 12 сентября 2010

Пайк имеет их, как и Сорока , опционально типизированный язык, над которым я работаю. Закрывающий компилятор Google для Javascript позволяет аннотировать типы в Javascript с помощью |.

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

var a = 123;
if (foo) { a = "string"; }
bar(a);

Статически определенный тип, передаваемый bar(), равен Number | String.

1 голос
/ 12 сентября 2010

Да, OCaml имеет их в виде полиморфных вариантов:

type my_var = Integer of int | Float of float;;
let x = Integer(10);;
let y = Float(3.14);;
1 голос
/ 12 сентября 2010

Это не имеет ничего общего с ОО, но (насколько я понимаю) то, что вы описываете, выглядит как полиморфизм, реализованный в C ++.

0 голосов
/ 12 сентября 2010

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

Одна из моих проблемчто если вы добавите типы T1 и T2 как часть вашего BigInteger | Double | Nil, как они узнают друг о друге и как будут обрабатывать определенные вами операции?Теперь я понимаю, что вы никогда не говорили, что язык позволит расширить определение «неявного» преобразования.

Если подумать, C # делает что-то похожее в своей обработке строк

string s = -42 + '+' + "+" + -0.1 / -0.1 + "=" + (7 ^ 5) + 
  " is " + true + " and not " + AddressFamily.Unknown; 

=> "1 + 1 = 2 - это правда, а не неизвестно"

string str = 1 + 2 + "!=" + 1 + 2;

=> "3! = 12"

И мне это не нравится.

...