LINUX.ORG.RU

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

 ,


2

4

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

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

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

★★★★★

Последнее исправление: hateyoufeel (всего исправлений: 3)
Ответ на: комментарий от tailgunner

Ну, естественно, семантика двусвязного списка никуда не денется. А вот SIGSEGV от разыменования nullptr пропадут.

В сухом остатке: есть объективная необходимость указывать, что какой-то ссылки не существует, а так же есть необходимость защититься от обращения к ссылке без значения.

Соответственно, решать это можно, как минимум, двумя способами:

1. Сделать void/null валидным значением для ссылок, но на уровне языка контролировать наличие проверок на void/null перед обращением по ссылке.

2. Считать ссылкой только валидную ссылку на объект. Для указания отсутствия валидной ссылки использовать какой-то другой объект (например, None в Optional[T]).

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

Коль скоро здесь поминали Хоара, то лично я воспринимаю слова Хоара об ошибке на миллиард долларов как сожаление о том, что не был выбран ни один из двух вышеупомянутых способов.

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

В сухом остатке: есть объективная необходимость указывать, что какой-то ссылки не существует, а так же есть необходимость защититься от обращения к ссылке без значения.

Нет понятия «ссылки не существует».

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

1. Сделать void/null валидным значением для ссылок, но на уровне языка контролировать наличие проверок на void/null перед обращением по ссылке.

2. Считать ссылкой только валидную ссылку на объект. Для указания отсутствия валидной ссылки использовать какой-то другой объект (например, None в Optional[T]).

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

Потому что в первом случае мы вводим механизм, узко заточенный под ссылки, а во втором - используем механизм pattern matching (или аналогичный оператор работы с tagged unions), полезный для решения гораздо более общих задач.

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

Потому что в первом случае мы вводим механизм, узко заточенный под ссылки

Не вижу в этом ничего плохого, т.к. при обычном программировании приходится считаться с объективной реальностью. Например, из-за которой в статически-типизированных языках есть разные типы для целых чисел и разные для вещественных. Почему-то то, что int — это одно, а float — другое, воспринимается нормально. А вот то, что есть указатели/ссылки — это уже плохо. Тем более, если рассмотреть указатели на указатели. Таки запись T** несколько удобнее, чем Optional[Optional[T]].

Хотя, если оперировать понятиями теории категорий и разрабатывать модели микропроцессоров на Haskell-е, то AlgDT рулят и бибикают, наверное :)

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

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

Потому что он ведёт к ненужному усложнению языка ещё одним специальным случаем, в отличие от второго способа, который реализуется общими штатными средствами. Т.е. второй способ следует KISS, а первый — нет.

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

Таки запись T** несколько удобнее, чем Optional[Optional[T]].

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

let x :: **T in case x of
  **valOfT -> doSomethingWithVal valOfT
{- *optOfT -> doSomethingWithOpt optOfT -}
  _        -> {- got Nothing -}

Или посмотри, как в том же Хаскелле реализуются «цепочки» вызовов функций, принимающих значение типа, а возвращающих Maybe, например. Без всяких «специальных случаев» и вручную писать проверки не нужно.

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

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

Ну раз здесь все такие умные, то объясните, почему 30 лет назад языках, которые стали широкоиспользуемыми, ничего подобного не сделали?

Может тому были объективные причины?

И может взгляд ФП-шников на то, как нужно программировать, всего лишь один из возможных?

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

Потому что в первом случае мы вводим механизм, узко заточенный под ссылки

Не вижу в этом ничего плохого

Ну в костыле нет ничего плохого - он помогает ходить.

при обычном программировании приходится считаться с объективной реальностью

Программирование с ADT - вполне обычное программирование, оно считается с общей для всех нас объективной реальностью.

Хотя, если оперировать понятиями теории категорий и разрабатывать модели микропроцессоров на Haskell-е, то AlgDT рулят и бибикают, наверное :)

Mach7

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

Ну раз здесь все такие умные, то объясните, почему 30 лет назад языках, которые стали широкоиспользуемыми, ничего подобного не сделали?

Потому, что развитие шло от императивного подхода изначально. Потому, что проще сделать. Есть у нас адреса, зарезервируем значение, чтобы показывать «отсутствие ссылки» и все. Языки были довольно простыми. Сейчас растут объемы проектов, тяжело в голове держать код, появляются те или иные приемы. Начинают применяться те приемы, что раньше были невостребованны.

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

Программирование с ADT - вполне обычное программирование, оно считается с общей для всех нас объективной реальностью.

У каждого, походу, своя реальность. Из языков, которые более-менее близко к мейнстриму, AlgDT и полноценный паттерн-матчинг есть в Scala, Haskell и OCaml.

Во всем остальном, включая C, C++, Java, C#, JavaScript, Python, Ruby, PHP, VisualBasic и т.д., кроме костылей ничего и нет.

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

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

Объемы проектов привысили возможности отдельных разработчиков уже очень и очень давно. Как раз лет 30-40 назад, когда был очередной кризис разработки ПО, и создавались языки вроде C++, Ada и Eiffel. Продолжением которых стали появившиеся чуть позже Java, C# и Scala.

Кроме того, пришествие Web-а и мобильных платформ (смартфонов, планшетов, умных телевизоров и пр.) привело к востребованности таких языков, как PHP, Ruby, Python и JavaScript. И что-то мне подсказывает, что средние размеры проектов на этих языках будут поменьше, чем средние размеры проектов на C++, Ada или Eiffel. А так же Java и C#. Тогда как самих проектах на PHP/Ruby/Python/JavaScript, возможно, будет много больше.

Но это все лирика. Физика в том, что во времена зарождения Eiffel возможности вычислительной техники были совсем другие. Потому и решения, которые выглядели красиво в теории, на практике могли просто не взлететь из-за ограниченных мощностей тогдашних ЭВМ. Посему достаточно странно наблюдать, как принятые тогда решения оцениваются исходя из сегодняшних возможностей и популярных идей.

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

Объемы проектов привысили возможности отдельных разработчиков уже очень и очень давно.

Крайне голословное утверждение.

Как раз лет 30-40 назад, когда был очередной кризис разработки ПО, и создавались языки вроде C++, Ada и Eiffel.

Ada была создана точно не из-за этого.

пришествие Web-а и мобильных платформ (смартфонов, планшетов, умных телевизоров и пр.) привело к востребованности таких языков, как PHP, Ruby, Python и JavaScript.

К вебу имеют непосредственное отношение только PHP и JS. К мобильным платформам же - ни один из перечисленных. Основная особенность этих языков - низкий порог вхождения. Расцвет веба привёл к необходимости в огромной количестве программистов, зачастую в ущерб качеству. Сечёшь фишку?

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

Miranda ( http://en.wikipedia.org/wiki/Miranda_(programming_language) ) появилась на год раньше Eiffel, при этом в ней уже были ADT и Pattern Matching. ML же вообще в 1973 сделали.

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

Miranda ( http://en.wikipedia.org/wiki/Miranda_(programming_language) ) появилась на год раньше Eiffel, при этом в ней уже были ADT и Pattern Matching. ML же вообще в 1973 сделали.

Молодой человек, вы о чем-нибудь за пределами Haskell и Erlang наслышаны?

То у вас голословными являются утверждения, что размеры программ уже очень давно превысили возможности одного разработчика. То Python и Ruby у вас к Web-у отношения не имеют, а JS к мобильным устройствам...

Упомянутые вами Miranda и ML вряд ли были широко известны даже в узких кругах в те времена. А уж о более-менее заметном использовании и говорить не приходится.

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

Молодой человек, вы о чем-нибудь за пределами Haskell и Erlang наслышаны?

Конечно.

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

Каких программ? Всех программ?

Miranda и ML вряд ли были широко известны даже в узких кругах в те времена

Потому что ты о них не слышал?

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

У каждого, походу, своя реальность.

Каждому привычна его часть общей реальности.

Из языков, которые более-менее близко к мейнстриму, AlgDT и полноценный паттерн-матчинг есть в Scala, Haskell и OCaml.

Еще F#, Swift. В Erlang есть pattern matching, не знаю насчет ADT.

Во всем остальном, включая C, C++, Java, C#, JavaScript, Python, Ruby, PHP, VisualBasic и т.д., кроме костылей ничего и нет.

Похоже, вместо «обычное программирование» ты хотел сказать «программирование на привычных языках».

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

Конечно.

Крайне голословное утверждение.

Каких программ? Всех программ?

Очень и очень многих программ.

Потому что ты о них не слышал?

Скорее потому, что никогда живьем видеть их не приходилось. Только встречать упоминания в литературе. Например, о том, что Страуструп ссылается на ML говоря о языках, которые оказали влияние на C++. И о том, что Haskell бы мог не появится, если бы автор Miranda согласился бы сделать Miranda базой для развития нового, современного ФЯ.

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

Еще F#

Да, про F# забыл, каюсь...

Swift.

Он совсем недавно появился и время, когда он станет полноценным мейнстримом, еще впереди.

В Erlang есть pattern matching, не знаю насчет ADT.

Откуда в Erlang-е AlgDT, если там кроме списков и рекордов до недавнего времени вообще ничего не было. Совсем-совсем недавно в язык map-ы добавили.

Похоже, вместо «обычное программирование» ты хотел сказать «программирование на привычных языках».

Можно и так. А можно еще и так: «программирование на языках, для которых не сложно найти нормальную работу».

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

В Erlang есть pattern matching, не знаю насчет ADT

ADT там тоже есть, но из-за отсутствия статической типизации и наличия символов (как в лиспе) не так часто используются.

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

ADT там тоже есть

Нету их в Эрланге.

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

Через >>=?

Не помню, вроде <?> обычно. Ну, думаю, можно и в монаду обернуть.

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

Ну раз здесь все такие умные, то объясните, почему 30 лет назад языках, которые стали широкоиспользуемыми, ничего подобного не сделали?

Обратная совместимость? Лень? Упрямость? Глупость? Куча вариантов.

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

Объемы проектов привысили возможности отдельных разработчиков уже очень и очень давно. Как раз лет 30-40 назад, когда был очередной кризис разработки ПО, и создавались языки вроде C++, Ada и Eiffel. Продолжением которых стали появившиеся чуть позже Java, C# и Scala.

Физика в том, что во времена зарождения Eiffel возможности вычислительной техники были совсем другие. Потому и решения, которые выглядели красиво в теории, на практике могли просто не взлететь из-за ограниченных мощностей тогдашних ЭВМ. Посему достаточно странно наблюдать, как принятые тогда решения оцениваются исходя из сегодняшних возможностей и популярных идей.

вот и странно это весьма: уже 30-40 лет назад было понятно, что основная проблема в программировании — это метод и способы структурирования сложности.

для чего предлагались:

1) дисциплина программирования, Дейкстрой

2) умение формулировать мысли и писать «исполняемые эссе», Кнутом

3) сознательный минимализм, послушание и дисциплина — Виртом в Оберонах и далее. чтобы сложность отсекать на входе. собственно, так как это было принято в разработке железа.

4) software circuits Бреда Кокса в Objective-C

5) толстый, человекопонятный кобол язык Ада — с богатыми фичами в языке.

6) формальный подход и верификация спецификаций — в ML, Haskel и т.п. как апофеоз — ОС seL4 и unikernel MirageOS

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

собственно, ISE: институт софтверной инженерии, метод BON, метод Эйфель, метод ОО проектирования и разработки (и ОО не означает здесь С++, а означает «наиболее reusable тип данных»).

и затем: софтверная инжерения, ISE Eiffel, ISE -> Eiffel.com и ISE Eiffel -> EiffelStudio.

книги Бертрана Мейера, о дисциплине и методике софтверной инженерии.

сейчас вот движуха с Якобсоном, OMG Essense и альфами системной инженерии, гибкая разработка методик по типу Agile, на основе Essense kernel, ЖЦ софтвернной разработки, международные стандарты качества и ЖЦ и т.п.

однако же: программисты на С++ продолжают жрать кактус, делать вид, что всего этого не было, костылять свой велосипед и придумывать отговорки «мощности типы были другие, да и мозги тоже».

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

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

Соответственно, решать это можно, как минимум, двумя способами:

1. Сделать void/null валидным значением для ссылок, но на уровне языка контролировать наличие проверок на void/null перед обращением по ссылке.

2. Считать ссылкой только валидную ссылку на объект. Для указания отсутствия валидной ссылки использовать какой-то другой объект (например, None в Optional[T]).

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

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

и возможность синтезировать сразу правильно сразу нужный объект.

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

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

Ну раз здесь все такие умные, то объясните, почему 30 лет назад языках, которые стали широкоиспользуемыми, ничего подобного не сделали?

ad hominem к языку, это аргумент, ога. язык программирования не имеет срока годности — потому что это способ выражения мыслей, идиом, парадигм.

Может тому были объективные причины?

скорее, субъективные. субъективно: развиваются не столько языки программирования, как абстрактные, платоновы идеи  — а языки программирования как виртуальные машины реализации этого языка (Си-машина, о-код и BCPL-машина, раст-машина или xVM), тысячи их.

кстати, платон тут довольно годно всё понимал, это уже потом после него извратили — есть эйдос, или идея вещи, или программа не скомпилированная; есть воплощение вещи, или рантайм скомплированной программы; есть пространство, или песочница виртуальной машины или Си-машины или УМТ машины с архитектурой фон-неймана.

а есть УММ, а не УМТ.

объективных причин не развивать это направление мысли не было, субъективщина во все поля: когда Аристотелю понадобилось научить школоту (Александра Македонскова, если чо) — он решил его не грузить, и дать лишь то, что он сможет и осилит взять.

то есть: всё метапрограммирование он задвинул за полку и обозвал «метафизикой».

И может взгляд ФП-шников на то, как нужно программировать, всего лишь один из возможных?

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

но он интуитивно понятный, ога. потому что дуги и петли — и запоминается луше всего то, на что делает акцент игровая механика (а не «идея сути игры»).

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

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

Да, разница прям существенная:

if attached A as B then
   ...
end
И
A match {
  case Some(B) => ...
  case None
}
Сразу же переходим от run-time в compile-time... Одной лишь силой мысли анонимных LOR-овских экспертов.

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

множество: нужны рантайм проверки. в компайлтайм — не нужно никакого кода.

категория: не нужны рантайм проверки. в компайлтайм — синтезируется нужный объект (из категории, а не из множества), и задаются морфизмы, эндофункторы в категории.

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