Дилан (язык программирования)
Эта статья нуждается в дополнительных ссылок для проверки . ( июнь 2013 г. ) |
![]() | |
Парадигма | мультипарадигмальность : функциональная , объектно-ориентированная |
---|---|
Разработчик | Сообщество открытого исходного кода Apple Computer , Арлекин , Университет Карнеги-Меллона |
Впервые появился | 1992 год |
Стабильная версия | 2022.1
/ 28 ноября 2022 г |
Дисциплина набора текста | Сильная, постепенная. |
Платформа | ИА-32 , x86-64 |
ТЫ | Кросс-платформенный |
Расширения имен файлов | Дилан, пострадал |
Веб-сайт | опендилан |
Основные реализации | |
Опен Дилан , Гвидион Дилан | |
Диалекты | |
инфикс-дилан (также известный как Дилан), префикс-дилан (только исторический) | |
Под влиянием | |
CLOS , АЛГОЛ , Схема , EuLisp | |
Под влиянием | |
Лассо , Питон , Рубин , Юлия [1] |
Dylan — это многопарадигмальный язык программирования , который включает поддержку функционального и объектно-ориентированного программирования (ООП), является динамичным и рефлексивным , обеспечивая при этом модель программирования, предназначенную для поддержки создания эффективного машинного кода, включая детальный контроль над динамическим и статическим поведением. . Он был создан в начале 1990-х годов группой во главе с Apple Computer .
Дилан является производным от Scheme и Common Lisp и добавляет интегрированную объектную систему, полученную из Common Lisp Object System (CLOS). В Дилане все значения (включая числа, символы, функции и классы ) являются объектами первого класса . Dylan поддерживает множественное наследование , полиморфизм , множественную отправку , аргументы ключевых слов , самоанализ объектов, шаблонов на основе макросы расширения синтаксиса и многие другие расширенные функции. Программы могут осуществлять детальный контроль над динамизмом, допуская программы, которые занимают континуум между динамическим и статическим программированием и поддерживают эволюционную разработку (позволяя быстро создавать прототипы с последующим поэтапным уточнением и оптимизацией).
Основная цель дизайна Дилана — создать динамический язык, хорошо подходящий для разработки коммерческого программного обеспечения . Дилан пытается решить потенциальные проблемы с производительностью, вводя «естественные» ограничения на полную гибкость систем Lisp , позволяя компилятору четко понимать компилируемые модули, такие как библиотеки .
Dylan заимствовал большую часть своей семантики из Scheme и других Lisp; некоторые реализации Dylan изначально были построены в существующих системах Lisp. Однако у Дилана синтаксис, подобный ALGOL, вместо префиксного синтаксиса, подобного Lisp.
История [ править ]
Dylan был создан в начале 1990-х годов группой под руководством Apple Computer . В свое время он предназначался для использования с компьютером Apple Newton , но реализация Дилана не достигла достаточной зрелости со временем, и вместо этого Ньютон использовал смесь C и NewtonScript , разработанную Уолтером Смитом. Apple прекратила разработку Dylan в 1995 году, хотя они выпустили «технологическую версию» (Apple Dylan TR1), которая включала расширенную интегрированную среду разработки (IDE).
Две другие группы внесли свой вклад в разработку языка и его реализацию: Harlequin выпустила коммерческую IDE для Microsoft Windows , а Университет Карнеги-Меллона выпустил компилятор с открытым исходным кодом для систем Unix под названием Gwydion Dylan. Обе эти реализации теперь имеют открытый исходный код. Реализация Harlequin теперь называется Open Dylan и поддерживается группой добровольцев Dylan Hackers.
Язык Дилана имел кодовое название «Ральф». Джеймс Хоакин выбрал имя Дилан для «ДИНАМИЧЕСКОГО ЯЗЫКА».
Синтаксис [ править ]
Многие синтаксические особенности Dylan взяты из его наследия Lisp. Первоначально Дилан использовал синтаксис префиксов, подобный Lisp, который был основан на s-выражениях . К тому времени, когда разработка языка была завершена, синтаксис был изменен на синтаксис, подобный АЛГОЛу, с расчетом на то, что он будет более знаком более широкой аудитории программистов. Синтаксис был разработан Майклом Калем. Это очень подробно описано в Справочном руководстве Дилана. [2]
Лексический синтаксис [ править ]
Дилан не чувствителен к регистру . Дилана Лексический синтаксис позволяет использовать соглашение об именах, в котором знаки дефиса (минус) используются для соединения частей многословных идентификаторов (иногда называемых « lisp-case » или « kebab case »). Это соглашение распространено в языках Лисп.
Помимо буквенно-цифровых символов и знаков дефис-минус, Дилан допускает использование в идентификаторах различных небуквенно-цифровых символов. Идентификаторы не могут состоять только из этих небуквенно-цифровых символов. [2] Если есть какая-либо двусмысленность, используются пробелы.
Пример кода [ править ]
Простой класс с несколькими слотами:
определить класс <point> ( <object> )
slot point-x :: <integer> ,
требуемое ключевое слово-init: x: ;
slot point-y :: <integer> ,
требуемое-инициализированное-ключевое слово: y: ;
конечный класс <точка> ;
По соглашению, в именах классов используются знаки «меньше» и «больше», используемые в угловых скобках , например класс с именем <point>
в примере кода.
В end class <point>
оба class
и <point>
являются необязательными. Это верно для всех end
статьи. Например, вы можете написать end if
или просто end
прекратить действие if
заявление.
Чтобы создать экземпляр <point>
:
make ( <точка> , x: 100 , y: 200 )
Тот же класс, переписанный максимально минимальным образом:
определить класс <point> ( <object> )
slot point-x ;
слот точка-y ;
конец ;
Оба слота теперь имеют тип <object>
. Слоты необходимо инициализировать вручную:
пусть p = make ( <точка> );
точка-x ( p ) := 100 ; // или p.point-x := 100;
точка-y ( p ) := 200 ; // или p.point-y := 200;
По соглашению имена констант начинаются с «$»:
определить константу $pi :: <double-float> = 3.1415927 d0 ;
Факториальная функция:
определить функцию факториал ( n :: <integer> ) => ( n! :: <integer> )
case
n < 0 => error ( «Невозможно взять факториал отрицательного целого числа: %d \n « , n );
п = 0 => 1 ;
иначе => n * факториал ( n - 1 );
конец
конец ;
Здесь, n!
и <integer>
это просто обычные идентификаторы.
нет Явного оператора возврата . Результатом метода или функции является последнее вычисленное выражение. Обычно точку с запятой после выражения в возвращаемой позиции оставляют.
Модули и пространство имен [ править ]
Во многих объектно-ориентированных языках классы являются основным средством инкапсуляции и модульности; каждый класс определяет пространство имен и контролирует, какие определения видны извне. Кроме того, классы во многих языках определяют неделимую единицу, которую необходимо использовать как единое целое. Например, используя String
функция конкатенации требует импорта и компиляции всех String
.
Некоторые языки, включая Dylan, также включают отдельное явное пространство имен или систему модулей, которая выполняет инкапсуляцию более общим способом.
В Дилане понятия модуля компиляции и модуля импорта разделены, и классы не имеют к ним никакого отношения. Библиотека определяет элементы , которые следует компилировать и обрабатывать вместе, а модуль определяет пространство имен. Классы могут быть объединены в модули или разделены на них по желанию программиста. Часто полное определение класса не существует в одном модуле, а распространяется на несколько модулей, которые при необходимости собираются вместе. В разных программах могут быть разные определения одного и того же класса, включая только то, что им нужно.
Например, рассмотрим дополнительную библиотеку для поддержки регулярных выражений на String
. В некоторых языках, чтобы функциональность была включена в строки, ее необходимо добавить в строку String
пространство имен. Как только это произойдет, String
класс становится больше, и функции, которым не нужно использовать регулярное выражение, все равно должны «платить» за это увеличением размера библиотеки. По этой причине подобные надстройки обычно размещаются в собственных пространствах имен и объектах. Обратной стороной этого подхода является то, что новые функции больше не являются частью String
; вместо этого он изолирован в собственном наборе функций, которые необходимо вызывать отдельно. Вместо myString.parseWith(myPattern)
, что было бы естественной организацией с точки зрения объектно-ориентированного программирования, что-то вроде myPattern.parseString(myString)
используется, что эффективно меняет порядок.
В Dylan для одного и того же кода можно определить множество интерфейсов, например, метод конкатенации String можно поместить как в интерфейс String, так и в интерфейс «concat», который собирает вместе все различные функции конкатенации из разных классов. Это чаще используется в математических библиотеках, где функции обычно применимы к самым разным типам объектов.
Более практичное использование конструкции интерфейса — создание общедоступных и частных версий модуля, что в других языках включается в качестве дополнительной функции , которая неизменно вызывает проблемы и добавляет синтаксис. Под Диланом каждый вызов функции можно просто поместить в интерфейс «Частный» или «Разработка», а общедоступные функции собрать в Public
. В Java или C++ видимость объекта определяется в коде, а это означает, что для поддержки аналогичного изменения программист будет вынужден полностью переписать определения и не сможет иметь две версии одновременно.
Классы [ править ]
Занятия в Дилане описывают slots
(члены данных, поля, ivar и т. д.) объектов аналогично большинству объектно-ориентированных языков. Весь доступ к слотам осуществляется через методы, как в Smalltalk . Методы получения и установки по умолчанию автоматически генерируются на основе имен слотов. В отличие от большинства других объектно-ориентированных языков, другие методы, применимые к классу, часто определяются вне класса, и поэтому определения классов в Dylan обычно включают только определение хранилища. Например:
определить класс <window> ( <view> )
slot title :: <string> = "untitled" , init-keyword: title: ;
слота позиция :: <точка> , ключевое слово требуемой инициализации: позиция: ;
конечный класс ;
В этом примере класс " <window>
" определено. Синтаксис <имя класса> является лишь соглашением, чтобы имена классов выделялись — угловые скобки являются просто частью имени класса. Напротив, в некоторых языках принято писать заглавную первую букву класса. имя или добавить к имени префикс C или T (например). <window>
наследуется от одного класса, <view>
, и содержит два слота, title
удерживая строку для заголовка окна и position
удерживая точку XY для угла окна. В этом примере заголовку присвоено значение по умолчанию, а позиции — нет. Необязательный синтаксис ключевого слова init позволяет программисту указать начальное значение слота при создании экземпляра объекта класса.
В таких языках, как C++ или Java, класс также определяет свой интерфейс. В этом случае приведенное выше определение не имеет явных инструкций, поэтому на обоих языках считается доступ к слотам и методам. protected
, что означает, что они могут использоваться только подклассами. Чтобы разрешить несвязанному коду использовать экземпляры окон, их необходимо объявить. public
.
В Dylan подобные правила видимости считаются не частью кода, а частью системы модулей/интерфейсов. Это добавляет значительную гибкость. Например, один интерфейс, используемый на ранних этапах разработки, мог объявить все общедоступным, тогда как тот, который использовался при тестировании и развертывании, мог ограничить это. В C++ или Java эти изменения потребуют внесения изменений в исходный код, поэтому люди не будут этого делать, тогда как в Дилане это совершенно не связанная концепция.
Хотя в этом примере оно не используется, Дилан также поддерживает множественное наследование .
Методы и общие функции [ править ]
В Дилане методы не связаны с каким-либо конкретным классом; методы можно рассматривать как существующие вне классов. Как и CLOS, Dylan основан на множественной диспетчеризации (мультиметодах), где конкретный вызываемый метод выбирается на основе типов всех его аргументов. Метод не обязательно должен быть известен во время компиляции, при этом понимается, что требуемая функция может быть доступна или нет в зависимости от предпочтений пользователя.
В Java одни и те же методы будут изолированы в определенном классе. Чтобы использовать эту функциональность, программист вынужден импортировать этот класс и явно обращаться к нему для вызова метода. Если этот класс недоступен или неизвестен во время компиляции, приложение просто не скомпилируется.
В Dylan код изолирован от хранения в функциях . Многие классы имеют методы, которые вызывают свои собственные функции, поэтому они выглядят и работают как большинство других объектно-ориентированных языков. Однако код также может находиться в универсальных функциях , то есть они не привязаны к определенному классу и могут быть вызваны кем угодно. Связывание конкретной универсальной функции с методом в классе осуществляется следующим образом:
определить метод Turn-Blue ( w :: <window> )
w . цвет := $синий ;
конечный метод ;
Это определение аналогично определениям в других языках и, скорее всего, будет заключено в <window>
сорт. Обратите внимание на вызов сеттера :=, который является синтаксическим сахаром для color-setter($blue, w)
.
Полезность универсальных методов становится очевидной, когда вы рассматриваете более «универсальные» примеры. Например, одна общая функция в большинстве языков — это to-string
, который возвращает некоторую удобочитаемую объекту форму. Например, окно может вернуть свой заголовок и позицию в скобках, а строка вернет себя. В Dylan все эти методы можно было собрать в один модуль под названием « to-string
", тем самым удалив этот код из определения самого класса. Если конкретный объект не поддерживал to-string
, его можно легко добавить в to-string
модуль.
Расширяемость [ править ]
Вся эта концепция может показаться некоторым читателям очень странной. Код для обработки to-string
для окна не определено в <window>
? Это может не иметь никакого смысла, пока вы не задумаетесь о том, как Дилан справляется с вызовом to-string
. На большинстве языков [ который? ] когда программа компилируется to-string
для <window>
ищется и заменяется указателем (более или менее) на метод. В Дилане это происходит при первом запуске программы; среда выполнения создает таблицу с подробностями имени метода/параметров и динамически ищет методы с помощью этой таблицы. Это означает, что функция для конкретного метода может располагаться где угодно, а не только в модуле времени компиляции. В конце концов, программисту предоставляется значительная гибкость в том, где размещать свой код, собирая его по линиям классов, где это уместно, и по функциональным линиям, где это не так.
Здесь подразумевается, что программист может добавить функциональность к существующим классам, определив функции в отдельном файле. Например, вы можете добавить проверку орфографии ко всем <string>
s, для которых в C++ или Java потребуется доступ к исходному коду класса строк, а такие базовые классы редко предоставляются в исходной форме. В Дилане (и других «расширяемых языках») метод проверки орфографии можно было добавить в spell-check
модуль, определяющий все классы, к которым он может быть применен через define method
построить. В этом случае фактическая функциональность может быть определена в одной универсальной функции, которая принимает строку и возвращает ошибки. Когда spell-check
модуль скомпилирован в вашу программу, все строки (и другие объекты) получат дополнительную функциональность.
Эппл Дилан [ править ]
Apple Dylan — это реализация Dylan, выпущенная Apple Computer . Первоначально он был разработан для продукта Apple Newton .
Ссылки [ править ]
- ^ Стокел-Уокер, Крис. «Юлия: Язык Златовласки» . Приращение . Полоса . Проверено 23 августа 2020 г. .
- ^ Перейти обратно: а б Андрей Шалит; Дэвид Мун; Орка Старбак (11 сентября 1996 г.). Справочное руководство Дилана . Яблоко Пресс. Аддисон-Уэсли . ISBN 9780201442113 .
Внешние ссылки [ править ]
- Официальный веб-сайт Open Dylan – содержит открытый исходный код, оптимизирующий компилятор Dylan для Unix/Linux, macOS, Microsoft Windows.
- Обзор языка
- Знакомство с Диланом
- Эппл Дилан TR1
- Интерпретатор Марле Дилана — реализация подмножества Дилана, подходящая для начальной загрузки компилятора.
- Дилан в Керли