Eiffel (язык программирования)

редактировать
Eiffel
логотип Eiffel
Paradigm Объектно-ориентированный, На основе классов, Generic, Concurrent
Разработано Бертраном Мейером
Разработчик Eiffel Software
Впервые появилось1986
Стабильный выпуск EiffelStudio 19.05 / 22 мая 2019 г.; 17 месяцев назад (22 мая 2019 г.)
Предварительный выпуск EiffelStudio 20.05 / 17 июня 2020 г.; 4 месяца назад (2020-06-17)
Дисциплина ввода статическая
Язык реализацииEiffel
Платформа Кросс-платформенная
OS FreeBSD, Linux, Mac OS X, OpenBSD, Solaris, Windows
Лицензия двойная и корпоративная
Расширения имен файлов .e
Веб-сайтwww.eiffel.org
Основные реализации
EiffelStudio, LibertyEiffel, SmartEiffel, Visual Eiffel, Gobo Eiffel, "The Eiffel Compiler" tecomp
Под
Ada, Simula, Z
Под услугами
Ada 2012, C#, D, Java, Racket, Ruby, Sather, Scala

Eiffel - это объектно- ориентированный язык программирования, ориентированный Бертраном Мейером (сторонником объектной ориентации и автором Конструирование объектно-ориентированного программного обеспечения ) и Eiffel Software. Мейер придумал язык в 1985 году с целью повышения надежности программного обеспечения; первая версия стала доступной в 1986 году. В 2005 году Eiffel стал стандартизированным языком ISO.

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

Многие концепции, принятые введенными Эйфелем, позже свое отражение в Java, C# и других языках. Новые идеи дизайна языка, в частности, посредством стандартизации Ecma / ISO, продолжают внедряться в язык Eiffel.

Содержание
  • 1 Характеристики
  • 2 Цели проектирования
    • 2.1 Предпосылки
    • 2.2 Реализации и среды
    • 2.3 Спецификации и стандарты
  • 3 Синтаксис и семантика
    • 3.1 Общая структура
      • 3.1.1 Область действия
      • 3.1.2 «Привет, мир!»
    • 3.2 Дизайн по контракту
    • 3.3 Защита от аннулирования
    • 3.4 Возможности: команды и запросы
    • 3.5 Перегрузка
    • 3.6 Универсальность
    • 3.7 Основы наследования
    • 3.8 Отложенные классы и функции
    • 3.9 Переименование
    • 3.10 Кортежи
    • 3.11 Агенты
    • 3.12 Один раз процедуры
    • 3.13 Преобразования
    • 3.14 Обработка исключений
    • 3.15 Параллелизм
    • 3.16 Синтаксис оператора и скобки, команды присваивания
    • 3.17 Лексические и синтаксические
    • 3.18 Соглашения о стилях
    • 3.19 Интерфейсы для других инструментов и языков
  • 4 Ссылки
  • 5 Внешние ссылки
Характеристики

Ключевые характеристики языка Eiffel включают:

  • объектно-ориентированные программы, которые служат основой для декомпозиции.
  • контракту Встроенный интегрирован с другими языковыми конструкциями.
  • Автоматическое управление памятью, обычно реализуемое посредством сборки мусора.
  • Наследование, включая множественное наследование, переименование, переопределение, «Выбор», несоответствующее наследование и другие механизмы, предназначенные для обеспечения безопасности наследования.
  • Ограниченное и неограниченное универсальное программирование
  • Единая система типов , обрабатывающая семантику как значения, так и ссылки, в которых все типы, включая базовые типы, такие как INTEGER, основаны на классах.
  • Статическая типизация
  • Пустая безопасность или статическая защита от нулевых ссылок с помощью механизма указанных типов.
  • Агенты или объекты, которые обертывают управление, связаны с подключениями и лямбда-исчислением.
  • Один раз подпрограммы или подпрограммы, оцениваемые только один раз, для совместного использования объектов и децентрализованной инициализации.
  • Синтаксис на основе ключевых слов в традиции АЛГОЛ / Паскаль, но без параметров, поскольку точки с запятой являются необязательными, с синтаксисом операторами, доступным для подпрограмм.
  • Нечувствительность к регистру
  • Простое параллельное объектно-ориентированное программирование (SCOOP ) облегчает создание нескольких, одновременно активных исполнительных машин на уровне абстракции выше конкретных деталей этих транспортных средств (например, несколько потоков без специального управления мьютексами).
