Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Существует ли язык мечты, сочетающий в себе преимущества динамической и строгой типизации?

Автор вопроса: Mr. LameОтветов: 5

Мне было бы интересно изучить язык, который внутренне обрабатывает объекты как хэш-таблицы (например, JavaScript), но мог бы обернуть их сильными типами, чтобы предложить преимущества завершения кода/разума во время разработки. Вот как я хочу, чтобы этот язык сновидений работал:

public class Lion
{
  public void Roar() { Console.WriteLine("Aaarrgghh");}
}

public static Main(string[] args)
{
  object myCat = new object(); // just plain object, no type!
  // adding a Roar() method to the myCat instance
  myCat.Roar += delegate() {Console.WriteLine("Miauew");}
  // At this point myCat should qualify to be a Lion.
  // So we should be able to successfully duck-type-cast
  // her to a lion
  Lion myLion = myCat as Lion;
  // now the myLion reference is strongly typed,
  // so I expect the Intellisense window pop up
  // and offer me the Roar() method when I hit the dot after "myLion"
  myLion.Roar();
}

Я хочу, чтобы эта программа компилировалась без ошибок, запускалась без исключений и печатала "Miauew" в консоли. Есть ли язык, который может это сделать? Может С# 4.0?

  • Я думал о чем-то подобном как о расширении Lua. Я использую Lua во встроенной среде, где ценен каждый байт памяти. Lua также использует хеш-таблицы внутри, что очень неэффективно с точки зрения памяти для определенных типов объектов. Было бы неплохо иметь структурный синтаксис для простого создания плотно упакованного объекта в Lua, вместо того, чтобы полагаться на пользовательские объекты в C. Dolphin 28.06.2009

strong-typingduck-typingdynamic-typing

Ответы

Ответ 1 · рейтинг 3 · Emiswelt

Возможно, новый динамический тип в C# 4.0. посмотрите на это: http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx

Ответ 2 · рейтинг 2 · Pete Kirkham

Это скорее зависит от того, что вы намеревались реализовать с помощью типа Lion, не виртуальный метод.

Расширенная типизация (набор объектов данного типа - это те, которые обладают свойствами типа, что близко к статическому эквиваленту утиной печати) требует, чтобы структура объекта подразумевала его тип, но ваш Lion type не имеет структуры - он только говорит, что все, что является львом, имеет этот конкретный метод Roar. Итак, для вашего примера я не вижу способа, которым вы могли бы превратить свою кошку в Льва, поскольку у нее нет единственного структурного свойства, которое, как вы сказали, есть у львов.

Если, с другой стороны, вы имели в виду, говоря, что все, что вы называете львом, может иметь либо собственный метод рыка, либо будет использовать метод в льве, это ничего не говорит о типе объектов, которые являются львами, и AFAIK вы могли бы получить такое же поведение с методом расширения для объекта (хотя я недостаточно знаю С#, чтобы знать, переопределяют ли собственные методы методы расширения в С#).

В динамической IDE нет причин, по которым вам нужно приводить к Lion, прежде чем IDE сможет определить, что у myCat есть свойство Roar - эта информация выводится статически.

Причина, по которой поддержка IDE затруднена в языках с динамически конструируемыми типами, таких как JavaScript, заключается в том, что вы можете сделать это:

let myCat = {}

if ( locale.name == 'en' )
    myCat.roar = function () { alert ( "Miauew" ); }
else
    mCat[ resources.getString( 'roar' ) ] =
        function () { alert ( resources.getString ( 'Miauew' ) ); }


// the structure of the type of myCat depends what locale the code
// is running in, so you can't deduce the Intellisense
myCat.

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

Если Intellisense не может вывести структуру объектов, структура которых выводима статически, то это недостаток Intellisense, а не динамической типизации.

Что бы вы назвали преимуществом строгой типизации в вашем примере?

Ответ 3 · рейтинг 2 · Community

Каждый раз, когда я пытался спланировать что-то подобное, проблема заключалась в актерском составе. Конечно, вы можете просто поверить программисту на слово, но это сочетает в себе худшие черты обеих систем типизации. Возможно, приведение могло бы проверять во время выполнения, реализует ли объект интерфейс Lion, но это в принципе невозможно. В данном случае это выглядит правдоподобно, поскольку все, что вам нужно, - это существование функции void (*)(). Но вообще, что, если у Lion есть метод getHabitat, который возвращает объект, который должен принадлежать другому интерфейсу? Строго типизированный язык должен быть в состоянии сказать наверняка, что он действительно это делает, но без фактического вызова метода вы не можете вообще сказать, возвращает ли нетипизированный код Habitat, и, следовательно, в терминах строгой типизации вы не можете работать. вне ли это Лев.

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

Ответ 4 · рейтинг 1 · Paul Biggar

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

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

Статические типы в динамических языках

Проблема возникает, когда вы смотрите на то, как объекты используются в языках сценариев - все они имеют утиный тип. Это означает, что имя типа (номинальное написание) бесполезно. Все современные императивные языки (Java, C#, C++, C) используют номинальные системы типов. Таким образом, в C++ вы можете сказать, что ожидаете Duck, но в Python вам действительно нужно что-то, что идет quack().

Поэтому рассмотрите возможность добавления статической типизации к языку с утиной типизацией. Поскольку функция ожидает от параметра значение quack(), но не может сказать, что ожидает значение Duck, объединение этих двух параметров затруднено. Вы можете определить интерфейс с именем quacks, который может quack(), и использовать его в качестве типа. Но на самом деле это немного многословно, что убивает преимущества динамической типизации. Однако, возможно, может быть что-то в этом роде (какая-то система структурных типов), которая может сделай это.

Альтернативой было бы просто потребовать от программиста указать Duck, и в любом случае, черт бы побрал этот бизнес с утиным набором - никто на самом деле не использует его, не так ли? Но тогда вы просто пишете Java на Python, и как человек, который пробовал это однажды, позвольте мне сказать вам, что это очень контрпродуктивно.

Динамические типы в статических языках

Итак, давайте посмотрим на это с другой стороны. Как C# выиграет от ключевого слова dynamic? Простой ответ: не будет. Честно говоря, я не вижу той красоты и свободы, которые вы получаете от Python в dynamic C#. Теперь, единственное, что я знаю об этом, исходит из выступления Джона Скита, но ошеломляющее впечатление, которое я получил, состоит в том, что это многословно и неэлегантно. И я думаю, что это не ошибка реализации со стороны C#. Я думаю, это потому, что проблемы, которые динамическая типизация решает в Python, уже решены в C# (хотя и подробно), и dynamic просто ничего не приносит на вечеринку.

Исследование статических/динамических вещей

Поищите постепенный набор текста Джереми Сиека, это самые передовые статические/динамические исследования. Тем не менее, это немного трудное чтение, и я сам только бегло рассмотрел его, поэтому я не могу обобщить его. Тем не менее, интересно пролистать только его связанные работы и Конференция STOP, вероятно, будет хорошей.

Ответ 5 · thSoft

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы