Иконка (язык программирования) - Icon (programming language)
Парадигма | мультипарадигма : структурированная , ориентированная на текст |
---|---|
Разработано | Ральф Грисволд |
Впервые появился | 1977 |
Стабильный выпуск | 9.5.20 / 13 августа 2020 г .
|
Печатная дисциплина | динамичный |
Веб-сайт | www |
Основные реализации | |
Значок, Jcon | |
Диалекты | |
Юникон | |
Под влиянием | |
SNOBOL , SL5, Алгол | |
Под влиянием | |
Юникон, Python , Goaldi |
Icon - это язык программирования очень высокого уровня, основанный на концепции «целенаправленного выполнения», при котором код возвращает «успех» вместе с допустимыми значениями или «отказ», что указывает на отсутствие достоверных данных для возврата. Успех и неудача данного блока кода используются для направления дальнейшей обработки, тогда как в традиционных языках обычно используется логическая логика, написанная программистом, для достижения тех же целей. Поскольку логика для базовых структур управления часто неявна в Icon, общие задачи могут быть выполнены с помощью менее явного кода.
Иконка была разработана Ральфом Грисволдом после ухода из Bell Labs, где он был одним из основных разработчиков языка SNOBOL . SNOBOL был языком обработки строк с синтаксисом, который по стандартам начала 1970-х считался устаревшим. После переезда в Университет Аризоны он продолжил разработку основных концепций SNOBOL в SL5, но счел результат неудачным. Это привело к значительному обновлению Icon, который сочетает в себе короткий, но концептуально насыщенный код языков, подобных SNOBOL, с более знакомым синтаксисом языков, вдохновленных ALGOL, таких как C или Pascal .
Как и языки, которые вдохновили его, основная область использования Icon - это управление строками и текстовыми шаблонами. Строковые операции часто терпят неудачу, например, найти «the» в «world». На большинстве языков это требует тестирования и ветвления, чтобы избежать использования недействительного результата. В Icon большинство таких тестов просто не требуются, что сокращает объем кода, написанного программистом. Обработка сложных шаблонов может быть выполнена в нескольких строках краткого кода, аналогичного более специализированным языкам, таким как Perl, но с сохранением более функционально-ориентированного синтаксиса, знакомого пользователям других языков, подобных АЛГОЛу.
Icon не является объектно-ориентированным , но в 1996 году было разработано объектно-ориентированное расширение под названием Idol, которое в конечном итоге стало Unicon . Он также вдохновил другие языки, особенно на него повлияли его простые генераторы; Генераторы иконок послужили основным источником вдохновения для языка программирования Python .
История
СНОБОЛ
Первоначальная разработка SNOBOL , задним числом известная как SNOBOL1, была начата осенью 1962 года в отделе исследований программирования Bell Labs . Эти усилия были реакцией на разочарование при попытке использовать язык SCL для манипулирования полиномиальными формулами, символической интеграции и изучения цепей Маркова . SCL, написанный главой отдела Честером Ли, был медленным и имел низкоуровневый синтаксис, что приводило к объемам кода даже для простых проектов. После краткого изучения языка COMIT, Иван Полонский, Ральф Грисволд и Дэвид Фарбер, все члены отдела из шести человек, решили написать свой собственный язык для решения этих проблем.
Первые версии работали на IBM 7090 в начале 1963 года, а к лету были построены и использовались в Bell. Это почти сразу привело к появлению SNOBOL2, в котором был добавлен ряд встроенных функций и возможность связываться с кодом внешнего языка ассемблера . Он был выпущен в апреле 1964 года и в основном использовался в Bell, но также нашел применение в Project MAC . Введение системных функций в основном служило указанием на потребность в пользовательских функциях, что было основной особенностью SNOBOL3, выпущенного в июле 1964 года.
Введение SNOBOL3 совпало с основными изменениями в вычислительном отделе Bell Labs, включая добавление нового мэйнфрейма GE 645, что потребовало бы переписывания SNOBOL. Вместо этого команда предложила написать новую версию, которая будет работать на виртуальной машине , под названием SIL для промежуточного языка SNOBOL, что позволит легко портировать ее на любую достаточно мощную платформу. Это предложение было принято как SNOBOL4 в сентябре 1965 года. К этому времени в августе 1966 года появились планы по значительно улучшенной версии языка. Дальнейшая работа над языком продолжалась до конца 1960-х годов, в частности добавление типа ассоциативного массива в более позднюю версию. , который они назвали таблицей.
SL5 ведет к Icon
Грисволд покинул Bell Labs, чтобы стать профессором Университета Аризоны в августе 1971 года. В то время он представил SNOBOL4 как инструмент исследования.
Синтаксис SNOBOL, первоначально разработанный в начале 1960-х годов, имеет следы других ранних языков программирования, таких как FORTRAN и COBOL . В частности, язык зависит от столбца, поскольку многие из этих языков были введены на перфокартах, где расположение столбцов является естественным. Кроме того, управляющие структуры почти полностью основывались на ветвлении кода, а не на использовании блоков , которые становились обязательной функцией после появления АЛГОЛА 60 . К тому времени, как он переехал в Аризону, синтаксис SNOBOL4 безнадежно устарел.
Грисволд начал работу по реализации лежащей в основе концепции успеха / неудачи SNOBOL с традиционных структур управления потоками, таких как если / тогда. Это стало SL5, сокращенно от «SNOBOL Language 5», но результат был неудовлетворительным. В 1977 году он вернулся к языку, чтобы рассмотреть новую версию. Он отказался от очень мощной системы функций, представленной в SL5, с более простой концепцией приостановки / возобновления и разработал новую концепцию естественного преемника SNOBOL4 со следующими принципами;
- Философско-смысловая основа СНОБОЛ4
- Синтаксическая основа SL5
- Возможности SL5, за исключением механизма обобщенных процедур
Новый язык был первоначально известен как SNOBOL5, но, поскольку он значительно отличался от SNOBOL во всем, кроме лежащей в основе концепции, в конечном итоге потребовалось новое имя. После рассмотрения «s» как своего рода дань уважения «C», но в конечном итоге от него отказались из-за проблем с набором документов с использованием этого имени. Были предложены и отвергнуты серии новых имен; Ирвинг, бард и "TL" для "The Language". Это было в то время, когда Xerox PARC начала публиковать материалы о своей работе над графическими пользовательскими интерфейсами, и термин «значок» начал входить в компьютерный лексикон. Было принято решение сначала изменить имя на «icon», прежде чем окончательно выбрать «Icon».
Язык
Базовый синтаксис
Язык Icon является производным от ALGOL -класса структурированных языков программирования и, таким образом, имеет синтаксис, аналогичный C или Pascal . Icon больше всего похож на Pascal, используя :=
синтаксис для назначений, procedure
ключевое слово и аналогичный синтаксис. С другой стороны, Icon использует фигурные скобки в стиле C для структурирования групп выполнения, и программы запускаются с запуска вызываемой процедуры main
.
Во многих отношениях Icon также имеет общие функции с большинством языков сценариев (а также с SNOBOL и SL5, из которых они были взяты): переменные не нужно объявлять, типы приводятся автоматически, числа можно преобразовывать в строки и обратно автоматически. Другой особенностью, общей для многих языков сценариев, но не для всех, является отсутствие символа окончания строки; в Icon строки, которые не заканчиваются точкой с запятой, заканчиваются подразумеваемой точкой с запятой, если это имеет смысл.
Процедуры - это основные строительные блоки программ Icon. Хотя они используют именование Pascal, они работают больше как функции C и могут возвращать значения; function
в Icon нет ключевого слова.
Целенаправленное исполнение
Одна из ключевых концепций SNOBOL заключалась в том, что его функции возвращали «успех» или «неудачу» как примитивы языка, а не использовали магические числа или другие методы. Например, функция, которая возвращает позицию подстроки в другой строке, является обычной процедурой, встречающейся в большинстве языковых систем времени выполнения ; например, в JavaScript можно найти позицию слова «World» в «Hello, World!», что будет завершено с помощью , что вернет 7. Если вместо этого запросить код, код «потерпит неудачу», поскольку поисковый запрос не появляется в строке. В JavaScript, как и в большинстве языков, это будет обозначено возвращением магического числа, в данном случае -1.
position = "Hello, World".indexOf("World")
position = "Hello, World".indexOf("Goodbye")
В СНОБОЛ такой сбой возвращает специальное значение fail
. Синтаксис SNOBOL напрямую влияет на успешность или неудачу операции, переходя к помеченным участкам кода без написания отдельного теста. Например, следующий код печатает «Hello, world!» пять раз:
* SNOBOL program to print Hello World
I = 1
LOOP OUTPUT = "Hello, world!"
I = I + 1
LE(I, 5) : S(LOOP)
END
Для выполнения цикла LE
для индексной переменной I вызывается оператор «меньше или равно» , и если он S
завершается, то есть I меньше 5, выполняется переход к названной метке LOOP
и продолжается.
Icon сохранил базовую концепцию управления потоком, основанную на успехе или неудаче, но развил язык дальше. Одним из изменений была замена маркированного GOTO
ветвления блочно-ориентированными структурами в соответствии со стилем структурированного программирования, который охватил компьютерную индустрию в конце 1960-х годов. Вторая заключалась в том, чтобы разрешить передачу «отказа» по цепочке вызовов, чтобы целые блоки были успешными или неудачными в целом. Это ключевая концепция языка иконок. В то время как в традиционных языках нужно было бы включать код для проверки успеха или неудачи на основе логической логики, а затем переходить в зависимости от результата, такие тесты и переходы являются неотъемлемой частью кода Icon и не должны быть написаны явно.
Например, рассмотрим этот фрагмент кода, написанный на языке программирования Java . Он вызывает функцию read()
для чтения символа из (ранее открытого) файла, присваивает результат переменной a
, а затем write
передает значение a
другому файлу. В результате один файл копируется в другой. read
в конечном счете закончится символы для чтения из файла, потенциально на самый первый вызов, который оставил бы a
в неопределенном состоянии и потенциально вызвать , write
чтобы вызвать исключение пустого указателя . Чтобы избежать этого, в этой ситуации read
возвращает специальное значение EOF
(конец файла), что требует явной проверки, чтобы избежать write
этого:
while ((a = read()) != EOF) {
write(a);
}
Напротив, в Icon read()
функция возвращает строку текста или &fail
. &fail
не является просто аналогом EOF
, как это явно понимается языком как означающее «остановить обработку» или «выполнить случай отказа» в зависимости от контекста. Эквивалентный код в Icon:
Это означает: «пока чтение не возвращает ошибку, вызовите запись, в противном случае остановите». Нет необходимости указывать тест на магическое число, как в примере Java, это неявно, и результирующий код упрощен. Поскольку успех и неудача передаются по цепочке вызовов, можно встраивать функции в другие, и они останавливаются, когда вложенная функция дает сбой. Например, приведенный выше код можно сократить до:
В этой версии, если read
выходит из строя, write
выходит из строя и while
останавливается. Конструкции ветвления и цикла Icon основаны на успехе или неудаче кода внутри них, а не на произвольном логическом тесте, предоставленном программистом. if
выполняет then
блок, если его «тест» возвращает значение, и else
блок или переходит на следующую строку, если возвращается &fail
. Точно так же while
продолжает вызывать свой блок, пока не получит ошибку. Икона называет это понятие целенаправленным исполнением .
Важно противопоставить концепции успеха и неудачи концепции исключения ; исключения - это необычные ситуации, а не ожидаемые результаты. Неудачи в Icon - ожидаемые результаты; достижение конца файла - это ожидаемая ситуация, а не исключение. Icon не имеет обработки исключений в традиционном смысле, хотя отказ часто используется в ситуациях, подобных исключениям. Например, если читаемый файл не существует, происходит read
сбой без указания особой ситуации. На традиционном языке эти «другие условия» не имеют естественного способа обозначения; могут использоваться дополнительные магические числа, но чаще используется обработка исключений для «выброса» значения. Например, чтобы обработать отсутствующий файл в коде Java, можно увидеть:
try {
while ((a = read()) != EOF) {
write(a);
}
} catch (Exception e) {
// something else went wrong, use this catch to exit the loop
}
В этом случае необходимо два сравнения: одно для EOF и другое для всех остальных ошибок. Поскольку Java не позволяет сравнивать исключения как логические элементы, как в случае с Icon, try/catch
вместо этого должен использоваться длинный синтаксис. Блоки try также приводят к снижению производительности, даже если исключение не генерируется, - распределенные затраты , которых обычно избегает Icon.
Icon использует тот же целевой механизм для выполнения традиционных логических тестов, хотя и с небольшими отличиями. Простое сравнение, например , не означает, «если операции справа оцениваются как истинные», как это было бы в большинстве языков; вместо этого это означает что-то вроде «если операции справа завершились успешно . В этом случае оператор < завершается успешно, если сравнение истинно. Оператор вызывает свое предложение, если выражение выполнено успешно, или следующую или следующую строку, если оно не выполняется. результат аналогичен традиционному if / then в других языках, выполняется if меньше чем . Тонкость заключается в том, что одно и то же выражение сравнения можно разместить где угодно, например:
if a < b then write("a is smaller than b")
if
then
else
if
then
a
b
Другое отличие состоит в том, что <
оператор возвращает свой второй аргумент в случае успеха, что в этом примере приведет к тому, что значение b
будет записано, если оно больше a
, в противном случае ничего не будет записано. Поскольку это не тест сам по себе , а оператор, возвращающий значение, их можно связать вместе, допуская такие вещи, как if a < b < c
общий тип сравнения, который на большинстве языков должен быть записан как соединение двух неравенств, например if (a < b) && (b < c)
.
Ключевым аспектом целенаправленного выполнения является то, что программе, возможно, придется вернуться к более раннему состоянию, если процедура не удалась, и эта задача известна как обратное отслеживание . Например, рассмотрим код, который устанавливает переменную в начальное положение, а затем выполняет операции, которые могут изменить значение - например, это обычное явление в операциях сканирования строки, когда курсор перемещается по строке при сканировании. Если процедура завершается неудачно, важно, чтобы любые последующие чтения этой переменной возвращали исходное состояние, а не состояние, в котором оно было внутренне изменено. Для решения этой задачи, Icon имеет обратимое назначение оператор, <-
и на обратимый обмен , <->
. Например, рассмотрим код, который пытается найти строку шаблона в более крупной строке:
Этот код начинается с перехода i
к 10, начальному местоположению поиска. Однако в случае find
неудачи блок будет отказывать в целом, что приведет к тому, что значение i
будет оставлено равным 10 как нежелательный побочный эффект . Замена i := 10
на i <- 10
указывает, что i
в случае сбоя блока следует сбросить его до предыдущего значения. Это обеспечивает аналог атомарности в исполнении.
Генераторы
Выражения в Icon могут возвращать одно значение, например, x < 5
будут оценивать и возвращать x, если значение x меньше 5, или иначе не получится. Однако Icon также включает в себя концепцию процедур, которые не возвращают сразу успех или неудачу, а вместо этого возвращают новые значения каждый раз при их вызове. Они известны как генераторы и являются ключевой частью языка иконок. Выражаясь языком Icon, оценка выражения или функции производит последовательность результатов . Результирующая последовательность содержит все возможные значения, которые могут быть сгенерированы выражением или функцией. Когда последовательность результатов исчерпана, выражение или функция не выполняется.
Icon позволяет любой процедуре возвращать одно значение или несколько значений, управляемый с помощью fail
, return
и suspend
ключевые слова. Процедура, в которой отсутствует какое-либо из этих ключевых слов, возвращается &fail
, что происходит всякий раз, когда выполнение выполняется до end
процедуры. Например:
Вызов f(5)
вернет 1, но вызов f(-1)
вернется &fail
. Это может привести к неочевидному поведению, например, write(f(-1))
ничего f
не выводится из-за сбоя и приостанавливает работу write
.
Для преобразования процедуры в генератор используется suspend
ключевое слово, которое означает «вернуть это значение и при повторном вызове начать выполнение с этого момента». В этом отношении это что-то вроде комбинации static
концептов C и return
. Например:
создает генератор, который возвращает ряд чисел, начиная с i
и заканчивая a j
, а затем возвращается &fail
после этого. suspend i
останавливает выполнение и возвращает значение i
без переустановки любого государства. Когда другой вызов той же функции выполняется, выполнение начинается с этого момента с предыдущими значениями. В этом случае это заставляет его выполнить i +:= 1
, вернуться к началу блока while, а затем вернуть следующее значение и снова приостановить. Это продолжается до тех пор i <= j
, пока не произойдет сбой, после чего он выходит из блока и вызывает fail
. Это позволяет легко создавать итераторы .
Другой тип генератора-строителя - генератор переменного тока , который выглядит и работает как логический or
оператор. Например:
Кажется, что это говорит «если y меньше, чем x или 5, то ...», но на самом деле это сокращенная форма для генератора, который возвращает значения, пока они не упадут за конец списка. Значения списка «вводятся» в операции, в данном случае <
. Итак, в этом примере система сначала проверяет y <x, если x действительно больше, чем y, она возвращает значение x, тест проходит, и значение y записывается в then
предложении. Однако, если x не больше, чем y, он выходит из строя, и генератор продолжает работать, выполняя y <5. Если этот тест проходит, y записывается. Если y не меньше ни x, ни 5, генератор выходит из строя и выходит из if
строя, выходит из строя и write
не выполняется. Таким образом, значение y будет отображаться на консоли, если оно меньше x или 5, тем самым выполняя назначение логического значения or
. Функции не будут вызываться, если оценка их параметров не будет успешной, поэтому этот пример можно сократить до:
Внутренне генератор - это не просто генератор, or
и его также можно использовать для создания произвольных списков значений. Это можно использовать для перебора произвольных значений, например:
Поскольку списки целых чисел обычно встречаются во многих контекстах программирования, Icon также включает to
ключевое слово для создания специальных генераторов целых чисел:
который можно сократить:
Значок не является строго типизированным, поэтому списки генераторов могут содержать различные типы элементов:
Это записывает 1, «привет» и, возможно, 5 в зависимости от значения x.
Аналогично, оператор конъюнкции , &
используется аналогично логическому and
оператору:
Этот код вызывает ItoJ
и возвращает начальное значение 0, которое присваивается x. Затем он выполняет правую часть конъюнкции, и, поскольку x % 2
он равен 0, он записывает значение. Затем он снова вызывает ItoJ
генератор, который присваивает 1 переменной x, который не работает с правой стороны и ничего не печатает. Результатом является список всех четных целых чисел от 0 до 10.
Концепция генераторов особенно полезна и эффективна при использовании со строковыми операциями и является основной базой для общего дизайна Icon. Рассмотрим indexOf
операцию, используемую во многих языках; эта функция ищет одну строку внутри другой и возвращает индекс ее местоположения или магическое число, если оно не найдено. Например:
s = "All the world's a stage. And all the men and women merely players";
i = indexOf("the", s);
write(i);
Это просканирует строку s
, найдет первое вхождение «the» и вернет этот индекс, в данном случае 4. Строка, однако, содержит два экземпляра строки «the», поэтому для возврата во втором примере альтернативный синтаксис: использовал:
j = indexOf("the", s, i+1);
write(j);
Это указывает ему сканировать, начиная с местоположения 5, поэтому он не будет соответствовать первому экземпляру, который мы нашли ранее. Однако может не быть второго экземпляра «the» - может не быть и первого - поэтому возвращаемое значение indexOf
должно быть проверено по магическому числу -1, которое используется для обозначения отсутствия совпадений. Полная процедура, которая распечатывает местоположение каждого экземпляра:
s = "All the world's a stage. And all the men and women merely players";
i = indexOf("the", s);
while i != -1 {
write(i);
i = indexOf("the", s, i+1);
}
В Icon аналогом find
является генератор, поэтому те же результаты можно получить с помощью одной строки:
Конечно, бывают случаи, когда нужно найти строку после некоторой точки ввода, например, при сканировании текстового файла, который содержит номер строки в первых четырех столбцах, пробел, а затем строку текста. Целенаправленное выполнение можно использовать, чтобы пропустить номера строк:
Позиция будет возвращена, только если "the" появится после позиции 5; в противном случае сравнение не удастся, передайте ошибку на запись, и запись не произойдет.
every
Оператор подобен while
, цикл через каждый пункт , возвращаемый генератором и выход при отказе:
Существует разница между ключом every
и while
; while
переоценивает первый результат до тех пор, пока он не завершится ошибкой, а every
следующее значение получает от генератора. every
фактически вводит значения в функцию аналогично блокам в Smalltalk . Например, приведенный выше цикл можно переписать следующим образом:
В этом случае значения от i до j будут вводиться someFunction
и (потенциально) записывать несколько строк вывода.
Коллекции
Icon включает несколько типов коллекций, включая списки, которые также можно использовать как стопки и очереди , таблицы (также известные как карты или словари на других языках), наборы и другие. Иконка называет их структурами . Коллекции являются неотъемлемыми генераторами и могут быть легко вызваны с помощью синтаксиса Bang. Например:
Используя распространение ошибок, как показано в предыдущих примерах, мы можем комбинировать тесты и циклы:
Поскольку коллекция списков является генератором, это можно упростить с помощью синтаксиса bang:
В этом случае удар write
заставляет Icon возвращать строку текста одну за другой из массива и, наконец, терпит неудачу в конце. &input
является основанным на генераторе аналогом того, read
что считывает строку из стандартного ввода , поэтому !&input
продолжает чтение строк до конца файла.
Поскольку Icon не имеет типа, списки могут содержать любые типы значений:
Предметы могут включать в себя другие конструкции. Для создания более крупных списков Icon включает list
генератор; i := list(10, "word")
формирует список, содержащий 10 копий слова. Как и массивы в других языках, Icon позволяет искать элементы по положению, например weight := aCat[4]
. Включена нарезка массивов , позволяющая создавать новые списки из элементов других списков, например, aCat := Cats[2:4]
создает новый список под названием aCat, который содержит слово «tabby », 2002 .
Таблицы - это, по сути, списки с произвольными индексными ключами, а не целыми числами:
Этот код создает таблицу, в которой в качестве значения по умолчанию для любого неизвестного ключа будет использоваться ноль. Затем он добавляет в таблицу два элемента с ключами «там» и «здесь» и значениями 1 и 2.
Наборы также похожи на списки, но содержат только один член любого заданного значения. Значок включает в ++
себя объединение двух наборов, **
пересечение и --
разницу. Значок включает в себя ряд предопределенных "Cset", набор, содержащий различные символы. Есть четыре стандартных Csets в иконе, &ucase
, &lcase
, &letters
, и &digits
. Новый Csets можно сделать, приложив строку в одинарных кавычках, например, vowel := 'aeiou'
.
Струны
В Icon строки - это списки символов. В виде списка они являются генераторами, поэтому их можно перебирать с помощью синтаксиса bang:
Распечатает каждый символ строки в отдельной строке.
Подстроки можно извлечь из строки, используя спецификацию диапазона в скобках. Спецификация диапазона может возвращать точку на один символ или часть строки. Строки можно индексировать справа или слева. Позиции в строке определяются между символами 1 A 2 B 3 C 4 и могут быть указаны справа −3 A −2 B −1 C 0
Например,
Где в последнем примере показано использование длины вместо конечной позиции
Спецификацию нижних индексов можно использовать как lvalue в выражении. Это можно использовать для вставки строк в другую строку или удаления частей строки. Например:
Сканирование строк
Еще одним упрощением обработки строк является вызываемая с помощью система сканирования?
, которая вызывает функции для строки:
Значок обращается к левой части объекта ?
как к теме и передает его в строковые функции. Напомним, что find
принимает два параметра: текст поиска в качестве первого параметра и строку для поиска во втором параметре. Использование ?
второго параметра является неявным и не требует указания программиста. В обычных случаях, когда несколько функций вызываются последовательно для одной строки, этот стиль может значительно уменьшить длину результирующего кода и улучшить ясность. Сигнатуры функции значка идентифицируют параметр объекта в своих определениях, поэтому параметр может быть поднят таким образом.
Это ?
не просто синтаксический сахар, он также устанавливает «среду сканирования строк» для любых последующих операций со строками. Это основано на двух внутренних переменных &subject
и &pos
; &subject
просто указатель на исходную строку, а &pos
текущая позиция в ней или курсор. В различных процедурах обработки строк в Icon используются эти две переменные, поэтому программист не должен их явно указывать. Например:
произвел бы:
subject=[this is a string], pos=[1]
Для перемещения по сканируемой строке можно использовать встроенные и определяемые пользователем функции. Все встроенные функции будут по умолчанию &subject
и &pos
разрешить синтаксис сканирования для использования. Следующий код запишет все «слова», разделенные пробелами, в строку:
В этом примере представлен ряд новых функций. pos
возвращает текущее значение &pos
. Может быть не сразу очевидно, зачем нужна эта функция, а не просто использовать значение &pos
напрямую; причина в том, что &pos
это переменная, и поэтому она не может принимать значение &fail
, которое может принимать процедура pos
. Таким образом, pos
обеспечивается легкая оболочка &pos
, позволяющая легко использовать целенаправленное управление потоком Icon без необходимости выполнять написанные вручную логические тесты &pos
. В этом случае тестом является «is & pos zero», что при нечетной нумерации расположения строк в Icon является концом строки. Если он не равен нулю, pos
возвращается &fail
, который инвертируется с, not
и цикл продолжается.
many
находит один или несколько примеров предоставленного параметра Cset, начиная с текущего &pos
. В этом случае он ищет пробелы, поэтому результатом этой функции является расположение первого непробельного символа после &pos
. tab
перемещается &pos
в это место, опять же с потенциалом &fail
на случай, например, many
падения с конца струны. upto
по сути является противоположностью many
; он возвращает местоположение непосредственно перед предоставленным ему Cset, которое в примере затем устанавливает &pos
для другого tab
. Чередование также используется для остановки в конце строки.
Этот пример можно сделать более надежным за счет использования более подходящего Cset «разбиения на слова», который может включать точки, запятые и другие знаки препинания, а также другие символы пробелов, такие как табуляция и неразрывные пробелы. Затем этот Cset можно использовать в many
и upto
.
Более сложный пример демонстрирует интеграцию генераторов и сканирования строк в языке.
Критика
Лоуренс Тратт написал статью об Icon, в которой исследовал ее реальные приложения и указал на ряд проблемных областей. Среди них был ряд практических решений, которые исходят из обработки строк, но не имеют большого смысла в других областях. Из их:
Решение об отказе по умолчанию в конце процедур имеет смысл в контексте генераторов, но в меньшей степени в случае общих процедур. Возвращаясь к примеру, указанному выше, write(f(-1))
не будет вывода, чего можно было ожидать. Тем не мение:
приведет к печати 10. Проблема такого рода совсем не очевидна, так как даже в интерактивном отладчике весь код вызывается, но x
никогда не получает ожидаемого значения. Это можно было бы отклонить как одну из тех "ловушек", о которых программисты должны знать на любом языке, но Тратт исследовал множество программ Icon и обнаружил, что подавляющее большинство процедур не являются генераторами. Это означает, что поведение Icon по умолчанию используется только крошечным меньшинством его конструкций, но представляет собой основной источник потенциальных ошибок во всех остальных.
Другой проблемой является отсутствие логического типа данных и обычной логической логики. Хотя система успеха / неудачи работает в большинстве случаев, когда конечной целью является проверка значения, это все же может привести к некоторому странному поведению в, казалось бы, простом коде:
Эта программа напечатает «принято». Причина в том, что тест c
действительно возвращает значение; это значение равно нулю, значение по умолчанию для всех не инициированных в противном случае переменных. Ноль - допустимое значение, значит, if c
успешно. Чтобы решить эту проблему, необходимо сделать тест явным, c == 0
что отвлекает от самодокументируемого кода - неоднозначно, проверяет ли это «с ноль» или «с существует».
Смотрите также
Примечания
использованная литература
Цитаты
Библиография
- Грисволд, Ральф; Грисволд, Мэдж (2002). Язык программирования иконок (третье издание) . Одноранговые коммуникации. ISBN 1-57398-001-3.
- Грисволд, Ральф; Грисволд, Мэдж (март 1993). «История языка программирования иконок». Коммуникации ACM . 23 (3): 53–68.
- Грисволд, Ральф (1981). «13». В Wexelblat, Ричард (ред.). История языков программирования SNOBOL . История языков программирования . Академическая пресса.
- Грисволд, Ральф (2 марта 1996 г.). «Обзор языка программирования иконок; версия 9» . Департамент компьютерных наук Университета Аризоны .
- Тратт, Лоуренс (18 октября 2010 г.). «Опыт использования системы оценки выражений в виде иконок» (PDF) . Материалы 6-го симпозиума по динамическим языкам : 73–80. DOI : 10.1145 / 1869631.1869640 .
внешние ссылки
- Домашняя страница значка
- Устное историческое интервью со Стивеном Уэмплером , Институт Чарльза Бэббиджа , Университет Миннесоты. Wampler обсуждает свою работу над разработкой Icon в конце 1970-х годов.
- Устное интервью истории с Робертом Голдбергом , Институт Чарльза Бэббиджа , Университет Миннесоты. Голдберг обсуждает свое взаимодействие с Грисволдом во время работы над Icon в классе Иллинойского технологического института .
- Устное историческое интервью с Кеннетом Уокером , Институт Чарльза Бэббиджа , Университет Миннесоты. Уокер описывает рабочую среду проекта Icon, свое взаимодействие с Гризуолдом и свою собственную работу над компилятором Icon.
- Страница языка программирования Icon на сайте проекта задач сравнительного программирования Rosetta Code