LINUX.ORG.RU

В чём профит от Eiffel...

 ,


2

4

...и, в частности, от design by contract? Чем эта фича принципиально отличается от ассертов в других языках?

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

Мой интерес вызван тем, что Бертран Мейер - автор языка Eiffel - возглавляет (возглавлял?) кафедру программной инженерии и верификации программ в СПбНИУ ИТМО (http://sel.ifmo.ru/), и используют они в основном Eiffel.

★★★★★

Последнее исправление: hateyoufeel (всего исправлений: 3)

Программировать БД можно?

bookman900 ★★★★★
()
Ответ на: комментарий от tailgunner

Да, мне тоже название кажется не совсем корректным, но это скорее к товарищу Мейеру вопрос.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от msgascii

А C транслируется в ассемблер. И Java транслируется в ассемблер. И даже Haskell транслируется в ассемблер.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

И даже Haskell транслируется в ассемблер.

Даже удивительно, что до сих пор никто не занялся созданием хаскель-машины

Gvidon ★★★★
()

ИТМО

Ультразашквар

Чем эта фича принципиально отличается от ассертов

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

buddhist ★★★★★
()

Если интересно, то в 2007-м году я довольно серьезно интересовался Eiffel, более-менее его освоил (благо язык очень простой, а книга про него «Объектно-ориентированное конструирование программных систем» расписывает все очень подробно), даже какие-то программки небольшие на нем делал. Впечатления описаны здесь: #1, #2 (краткий обзор своими словами), #3 (впечатления, положительные и не очень).

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

Однако, Eiffel единственный язык, в котором контракты (пред, постусловия, инварианты) хочется описывать и это делается естественно и с удовольствием. В языке D, например, хоть контракты и есть, но про них либо вечно забываешь, либо лень писать. Насколько я знаю, попытки добавить контракты в другие мейнстримовые языки в виде библиотек, расширений или внешних инструментов (например, когда контракты записываются в JavaDoc/Doxygen-комментариях) не прижились. Т.е. фанаты DbC их используют, а обычные программисты забивают.

В Eiffel-е почему-то иначе. Причем контракты, которые описываются для классов стандартной библиотеки Eiffel-я, являются существенным дополнением к документации. Разобраться с каким-нибудь контейнером в Eiffel было гораздо проще, чем с STL-евским в C++.

Поэтому в Eiffel контракты реально работают. В отличии от других языков. Вроде как в MS Research был язык Spec#, в котором так же DbC использовался в полный рост, но в массы Spec# так и не вышел.

Что еще можно сказать про Eiffel? Пожалуй, единственный ООП язык с нормальным множественным наследованием. После Eiffel любые статически-типизированные ОО-языки без оного воспринимаются вообще как не ОО-языки. Даже C++ в этом сильно Eiffel-ю уступает. В последние годы Eiffel сильно развился. Очень крутую штуку в него добавили несколько лет назад, void safety называется. Что-то подобное в C#, насколько я помню, добавляли уже после того, как void safety пошла в продакшен в Eiffel-е. Кроме того, вроде как SCOOP до ума довели. Но насколько SCOOP пригоден для реального применения — фиг знает.

Общее же впечатление такое: это язык, которому можно научить не очень хороших разработчиков, они будут писать нормальный код и не косячить сильно. Но хорошим программистам, которых тот же C++ не пугает, писать на Eiffel будет тоска смертная.

Посему в OpenSource Eiffel-ю, на мой взгляд, ловить нечего (собственно, его там почти и нет). А в коммерческой разработке, из-за очень высокой стоимости лицензий на EiffelStudio и ограниченного выбора прикладных библиотек, Eiffel может найти себе применение только в очень узких сферах. Где ему придется потолкаться, например, с Ada. Не говоря уже про C++ и Java.

Как-то так.

eao197 ★★★★★
()
Ответ на: комментарий от buddhist

но в SPARK/Ada для верификации контрактов используется полноценный прувер

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

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от eao197

Спасибо за развернутый коммент.

Очень крутую штуку в него добавили несколько лет назад, void safety называется

На самом деле это костыль, вызванный наличием невалидных значений (void/null) в пространстве значений ссылок как типа.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

На самом деле это костыль, вызванный наличием невалидных значений

AFAIK, для императивных языков программирования значения null — это фундаментальная фича, крайне необходимая, например, при реализации многих структур данных. Скажем, списков.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

AFAIK, для императивных языков программирования значения null — это фундаментальная фича, крайне необходимая, например, при реализации многих структур данных. Скажем, списков.

Нет. Algebraic Data Types решают эту проблему намного лучше.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Нет. Algebraic Data Types решают эту проблему намного лучше.

Чем тогда вариант None в Optional(Some<T>,None) будет отличаться от Null?

eao197 ★★★★★
()
Ответ на: комментарий от hateyoufeel

Да вы, батенька, догматик...

Т.е., по вашему,

struct ListItem {
  Payload data;
  Optional<ListItem> prev;
  Optional<ListItem> next;
}

item = new ListItem;
item.prev = None;
item.next = None;
принципиально отличается от
struct ListItem {
  Payload data;
  ListItem prev;
  ListItem next;
}

item = new ListItem;
item.prev = null;
item.next = null;

?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Чем тогда вариант None в Optional(Some<T>,None) будет отличаться от Null?

Его невозможно разыменовать:

enum NullablePtr {
    Valid(Box<usize>),
    Invalid
}

fn foo(p: NullablePtr) -> () {
    match (p) {
        NullablePtr::Valid(p) => println!("{}", p),
        NullablePtr::Invalid => /* разыменование написать невозможно */println!("NULL")
    }
}

fn main() {
    foo(NullablePtr::Valid(Box::new(1)));
    foo(NullablePtr::Invalid);
}
tailgunner ★★★★★
()
Ответ на: комментарий от eao197

None имеет тип Optional(T). Null имеет тип T. Если функция принимает T, при попытке сунуть в неё Optional(T) тайпчекер надаёт тебе по голове. Так понятнее?

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от eao197

Тем, что ты не можешь использовать вложенный объект не распаковав его явно, а значит NullPointerException во всех его видах невозможен в принципе. Плюс Null подразумевает указатели/ссылки и выделение на куче, в то время как Option хранит объекты по значению.

nonimous
()
Ответ на: комментарий от eao197

В первом случае явно видно, что там может быть None, во втором: ничего не ясно. Там даже data может быть null, и тайпчекер будет молчать.

Kuzy ★★★
()
Ответ на: комментарий от tailgunner

Ну как раз добавление void safety именно это и добавило в язык. Что для императивного ООЯ времен середины 80-х очень даже неплохо. Такой себе частный случай AlgDT в языке, где AlgDT не было в принципе.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Естественно отличается, в первом случае item.prev.prev будет ошибкой компиляции, а во втором - ошибкой исполнения.

nonimous
()

Да ни в чём. Ну, если не с брэйнфаком сравнивать.

Miguel ★★★★★
()
Ответ на: комментарий от eao197

для императивного ООЯ времен середины 80-х очень даже неплохо

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

tailgunner ★★★★★
()
Ответ на: комментарий от hateyoufeel

Так понятнее?

Сударь, вы дебил?

Речь шла о конкретном случае, когда нужен Optional(T) и нужно указать, что T нет. Значение None в данном случае и есть полный аналог null.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Сударь, вы дебил?

Нет, дебил - это ты, потому что не можешь осознать, что None в твоём примере не входит в пространство значений типа T, что позволяет найти множество ошибок на этапе компиляции.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от Kuzy

В первом случае явно видно, что там может быть None, во втором: ничего не ясно. Там даже data может быть null, и тайпчекер будет молчать.

Просто для информации: в Eiffel, как и в C++, есть не только ссылочные типы. Payload может храниться внутри ListItem-а в виде значения. Так что не нужно к Eiffel-ю походить с мерками языков вроде Java.

eao197 ★★★★★
()
Ответ на: комментарий от hateyoufeel

Нет, дебил - это ты, потому что не можешь осознать, что None в твоём примере не входит в пространство значений типа T, что позволяет найти множество ошибок на этапе компиляции.

Причем тут множество значений типа Т?

Речь шла о том, что без null нельзя реализовать некоторые фундаментальные структуры данных. Например, списки. Ссылки на соседние узлы списка могут отсутствовать. Этот факт вам нужно отразить. Вы это делаете либо посредством значения null для ссылки. Либо с помощью None в случае с Optional. Уберите из своего гипотетического языка с AlgDT значение None и как вы будете разбираться с такими ситуациями?

Достоинство void safety в Eiffel в том, что ссылки там теперь рассматриваются как аналоги Optional<T>, где T — это ссылочный тип. Просто записывается это почти так же, как и раньше. И паттерн-матчинг в язык вводить не пришлось.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

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

anonymous
()
Ответ на: комментарий от eao197

Уберите из своего гипотетического языка с AlgDT значение None и как вы будете разбираться с такими ситуациями?

Не понял вопроса, зачем убирать None? Плюс Option это не столько часть языка, это часть стандартной библиотеки, частный случай ADT. Если его убрать Option, его аналог определяется в 5 строк.

Достоинство void safety в Eiffel в том, что ссылки там теперь рассматриваются как аналоги Optional<T>, где T — это ссылочный тип.

Я так понял, только ссылки специально помеченных типов. Т.е. NullPointerException все так же возможен.

И паттерн-матчинг в язык вводить не пришлось.

Лол.

if attached some_attribute as l_attribute then
   do_something (l_attribute)
end
А это что такое? Это ad-hoc паттерн-матичнг для одного особого типа на уровне языка. Авторы явно хотели утащить Maybe из Haskell, но полноценный ADT не осилили.

В общем же можно придти к выводу, что этот твой void safety - эталонный костыль.

nonimous
()
Ответ на: комментарий от true_admin

Ленивой хаскель-машины :)