Цели проектирования

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

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

Предпосылки

Eiffel изначально был разработан Eiffel Software, компанией, основанной Бертраном Мейером. Построение объектно-ориентированного программного обеспечения содержит подробное описание концепций и теории объектной технологии, которые приводят к разработке Эйфеля.

Целью проектирования, лежащей в основе языка, библиотек и методов программирования, Eiffel, позволяет создать надежные, многоразовые программные модули. Eiffel поддерживает множественное наследование, универсальность, полиморфизм, инкапсуляцию, типобезопасные преобразования и ковариацию параметров. Самый важный вклад Эйфеля в программного обеспечения - это проектирование по контракту (DbC), в котором утверждение, предварительные условия, постусловия и инварианты классов используются для корректности программы без ущерба для эффективности.

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

Реализации и среды

EiffelStudio - это интегрированная среда разработки, доступная либо по с открытым исходным кодом, либо по коммерческой лицензии. Он предлагает объектно-ориентированную среду для разработки программного обеспечения. EiffelEnvision - это подключаемый модуль для Microsoft Visual Studio, который позволяет пользователям редактировать, компилировать и отлаживать проекты Eiffel из среды Microsoft Visual Studio IDE. Доступны пять других реализаций с открытым исходным кодом: Tecomp "The Eiffel Compiler"; Гобо Эйфель; SmartEiffel, реализация GNU, основанная на более старой версии языка; LibertyEiffel, на основе компилятора SmartEiffel; и Visual Eiffel.

Некоторые другие языки программирования включают элементы, впервые представленные в Eiffel. Sather, например, изначально был основан на Eiffel, но с тех пор разошелся и теперь включает несколько функций функционального программирования. Язык интерактивного обучения Blue, предшественник BlueJ, также основан на Eiffel. Apple Media Tool включает язык Apple Media на основе Eiffel.

Спецификации и стандарты

Определение языка Eiffel является международным стандартом ISO. Стандарт был разработан ECMA International, которая впервые утвердила стандарт 21 июня 2005 г. как Стандарт ECMA-367, Eiffel: язык анализа, проектирования и программирования. В июне 2006 года ECMA и ISO приняли вторую версию. В ноябре 2006 года ISO впервые опубликовала эту версию. Стандарт можно найти и бесплатно использовать на сайте ECMA. Версия ISO идентична во всех отношениях, кроме форматирования.

Eiffel Software, Tecomp "Eiffel Compiler" и разработчик библиотеки Eiffel Gobo взяли на себя обязательство внедрить стандарт; EiffelStudio 6.1 и «Компилятор Eiffel» от Eiffel Software реализуют некоторые из основных новых механизмов, в частности, встроенные агенты, команды присваивания, скобочную нотацию, несоответствующее наследование и присоединенные типы. Команда SmartEiffel отвернулась от этого стандарта, чтобы создать свою собственную версию языка, которая, по их мнению, ближе к оригинальному стилю Eiffel. Object Tools не раскрывает, будут ли будущие версии его компилятора Eiffel стандарту. LibertyEiffel реализует диалект где-то посередине между языком SmartEiffel и стандартом.

Стандарт цитирует следующие предшествующие спецификации языка Eiffel:

  • Бертран Мейер: Eiffel: The Language, Prentice Hall, вторая печать, 1992 г. (первая печать: 1991 г.)
  • Бертран Мейер: Standard Eiffel (редакция предыдущей статьи), текущая, с 1997 г. по настоящее время, на странице Бертрана Мейера в ETL3 и
  • Бертран Мейер: Построение объектно-ориентированного программного обеспечения, Prentice Hall: первое издание, 1988 г.; второе издание, 1997 г.
  • Бертран Мейер: Touch of Class: Обучение правильному программированию с помощью объектов и контрактов, Springer-Verlag, 2009 г. ISBN 978-3-540-92144-8 lxiv + 876 страниц Полноцветная печать, множество цветных фотографий

Текущая версия стандарта от июня 2006 г. содержит некоторые несоответствия (например, ковариантные переопределения). Комитет ECMA еще не объявил никаких сроков и указаний по устранению несоответствий.

Синтаксис и семантика

Общая структура

«система» или «программа» Эйфеля - это совокупность классов. Выше классов Eiffel определяет кластер, который, по сути, представляет собой группу классов и, возможно, подкластеров (вложенных кластеров). Кластеры - это не синтаксическая конструкция языка , а скорее стандартное организационное соглашение. Обычно программа Eiffel организована с каждым классом в отдельном файле, каждый кластер - в каталоге, содержит файлы классов. В этой организации подкластеры - это подкаталоги. Например, согласно стандартным организационным системам, xeможет быть именем файла, который определяет класс с именем X.

Класс содержит функции, которые похожи на «процедуры», «члены», «Атрибуты» или «методы» в других объектно-ориентированных языках программирования. Класс также определяет свои инварианты и содержит другие свойства, такие как раздел «примечания» для документации и метаданных. Стандартные данные Эйфеля, такие как INTEGER, STRINGи ARRAY, сами по себе являются классами.

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

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

Scoping

В отличие от объектов многих объектов, ориентированных на языков, но, как и Smalltalk, Eiffel не разрешает никакого присваивания атрибутам объектов, за исключением характеристик объекта, которые являются практическим выполнение принципа сокрытия информации или абстракции данных, требуемых формальных интерфейсов для мутации данных. Чтобы перевести его на язык других объектно-ориентированных языков программирования, все атрибуты Eiffel являются «защищенными», а для изменения значений клиентскими объектами необходимы «установщики». Результатом этого является то, что «установщики» могут и обычно реализуют инварианты, для которых Eiffel использует синтаксис.

Хотя Eiffel не разрешает прямой доступ к функции класса клиентского класса, он допускает определение «команды назначенного», например:

some_attribute: SOME_TYPE assign set_some_attribute set_some_attribute (v: VALUE_TYPE) - Установить значение некоторого атрибута равным `v '. do some_attribute: = v end

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

В отличие от других языков, имеющих понятие «общедоступный» »,« Защищенный »,« частный »и т. Д., Eiffel использует методы экспорта, чтобы более точно контролировать видимости между классами клиентов и поставщиков. Аналогично слову «защищенный» в других языках. Область применения, примененная таким образом к «набору функций» (например, все, что находится ниже ключевого слова «характеристика» до следующего ключевого слова набора функций или до конца класса), может быть изменено в классах-потомках с помощью ключевого слова «экспорт».

feature {NONE} - Инициализация default_create - Инициализировать новый "нулевой" десятичный экземпляр. do make_zero end

В качестве альтернативы, отсутствие объявления экспорта {x} подразумевает {ЛЮБОЙ} и аналогично "общедоступной" области видимости других языков.

feature - Константы

Наконец, можно выборочно и точно контролировать область видимости для любого класса во вселенной проекта Eiffel, например:

feature {DECIMAL, DCM_MA_DECIMAL_PARSER, DCM_MA_DECIMAL_HANDLER} - Доступ

, компилятор только классам, перечисленным в фигурных скобках, получить доступ к функциям внутри группы функций (например, DECIMAL, DCM_MA_DECIMAL_PARSER, DCM_MA_DECIMAL_HANDLER).

«Привет, мир!»

Внешний вид языка программирования часто передается с помощью программы «Привет, мир!». Такая программа, написанная на Eiffel, может быть:

класс HELLO_WORLD create make feature make do print ("Hello, world!% N") end end

Эта программа содержит класс HELLO_WORLD. Конструктор (процедура создания) для класса с именем makeвызывает системную библиотеку printдля записи "Hello,world! "сообщение на выход.

Дизайн по контракту

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

Компилятор Eiffel разработан для включения контрактов функций и классов на различных уровнях. EiffelStudio, например, выполняет все контракты функций и классов во время выполнения в «режиме Workbench». Когда исполняемый файл создается, компилятор получает указание через файл настроек проекта (например, файл ECF) либо включить, либо исключить любой набор контрактов. Таким образом, исполняемый файл может быть скомпилирован для включения или исключения любого уровня контракта, тем самым непрерывными уровнями модульного и интеграционного тестирования. Более того, контракты могут работать непрерывно и методично с помощью функций автотеста в EiffelStudio.

Механизмы проектирования по объединению интегрированных языков и направляют переопределение функций в наследовании:

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

Кроме того, язык поддерживает «инструкции проверки» (своего рода «утверждение»), инварианты цикла, и варианты цикла (гарантирующие завершение цикла).

Void-security

Void-security, как и статическая типизация, является еще одним средством повышения качества программного обеспечения. Безопасное программное обеспечение защищено от ошибок времени выполнения, вызванных вызовами пустых ссылок, и поэтому будет более надежным, чем программное обеспечение, которое может вызвать вызовы пустых целей. Полезна аналогия со статической типизацией. Фактически, возможность защиты от пустот можно рассматривать как расширение системы типов или шаг за пределы статической типизации, потому что механизм обеспечения защиты от пустот интегрирован в систему типов.

Защиту от недействительных целевых вызовов можно увидеть с помощью понятий присоединения и (по расширению) отсоединения (например, ключевое слово detachable). Возможности void-safe можно увидеть в короткой переработке приведенного выше примера кода:

some_attribute: detachable SOME_TYPE use_some_attribute - Установить значение some_attribute на `v '. do, если some_attribute прикреплен как l_attribute, затем do_something (l_attribute) end end do_something (a_value: SOME_TYPE) - Сделайте что-нибудь с ʻa_value '. делать... делать что-то с ʻa_value '... end

В приведенном выше примере кода показано, как компилятор может статически определять надежность того, будет ли some_attributeприсоединен или отсоединен в точке его использования. Примечательно, что присоединенное ключевое слово допускает «локальное вложение» (например, l_attribute), которое ограничено только блоком кода, заключенным в конструкцию if-statement. Таким образом, в этом небольшом блоке кода можно статически гарантировать, что локальная переменная (например, l_attribute) не является недействительной (то есть является недействительной).

Возможности: команды и запросы

Основная характеристика класса состоит в том, что он определяет набор функций: поскольку класс представляет набор объектов времени выполнения или «экземпляров», особенность - это операция над этими объектами. Есть два типа функций: запросы и команды. Запрос предоставляет информацию об экземпляре. Команда изменяет экземпляр.

Различие между командой и запросом важно для метода Эйфеля. В частности:

  • Принцип унифицированного доступа : с точки зрения программного клиента, выполняющего вызов функции класса, независимо от того, является ли запрос атрибутом (значением поля) или функцией (вычисляемым значением), не должно не имеет значения. Например, a_vehicle.speedможет быть атрибутом, к которому осуществляется доступ кобъекту a_vehicle, или он может быть вычислен функцией, которая делит расстояние на время. Обозначения одинаковы в обоих случаях.
  • Принцип разделения команд и запросов : Запросы не должны проверять экземпляр. Это не языковое правило, методологический принцип. Итак, в хорошем стиле Эйфеля нельзя найти функции «получить», которые что-то меняют и возвращают результат; вместо этого существуют команды (процедуры) для изменения объектов и запросов для получения информации об объекте в результате предыдущих изменений.

