Dyalog APL
Реализация языка программирования APLОдна из самых популярных реализаций APL, созданная в 1983 году и активно развивающаяся в настоящее время. Реализует стандарт языка ISO8485 и ряд улучшений, включая графический интерфейс пользователя.
Реализация проприетарная, но существуют бесплатные версии для студентов и онлайн-интерпретатор TryAPL для первичного знакомства с языком. Доступны версии для ряда основных платформ.
Одной из особенностей интерпретатора является наличие так называемых D-функций, или динамических функций, позволяющих определять функции (в том числе именованные) в ходе выполнения программы. Определение функции заключается в фигурные скобки { ... }
, левый и правый аргументы функции доступны под именами ⍺
и ⍵
, соответственно. В пределах таких функций можно использовать локальные определения, рекурсивные вызовы (для безымянных функций символ ∇
соответствует вызову функцией самой себя).
Онлайн-интерпретатор TryAPL
Примеры:
Hello, World!:
Пример для версий Dyalog APL 13.1'Hello, World!'
Факториал:
Пример для версий Dyalog APL 13.1Первая строка задает значение индекса первого элемента в списках (в данном случае 0). Вторая строка задает точность при выводе чисел (она должна превышать длину максимального факториала).
Третья строка при чтении справа налево делает следующее:
⍳17
генерирует список из 17 индексов, начинающихся с 0, т.е. 0 … 16.17 / ⊂'!='
генерирует список из 17 строк!=
.⊂
— операторenclose
, который позволяет оперировать строками как скалярами, а не как массивами символов./
— оператор репликации.!⍳17
применяет к каждому элементу списка унарную операцию!
— факториал.,
— бинарная операция конкатенации правого и левого аргументов; после двух конкатенаций выражение принимает значение0 1 2 3 4 ... 15 16 != != ... != 1 1 2 6 24 120 720 5040 40320 362880 ...
, т.е. список чисел, список строк и затем список факториалов.3 17⍴
изменяет форму списка-аргумента, получая из него матрицу из 3 строк и 17 столбцов:┌→─┬──┬──┬──┬──┬───┬───┬────┬─────┬──────┬───────┬────────┬─────────┬──────────┬───────────┬─────────────┬──────────────┐ ↓0 │1 │2 │3 │4 │5 │6 │7 │8 │9 │10 │11 │12 │13 │14 │15 │16 │ ├~─┼~─┼~─┼~─┼~─┼~──┼~──┼~───┼~────┼~─────┼~──────┼~───────┼~────────┼~─────────┼~──────────┼~────────────┼~─────────────┤ │!=│!=│!=│!=│!=│!= │!= │!= │!= │!= │!= │!= │!= │!= │!= │!= │!= │ ├─→┼─→┼─→┼─→┼─→┼──→┼──→┼───→┼────→┼─────→┼──────→┼───────→┼────────→┼─────────→┼──────────→┼────────────→┼─────────────→┤ │1 │1 │2 │6 │24│120│720│5040│40320│362880│3628800│39916800│479001600│6227020800│87178291200│1307674368000│20922789888000│ └~─┴~─┴~─┴~─┴~─┴~──┴~──┴~───┴~────┴~─────┴~──────┴~───────┴~────────┴~─────────┴~──────────┴~────────────┴~─────────────┘
наконец,
⍉
транспонирует эту матрицу так, что в каждой строке находятся три элемента — число, строка-разделитель и факториал числа.
В итоге вывод программы имеет следующий вид:
┌→─┬──┬──────────────┐
↓0 │!=│1 │
├~─┼─→┼~─────────────┤
│1 │!=│1 │
├~─┼─→┼~─────────────┤
│2 │!=│2 │
├~─┼─→┼~─────────────┤
[...25 lines of output ...]
├~─┼─→┼~─────────────┤
│16│!=│20922789888000│
└~─┴─→┴~─────────────┘
Матрица оформлена как таблица с границами между ячейками из-за того, что она содержит boxed строки.
⎕IO←0
⎕PP←18
⍉3 17⍴ (⍳17) , (17 / ⊂'!=') , !⍳17
Числа Фибоначчи:
Пример для версий Dyalog APL 13.1В этом примере используется формула Бине, реализованная через анонимную динамическую функцию. ⋄
— разделитель выражений, т.е. функция состоит из двух выражений, вычисляющихся слева направо. Первое из них вычисляет золотое сечение и ассоциирует его с именем phi
. Второе — вычисляет значение функции через правый аргумент ⍵
. ⌈
— округление вверх.
Поскольку функция унарна и определяется через скалярные функции, ее можно применить к массиву, в данном случае к массиву номеров чисел Фибоначчи от 1 до 16, включительно. Результатом будет массив чисел Фибоначчи:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
{phi←(1+5*0.5)÷2 ⋄ ⌈((phi*⍵) - (1-phi)*⍵)÷5*0.5} 1+⍳16
Факториал:
Пример для версий Dyalog APL 13.1В этом примере факториал числа N
вычисляется как свертка списка чисел от 1 до N
, включительно, при помощи выражения ×/1+⍳
. Анонимная D-функция применяет это выражение к своему правому аргументу и конкатенирует его с самим аргументом и строкой-разделителем. Функция, в свою очередь, применяется к списку чисел от 0 до 16, записанному в столбик (т.е. как двухмерный массив 17x1). Вывод программы выглядит следующим образом:
┌→───────────────────┐
↓0 != 1 │
├+──────────────────→┤
│1 != 1 │
├+──────────────────→┤
│2 != 2 │
├+──────────────────→┤
[...25 lines of output ...]
├+──────────────────→┤
│16 != 20922789888000│
└+──────────────────→┘
⎕IO←0
⎕PP←18
{⍵, '!=', ×/1+⍳⍵}¨17 1⍴⍳17
Числа Фибоначчи:
Пример для версий Dyalog APL 13.1В данном примере используется анонимно D-функция, рекурсивно вызывающая сама себя. Первое выражение функции обрабатывает случай первых двух чисел Фибоначчи, равных единице. Для остальных чисел работает второе выражение, которое вызывает эту же D-функцию (функция ∇
) для меньших значений аргументов и суммирует их. Первая строка ассоциирует массив чисел с переменной fib
и ничего не выводит.
Во второй строке вычисленный массив чисел Фибоначчи выводится в нужном формате: к каждому элементу применяется функция, конкатенирующая его с запятой-разделителем, элементы получившегося массива конкатенируются друг с другом (,/
) и к результату добавляется троеточие. Итоговый вывод этой команды выглядит следующим образом:
1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , 144 , 233 , 377 , 610 , 987 , ...
fib←{⍵≤2:1 ⋄ (∇⍵-1)+∇⍵-2}¨1+⍳16
(⊃(,/{⍵, ', '}¨fib)),'...'
Квадратное уравнение:
Пример для версий Dyalog APL 13.1В этом примере определяется именованная D-функция, которая принимает коэффициенты уравнения как один параметр — массив из трех элементов и выводит решение уравнения. Вначале параметр разбирается на отдельные коэффициенты, и им присваиваются имена (N⊃⍵
выбирает N-ый элемент массива). Затем выполняются проверки первого коэффициента и дискриминанта, по которым функция может вернуть нетипичное решение. Наконец, оба случая ненулевого дискриминанта обрабатываются одним и тем же кодом благодаря тому, что в APL есть встроенные комплексные числа. Например, вызов функции
solve 1 0 2
возвращает следующие значения:
0J1.4142135623730951 0J¯1.4142135623730951
(J
— разделитель действительной и мнимой частей числа, ¯
— “высокий” минус, использующийся для ввода/вывода отрицательных чисел).
Отметим, что данный код является нетипичным для APL из-за использования условного ветвления, а также из-за того, что механизм использования аргумента ограничивает диапазон его возможных значений до одномерного массива из трех элементов.
solve←{A←0⊃⍵ ⋄ B←1⊃⍵ ⋄ C←2⊃⍵ ⋄ A=0:'Not a quadratic equation.' ⋄ D←(B*2)-4×A×C ⋄ D=0:-0.5×B÷A ⋄ ((-B-D*0.5), -B+D*0.5)×0.5÷A}
Комментарии
]]>blog comments powered by Disqus
]]>