Сделал мой вечер! Так и представляю, пока пользователь не взглянет на терминал железка ничего не вычисляет.

exception13 ★★★★★
()
Ответ на: комментарий от nonimous

Не понял вопроса, зачем убирать None?

Затем, что я говорил, что null — эта фундаментальная вещь, без которой много чего невозможно. Аналогом может считаться None, без которого те же самые вещи (вроде списков) нельзя будет реализовать, как и без null.

Это ad-hoc паттерн-матичнг для одного особого типа на уровне языка.

Ну блин, а разве я не об этом сказал чуть выше: «Ну как раз добавление void safety именно это и добавило в язык. Что для императивного ООЯ времен середины 80-х очень даже неплохо. Такой себе частный случай AlgDT в языке, где AlgDT не было в принципе.»

В точности тоже самое. Но полноценного паттерн-матчинга в языке как не было, так и нет.

Авторы явно хотели утащить Maybe из Haskell, но полноценный ADT не осилили.
В общем же можно придти к выводу, что этот твой void safety - эталонный костыль.

Не, ну ё-моё! Речь идет о языке, который был создан в 1986-м, в котором сделали то же самое с сылочными типами, что и в куче языков того времени (а так же более ранних и более поздних): допустили наличие null для ссылок. Потому, что если есть ссылки, а не AlgDT, то без null ну никак.