Перегрузка

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

Имена, конечно, можно повторно использовать в разных классах. Например функция, плюс (вместе с его инфиксным псевдонимом«+») определена в нескольких классах: INTEGER, REAL, STRING и т. Д..

Универсальность

Универсальный класс - это класс, который различается по типу (например, LIST [PHONE], список номеров телефонов; ACCOUNT [G->ACCOUNT_TYPE], что позволяет использовать ACCOUNT [SAVINGS] и АККАУНТ [ПРОВЕРКА] и т. д.). Классы могут быть универсальными, что означает, что они параметры по типам. Общие параметры заключаются в квадратные скобки:

класс LIST [G]...

G известен как «формальный универсальный параметр». (Эйфель резервирует «аргумент» для подпрограмм и использует «параметр» только для общих классов.) С таким объявлением G представляет внутри класса произвольный тип; поэтому функция может возвращать значение типа G, процедура может принимать аргумент этого типа:

item: G do... end put (x: G) do... end

The LIST [INTEGER]и LIST [WORD]являются «родовыми производными» этого класса. Разрешенные комбинации (с n: INTEGER, w: WORD, il: LIST [INTEGER], wl: LIST [WORD]) это:

n: = il.item wl.put (w)

INTEGERи WORD- «фактические общие параметры» в этих общих производных.

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

HASH_TABLE [G, KEY ->HASHABLE]

вывод HASH_TABLE [INTEGER, STRING]действителен, только если STRINGнаследуется от HASHABLE(как и в типичных библиотеках Eiffel). Внутри класса наличие KEY, ограниченного HASHABLE, означает, что для x: KEYможно применить к xвсе функции HASHABLE, как в x.hash_code.

Основы наследования

Чтобы наследовать от одного или нескольких других классов будет наследовать наследоватьв начало:

класс C наследует AB -... Остальная часть объявления класса...

Класс может переопределить (переопределить) некоторые или все унаследованные функции. Это должно быть явно объявлено в начале класса с помощью подпункта переопределитьв предложении наследования, как в

класс C наследовать A переопределить f, g, h end B переопределить u, v end

См. Полное обсуждение наследования Эйфеля.

Отложенные классы и функции

Классы могут быть определены с отложенным классом, а не с классом, чтобы указать, что класс не может быть создан напрямую. Классы, не поддерживающие создание экземпляров, называются абстрактными классами в некоторых других объектно-ориентированных языках программирования. На языке Эйфеля можно создать экземпляр только «эффективного» класса (он может быть потомком отложенного класса). Функцию также можно отложить, используя слово deferredвместо предложения do. Если у класса есть какие-либо отложенные функции, он должен быть объявлен как отложенный; однако класс без отложенных функций может, тем не менее, отложенным.

Отложенные классы играют примерно ту же роль, что и многие теоретики объектно-ориентированного программирования считают, что интерфейсы сами по себе являются ответом на отсутствие множественных наследования в Java ( которое есть у Эйфеля).

Переименование

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

Кортежи

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

ТУПЛЕ [имя: СТРОКА; вес: РЕАЛЬНЫЙ; дата: DATE]

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

["Brigitte", 3.5, Last_night]

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

Благодаря понятию команда присваивания (см. Ниже), точечная такая нотация также может присвоить компоненты кортежа, как в

t.weight: = t.weight + 0.5

Теги кортежа являются необязательными, поэтому также можно записать тип кортежа как TUPLE [STRING, REAL, DATE]. (Некоторые компиляторах это единственная форма кортежа, поскольку теги были введены в стандарте ECMA.)

Точная спецификация, например, TUPLE [A, B, C]заключается в том, что он является следовать, по меньшей мере, из трех элементов, первые три из системы к типам A, B, Cсоответственно. В результате ТУПЛ [A, B, C]соответствует (может быть назначен) ТУПЛ [A, B], к ТУПЛ [A]и TUPLE(без параметров), самый верхний тип кортежа, соответствуют все типы кортежей.

Агенты

«агентный» механизм Эйфеля превращает операции в объекты. Этот механизм можно использовать для итераций, программы, программы событиями, и других контекстов, в которых используется передача операций по структуре программы. Другие языки программирования, особенно те, которые делают упор на функциональное программирование, допускают аналогичный шаблон с использованием продолжений, замыканий или генераторов ; Агенты Эйфеля подчеркивают объектно-ориентированную парадигму языка и используют синтаксис и семантику, аналогичные блокам кода в Smalltalk и Ruby.

. Например, для выполнения блока my_actionдля каждого элемента my_listможно написать:

my_list.do_all (agent my_action)

Чтобы выполнить my_actionтолько для элементов, удовлетворяющих my_condition, можно добавить ограничение / фильтр:

my_list.do_if (agent my_action, agent my_condition)

В этих примерах my_actionи my_conditionявляются подпрограммами. Добавление к ним префикса агентдает объект, который соответствует соответствующей подпрограмме со всеми ее свойствами, используя вызов с поставщиком аргументами. Итак, если aпредставляет этот объект (например, потому что aявляется аргументом для do_all), инструкция

a.call ([x])

вызовет исходную функцию с аргументом x, как если бы мы вызвали исходную функцию напрямую: my_action (x). Аргументы для вызовпередаются в виде кортежа, здесь [x].

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

my_list.do_all (agent action2 (?, Y))

повторяет action2 (x, y)для принятия значения x, где второй аргумент остается установленным на y. Знак вопроса ?указывает на открытый аргумент; y- закрытый аргумент агента. Обратите внимание, что основной синтаксис agent fявляется сокращением для agent f (?,?,...)со всеми открытыми аргументами. Также возможно сделать цель открытой с помощью записи {T}?, где T- это тип цели.