А потом взяли, да и исправили эту ошибку. Причем не сломав сильно совместимость между версиями языка.

Для LOR-овских аналитиков, это, наверное, ничего не значит. Но когда язык существует 25 лет и на нем написан не один миллион строк, это офигенно какой прорыв. Потому я и сказал в начале, что void safety сильно улучшил язык.

Конечно, если выйти за рамки обсуждения Eiffel и начать говорить об AlgDT вообще или Maybe из Haskell в частности, то можно далеко уйти. Но речь шла о конкретно Eiffel-е.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Что для императивного ООЯ времен середины 80-х очень даже неплохо.

Это очень плохо для языка, расчитанного на написание критичных к наличию ошибок программ.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Это очень плохо для языка, расчитанного на написание критичных к наличию ошибок программ.

Есть в изучении истории такое понятие «послезнание». Это когда события прошлого судят с позиции знания последствий этих самых событий. Вы сейчас как раз высказываетесь на основании послезнания.

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

Такие были времена.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

И паттерн-матчинг в язык вводить не пришлось.

Какая великая радость, однако.

nezamudich ★★
()
Ответ на: комментарий от eao197

Но когда язык существует 25 лет и на нем написан не один миллион строк, это офигенно какой прорыв.

Для Eiffel это может и прорыв, но на фоне современных ЯП это костыль, который не представляет особого интереса. И да, в С++ std::experimental::optional добавляют, и язык старше с большей кодовой базой на пару порядков, тоже «прорывом» называть?

А потом взяли, да и исправили эту ошибку.

Добавили возможность потенциально избегать части возможных ошибок. NullPointerExeptions никуда не делись, я так понял.

nonimous
()
Ответ на: комментарий от nonimous

И да, в С++ std::experimental::optional добавляют, и язык старше с большей кодовой базой на пару порядков, тоже «прорывом» называть?

Официальный релиз C++, как ни странно, датирован 1985-м годом.

В C++ в optional<T*> вы спокойно сможете поместить nullptr. И будете просто различать случаи, когда нет вообще никакого значения для T*, либо когда есть какое-то значение, включая nullptr.

В Eiffel ссылка не может иметь значение Void. Если только ссылка не объявлена как detachable. Но если ссылка объявлена как detachable, то вы не можете по ней обратиться, предварительно не проверив на Void. Так что получить NullPointerException в современном Eiffel еще нужно постараться.

И таки да, в рамках конкретного языка с многолетней историей это прорыв. Без кавычек.

В С и C++ такой прорыв не возможен. Как, полагаю, и в Python-е или Ruby.

eao197 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.