Различие между открытыми и закрытыми опдами (операнды = аргументы + цель соответствует различию между связанными и свободными переменными в лямбда-исчислении. Выражение агента, такое как action2 (?, Y)с некоторыми закрытыми операндами и некоторыми открытыми, соответствует версии исходной операции curried для закрытых операндов.

Механизм агента также позволяет определять агент без ссылок на существующую подпрограмму (например, my_action, my_condition, action2) через встроенные агенты, как в

my_list.do_all (агент (s: STRING) требует not_void: s / = Void do s.append_character (',') гарантирует добавление: s.count = old s.count + 1 end)

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

my_list.for_all (agent (x: INTEGER): BOOLEAN do Result: = (x>0) end)

Текущий механизм агента оставляет возможность ошибки типа времени выполнения (если процедура с аргументами передается агенту, ожидаемое m аргументов с m valid_argumentsиз call. Доступно несколько предложений по чисто статическому исправлению этой проблемы, в том числе предложение об изменении языка, предложенное Рибетом и др.

Один раз, подпрограммы

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

shared_object: SOME_TYPE после создания Result.make (args) - Создает объект и возвращает ссылку на него через `Result '. end

Возвращаемый объект - Результатв примере - сам может быть изменяемым, но его ссылка остается той же.

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

По умолчанию «однократная процедура» вызывается один раз для каждого потока. Семантику можно настроить на один раз для процесса или один раз на объекте, уточни его с помощью «однократного ключа», например один раз («ПРОЦЕСС»).

Конверсии

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

(Принцип преобразования) Тип не может одновременно соответствовать и преобразовывать в другой.

Например, ГАЗЕТАможет соответствовать PUBLICATION, но INTEGERпреобразуется в REAL(и не наследуется от него).

Механизм преобразования просто обобщает специальные правила преобразования (например, между INTEGERи REAL), которые существуют в большинстве языков программирования, что делает их применимыми к любому типу. пока соблюдается вышеуказанный принцип. Например, класс DATEможет быть объявлен для преобразования в STRING; это позволяет создать строку из даты просто через

my_string: = my_date

в качестве ярлыка для использования явного создания объекта с процедурой преобразования:

create my_string.make_from_date (my_date)

Чтобы первая форма стала синонимом второй, достаточно перечислить процедуру создания (конструктор) make_from_dateв предложении convertв начале класса.

В качестве другого примера, если существует такая процедура преобразования, указанная из TUPLE [день: INTEGER; месяц: STRING; year: INTEGER], тогда можно напрямую присвоить кортеж дате, вызывая соответствующее преобразование, как в

Bastille_day: = [14, "July", 1789]

Обработка исключений

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

Обработчик исключений Eiffel определяется с помощью ключевого слова rescue. В разделе восстановления использовать слово повторить снова выполнение функции. Например, следующая процедура отслеживает количество попыток ее выполнения и повторяет только определенное количество раз:

connect_to_server (сервер: SOCKET) - подключиться к серверу или отказаться от него после 10 попыток. require server / = Void, а затем server.address / = Аннулировать локальные попытки: INTEGER do server.connect sure connected: server.is_connected rescue if пытается < 10 then attempts := attempts + 1 retry end end

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

Параллелизм

Доступен ряд сетевых и потоковых библиотек, таких как EiffelNet и EiffelThreads. Модель параллелизма для Eiffel, основанная на концепции проектирования по контракту, - это SCOOP, или простое параллельное объектно-ориентированное программирование, которое еще не является частным официальным определением языка, но доступно в EiffelStudio. CAMEO - это (нереализованная) вариация SCOOP для Eiffel. Параллелизм также взаимодействует с исключениями. Асинхронные исключения могут вызвать завершение проблемы (когда подпрограмма вызывает исключение после того, как ее вызывающая сторона вызывает проблему, вызывающую проблему).

Синтаксис оператора и скобки, командываивания

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

a + b

, концептуально понимается так, как если бы это был вызов метод

a.plus (b)

с целью a, функция плюси аргумент b.

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

плюс псевдоним "+" (другое: INTEGER): INTEGER -... Обычное объявление функции... end

Диапазон операторов, которые могут быть в качестве псевдонима, широкие; они включают предопределенные операторы, такие как «+», а также «свободные операторы», состоящие из не буквенно-цифровых символов. Это позволяет создать инфиксные и префиксные обозначения, например, в математических и физических приложениях.

Каждый класс может иметь одну функцию с псевдонимом "", оператор "скобки", позволяя обозначение a [i,...]в качестве синонима для af (i,...), где f- выбранная функция. Это особенно полезно для контейнерных структур, таких как массивы, хэш-таблицы, списки и т. Д. Например, для доступа к элементу хеш-таблицы со строковыми ключами можно записать

number: = phone_book ["JILL SMITH"]

"Команды-назначители" - это вспомогательный механизм, позволяющий переосмыслить устоявшиеся и удобные обозначения в рамках объектно- ориентированного программирования. Команды присваивания позволяют схожему с присваиванием синтаксису вызывать процедуры «установщика». Собственно присвоение никогда не может иметь a.x: = v, поскольку это нарушает скрытие информации; вам нужно использовать команду (выбор) установки. Например, класс хеш-таблицы может иметь функцию и функцию

, элемент псевдонима "" (ключ: СТРОКА): ELEMENT [3] - Элемент ключа "key". - ("Получатель" запрос) do... end put (e: ELEMENT; key: STRING) - Вставить элемент ʻe ', связав его с ключом `key'. - (Команда "Setter") do... end

Затем, чтобы вставить элемент, вы должны использовать явный вызов команды setter:

[4] phone_book.put (New_person, "JILL SMITH")

Можно записать это эквивалентно как

[5] phone_book ["JILL SMITH"]: = New_person

(точно так же, как phone_book ["JILL SMITH"]) синоним для number: = phone_book.item ("JILL SMITH")), при условии, что объявление элементатеперь начинается (замена для [3]) с псевдонима элемента

»" (ключ: STRING): ELEMENT assign put

Это объявляет putкак команду назначения, связанную с item, и в сочетании с псевдонимом скобок делает [5] допустимым и эквивалентным к [4]. записать, используя скобки, как phone_book.item ("JILL SMITH"): = New_person.

note: список аргументов назначителя a должен быть: (возвращаемый тип; весь список аргументов a...)

Лексические и синтаксические свойства

Eiffel не чувствителен к регистру. составляют, maKeи MAKEвсе обозначают один и тот же идентификатор. Однако см. «Правила стиля» ниже.

Комментарии вводятся с помощью -(два последовательных тире) и расширяются до конца строки.

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

Нет вложенности объявлений функций и классов. В результате структуры класса Eiffel проста: некоторые предложения уровня класса (наследование, инвариант) и последовательность объявлений функций, все в том же уровне.

Принято группировать функции в «разделах функций» для большей читабельности, при этом стандартный набор тегов появляется в стандартном порядке, например:

class HASH_TABLE [ELEMENT, KEY ->HASHABLE] наследовать возможность ТАБЛИЦА [ЭЛЕМЕНТ] - Инициализация -... Объявления команд инициализации (процедуры / конструкторы создания)... функция - Доступ -... Объявления небулевых запросов о состоянии объекта, например элемент... функция - Отчет о состоянии -... Объявления логических запросов о состоянии объекта, например is_empty... feature - Изменение элемента -... Объявления команд, изменяющих структур, например put... - etc. end

В отличие от сообщества языков программирования с фигурными скобками, Eiffel проводит четкое различие между выражениями и инструкциями. Это соответствует принципу разделения команд и запросов метода Эйфеля.

Соглашения о стилех

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

Хотя язык нечувствителен кру, стандарты стилей предписывают использование заглавных букв для имен классов (LIST) и строчных букв для имен функций (make) и начальные капиталы для констант (Авогадро). Рекомендуемый стиль также предлагает разделение компонентов многословного определения, как в средняя_температура.

Спецификация Eiffel включает рекомендации по отображению текстов программного обеспечения в форматах набора ключевых слов: выделены слова жирным шрифтом, определяемые стандартные параметры и константы - показаны курсивом, комментарии, операторы и знаки препинания - римским, с текстом программы синим, как в настоящей статье, чтобы отличить его от пояснительного текста. Например, «Привет, мир!» приведенная выше программа будет в документации Eiffel, как показано ниже:

class HELLO_WORLD create make feature make do print ("Hello, world!") end end

Интерфейсы для других инструментов и языков

Eiffel является чисто объектно-ориентированный язык, но предоставляет открытую энергию для взаимодействия суру «внешним» программным продуктом на любом другом языке программирования.

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

Хотя прямая связь между Eiffel и C нет, многие компиляторы Eiffel (Visual Eiffel - одно исключение) выводят исходный код C как промежуточный язык для передачи компилятору C для оптимизации и переносимости. Таким образом, они являются примерами транскомпиляторов. Tecomp компилятора Eiffel может выполнять код Eiffel напрямую (как интерпретатор) без прохождения через промежуточный код C или испускать код C, который будет передан компилятору C для получения оптимизированного нативного кода. В.NET компилятор EiffelStudio напрямую генерирует код CIL (Common Intermediate Language). Компилятор SmartEiffel также может выводить байт-код Java.

Ссылки
Внешние ссылки
  • Eiffel Software Веб-сайт компании, представившей Eiffel, был Interactive Software Engineering (ISE).
Последняя правка сделана 2021-05-18 09:25:16
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте