A Programming Language

Пример, как выглядел изначальный APL, из книги Айверсона: A Programming Language - 1962 год.
Пример, как выглядел изначальный APL, из книги Айверсона: A Programming Language - 1962 год.

На рубеже 20 века, канадский учёный и программист Кеннет Айверсон, искал удобный способ для записи и обьяснения алгоритмов для своих студентов. В результате этого появился язык известный как APL, изначально представляющий собой графо-символьную нотацию для записи алгоритмов, а затем — как полноценный язык программирования. Его синтаксис стал продолжением математической мысли:

  • Никакого компромисса с машинной логикой — только чистые абстракции

  • Символы = операции, как в математике:  (форма),  (максимум),  (индексы)

  • Векторы и матрицы — базовые типы данных, а не библиотечные надстройки

⍝ Широко известный пример, короткой, но полной программы: 
⍝ вывод всех простых чисел до R
(~T∊T∘.×T)/T←1↓⍳R

Позже появились «упрощённые» версии APL с ASCII-синтаксисом (J, K). Но это уже другие языки — они жертвуют математической элегантностью ради удобства ввода. Настоящий APL — это:

  • Идеальный мост между формулой на бумаге и исполняемым кодом

  • Язык-манифест, где красота решения важнее «понятности» новичкам

  • Язык для тех, кто мыслит математическими абстракциями, а не синтаксисом

  • Не инструмент, а стиль мышления

⍝ Original APL (математическая нотация) vs ASCII-версии:
APL: V ← ⍋M ⍝ Сортировка матрицы
J/K: v =: /: m ⍝ Теряет визуальную связь с математикой

«APL — это алгебра для компьютеров. Если вы думаете, как математик, он станет вашим родным языком».

Хронология:

  • 1957-1962: Разработка нотации в Гарварде (ещё до появления BASIC и широкого распространения Фортрана)

  • 1966: Первая реализация APL на IBM 360 — уже как полноценного языка

  • 1970-е: Пик популярности в науке и финансах (например, в Bell Labs для анализа данных)

  • 1980-1990-е: Закат

Пик популярности (1970-е)

APL переживал расцвет там, где требовалась математическая плотность и интерактивность:

  1. Научные исследования и инженерия

    • Bell Labs: анализ телекоммуникационных данных

    • NASA: расчёты орбит (до появления MATLAB)

    • Финансы: алгоритмическая торговля в банках (например, Morgan Stanley)

  2. Уникальные преимущества

    APL\360 Интерактивный подход
    APL\360 Интерактивный подход
    • Интерактивность: REPL появился в APL на 20 лет раньше, чем в Python

    • Графика: Встроенные возможности визуализации — прообраз современных Jupyter Notebooks

    • Производительность: Оптимизированные операции с массивами (как современный NumPy, но без накладных расходов)

  3. Культовое железо

    IBM 5100, изображение из журнала «Byte» от декабря 1975 
    IBM 5100, изображение из журнала «Byte» от декабря 1975 
    • APL-машина стала драйвером развития персональных компьютеров (IBM 5100)

    • Легендарная APL\360 — первая коммерческая реализация от IBM

«В 1973 году 80% задач анализа данных в Wall Street решались на APL»

APL — это не язык, а «сжатый алгоритм»

Сегодня все говорят о DSL (Domain-Specific Languages). APL — это DSL для математики, созданный в 1960-х.

APL — это плотная символьная упаковка математики. Он создавался не как способ реализации алгоритмов, а как способ их описания.

  • В Python вы пишете как что-то сделать

  • В APL вы описываете что нужно сделать

Примеры

⍝ Умножение матриц
A +.× B

То же в Python:

np.dot(A, B)

Пояснение: +.× — это "внутреннее произведение" (как в линейной алгебре), а не циклы.

⍝ Факториал числа
!5

То же в Python:

math.factorial(5)

Пояснение: ! в APL — это математический символ факториала, а не вызов функции.

⍝ Поиск простых чисел
(2=+⌿0=T∘.|T)/T←⍳100

Тоже на Python:

[n for n in range(1, 101) if all(n % d != 0 for d in range(2, n))]

Пояснение: APL выражает фильтрацию через операции сравнения и редукции.

⍝ Перевернуть строку
⌽'Hello'

Тоже на Python:

"Hello"[::-1]

Пояснение:  — это символ "перевернуть", а не срезы с шагом -1.

⍝ Среднее значение
(+/X) ÷ ⍴X

То же на Python:

sum(X) / len(X)

Пояснение:  — это "форма" (размер), а ÷ — математическое деление.

⍝ Решето Эратосфена
(~T∊T∘.×T)/T←1↓⍳100

То же на Python:

[n for n in range(2, 101) if not any(n % d == 0 for d in range(2, n))]

Пояснение: APL выражает алгоритм через операции с множествами.

⍝ Генерация последовательности Фибонначи
{⍵,+/¯2↑⍵}⍣10 ⊢1 1

Тоже на Python:

a, b = 1, 1
for _ in range(10):
    a, b = b, a + b

Пояснение:  — это оператор "повторить", а ¯2↑ берёт последние 2 элемента.

⍝ Проверка на палиндром
(⌽≡⊢)'racecar'

То же на Python:

s == s[::-1]

Пояснение: ⌽≡⊢ означает "перевёрнутое равно оригиналу".

⍝ Норма вектора (квадратный корень из суммы квадратов)
(+/X*2)*0.5

То же на Python:

math.sqrt(sum(x**2 for x in X))

Пояснение: думаю и так поняли?

⍝ Найти все уникальные элементы, встречающиеся больше 2 раз
{(∪⍵)/⍨2<{≢ ⍵}⌸⍵} arr

Тоже на Python:

from collections import Counter
arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8]
result = [x for x, cnt in Counter(arr).items() if cnt > 2]  
  1. APL:

    • Операторы /⍨ — это математические абстракции.

    • Код отражает логику преобразования данных, а не алгоритм.

    • Пример: (∪⍵)/⍨2<... читается как "уникальные элементы, где частота >2".

  2. Python:

    • Требует явного создания объектов (Counter).

    • Использует императивные конструкции (циклы в виде list comprehension).

    • Пример: [x for x, cnt in ... if cnt>2] — это инструкция по обработке.

⍝ Сортировка матрицы по сумме строк
M[⍋+/M;]

⍝ +/M — сумма каждой строки (+ свертка по / для строк)
⍝ ⍋ — индексы для сортировки
⍝ M[...;] — индексирование строк в нужном порядке

То же на Python:

import numpy as np
sorted_M = M[np.argsort(np.sum(M, axis=1))]
# без numpy, может быть так:

sorted_M = sorted(M, key=lambda row: sum(row))
  1. APL:

    • Описывает действие ("отсортируй по суммам") в одном символе 

    • Не требует явного указания осей (axis=1) или лямбд

    • Работает для любого числа измерений без изменения кода

  2. Python:

    • Требует понимания, что axis=1 — это "по строкам"

    • Нужна внешняя функция (np.argsort)

    • Лямбда или numpy — это уже "как", а не "что"

⍝ Найти обратную матрицу ковариации для данных X
⌹ M +.× ⍉M

APL читается как: Обратная матрица (⌹) от произведения X и Xᵀ.

inv_cov = np.linalg.inv(X.T @ X)

Читается как: Вызови функцию inv из модуля linalg для результата умножения X.T на X.

  1. APL:
    Символы +.× — это прямые математические операции, как в учебнике.
    Нет упоминания "функций" или "методов" — только глаголы (действия).

  2. Python:
    Даже с numpy вы вызываете методы (.T@) и функции (np.linalg.inv), что требует знания API.

Матрицы, векторы и тензоры — родной язык APL

APL изначально заточен под операции с многомерными данными:

  • Матричные преобразования — одна строка вместо циклов

  • Агрегация, свёртки, редукции — без boilerplate-кода

  • Статистика, линейная алгебра — как на бумаге

Пример:

⍝ Умножение матриц в APL:
A +.× B

В NumPy это np.dot(A, B), но APL делает это естественнее и без библиотек.

Пример:

⍝ Количество положительных чисел в столбце
{+/⍵>0}⍤1⊢mat
⍝ Редукция высших рангов (тензоры)
tensor ← 2 3 3⍴⍳18  ⍝ 3D-массив

+/tensor  ⍝ Сумма по последней оси (внутри матриц)

+⌿tensor ⍝ Сумма по первой оси (сложение матриц)

На python можете повторить сами.

Прототипирование быстрее, чем ChatGPT

APL позволяет:

  • Проверить идею за минуты, а не часы

  • Сократить 100 строк Python до 5 символов

  • Думать на уровне математики, а не синтаксиса

⍝ Кластеризация k-средних (упрощённо):
k←3 ⋄ centroids←points[?⍨k] ⋄ {⍵⌷⍨⊂⍋↑⍵}⌺k ⊢ points

Попробуйте сделать это в Python так же быстро и непринуждённо алгебраично.

Так почему APL в тени?

Причины заката (1980–1990-е)

  1. Проблемы маркетинга

    • Dyalog и IBM продвигали APL только для нишевых экспертов

    • Никакой работы над массовым образованием (язык остался «сектой для избранных»)

  2. Технические барьеры

    • Символы: До эпохи Unicode ввод ⍋⍎⌈ требовал специальных терминалов и прочих извращений

    • Нет полноценных open-source сред

  3. Конкуренция

    • MATLAB (1984): Украл научную нишу с более привычным синтаксисом

    • Python + NumPy (1995): Даже при меньшей эффективности выиграл за счёт сообщества

    • Excel: Подкупил бизнес-пользователей «понятностью»

  4. Когнитивное сопротивление

    • Миф: «APL — это только для гениев»

    • Реальность: Язык просто требовал переключения мышления с процедурного на математическое

APL проиграл не потому, что был «плох», а из-за:

  • Отсутствия экосистемы (не было своего PyPI)

  • Когнитивного искажения («Это для избранных»)

  • Иннертности технологий (Unicode появился лишь в 2000-х)

  • Отсутствия толкового маркетинга и образовательных программ

И всё таки главная проблема в маркетинге

  • Dyalog (главный разработчик) не продвигает APL как современный инструмент (на самом деле уже продвигает, но всё ещё недостаточно)

  • IBM вовсе утратил интерес к APL и закрыл свой проект

  • Образовательных курсов по прежнему не хватает

  • Акцент на языке, как способе записи алгоритмов, утерян

  • Символьный синтаксис отпугивает новичков (хотя он логичнее, чем кажется — вспомните первое впечатление об математике или матанализе)

  • Не используется хайп вокруг «AI/ML», хотя APL идеален для быстрой проверки гипотез

«APL — это "как если бы математика стала языком программирования". Его трагедия в том, что мир выбрал "как если бы бухгалтерия стала языком программирования"» 

APL должен быть в mainstream

Этот язык идеален для:

  • Обучения Computer Science (алгоритмы без синтаксического шума)

  • Инженерных расчётов (финансы, биоинформатика, физика)

  • Быстрого прототипирования (превью модели за час, а не за неделю)


APL — это суперсила, которую незаслуженно игнорируют. Если вы устали от многословных языков — попробуйте APL. Возможно, это ваш новый любимый инструмент.

Сейчас понемногу назревает ренесанс APL, благодаря усилиям Dyalog:

  • Бесплатная версия без ограничений, для некоммерческого использования

  • Co-dfns — компилятор подмножества APL для CPU и GPU, частично поддерживается сотрудниками Dyalog

  • Dyalog проводит локальные конференции, которым конечно не хватает размаха

  • Началась поддержка и продвижение opensource инициатив со стороных Dyalog

  • APL Challenge и APL Forge — слегка запоздалый, но всё же отличный способ мотивации. Кстати первый победитель APL Forge, парень написавший "Систему приёма радиолакационных сигналов"

  • В Dyalog есть Adám, который является «Head of Language Design» — он всегда отвечает на stackoverflow на вопросы с тегом «dyalog», даже если вопрос примитивный

  • Появился менеджер пакетов Tatin, начиная с Dyalog APL 19.0 он включён в базовую установку

Где APL и APL-мышление дадут явные преимущества в 2025 году

1. Быстрое прототипирование в AI/ML

Проблема 2025:

  • Время на проверку гипотез в ML сокращается (конкуренция в generative AI, small models)

  • Python-стек (PyTorch + Pandas) требует 100+ строк для базовых экспериментов

Решение APL:

  • Сжатые реализации алгоритмов:

    ⍝ KNN классификация: для каждой точки берём наиболее частый класс среди k ближайших  
    knn←{k⊢↑⊃⍒↑+/¨(⍵∘.-⍺)*2}  
  • Преимущество:

    • Проверить идею за 1 час вместо недели на Python

    • Легко адаптировать под новые математические методы

Сферы:

  • Биоинформатика: Анализ CRISPR-данных (требует работы с разреженными матрицами)

  • Quant-трейдинг: Быстрая проверка рыночных аномалий

2. Edge Computing и IoT

Проблема 2025:

  • Устройства с ограниченными ресурсами (датчики, дроны) требуют лаконичного кода

  • Rust/Go/Zig хороши для продакшена, но медленны для прототипирования

Решение APL:

  • Крошечные прошивки: APL-код компилируется в нативный код через Co-dfns (аналог Zig, но с математическим синтаксисом)

  • Пример для датчика:

    ⍝ Фильтрация шумов (фильтр Калмана):
    ⎕IO←0  ⍝ Индексация с нуля
    
    KalmanFilter ← {
        ⍝ Параметры: F (динамика системы), Q (шум процесса), R (шум измерений)
        (F Q R) ← ⍺⍺
        measurements ← ⍵
        
        ⍝ Инициализация состояния и ковариации
        x ← measurements[0]  ⍝ Начальная оценка состояния
        P ← Q               ⍝ Начальная ковариация
        
        ⍝ Вспомогательная функция для обработки шагов
        Step ← {
            ⍝ 1. Прогноз
            x_pred ← F × x
            P_pred ← (F×P×F) + Q
            
            ⍝ 2. Коррекция
            K ← P_pred ÷ (P_pred + R)  ⍝ Коэффициент Калмана
            x ← x_pred + K × (⍵ - x_pred)
            P ← (1 - K) × P_pred
            
            x  ⍝ Возвращаем новое состояние
        }
        
        ⍝ Применяем ко всем измерениям
        x, Step¨ 1↓measurements
    }
    • В 10 раз меньше кода, чем на С

Сферы:

  • Медицинские импланты: Алгоритмы обработки сигналов ЭЭГ/ЭКГ

  • Автономные дроны: Реал-тайм обработка сенсоров

3. Наука о данных (Beyond Pandas)

Проблема 2025:

  • Pandas не справляется с данными >100 ГБ (медленный, требует кластера)

  • Современные аналоги (Polars, Arrow) — всё ещё сложны для ad-hoc анализа

Решение APL:

  • Встроенные оптимизации:

    • Столбцовые операции без копирования данных (как в Apache Arrow, но без накладных расходов)

    • Пример агрегации 1 млрд строк:

      stats←{(⍴⍵),⌈/⍵,⌊/⍵,+⌿⍵}  
      • Выполняется за секунды даже на ноутбуке.

Сферы:

  • Геномика: Анализ SNP (single nucleotide polymorphisms)

  • Финансы: Обработка тиковых данных без Spark

4. Образование (Computer Science 2.0)

Проблема 2025:

  • Современные курсы учат синтаксису, а не мышлению.

  • Студенты тратят 80% времени на борьбу с типами данных, а не на алгоритмы

Решение APL:

  • Курсы нового типа:

    • Линейная алгебра через +.× (матричное умножение = 3 символа)

    • Теория графов:

      ⍝ Проверка связности (матрица смежности → компоненты):
      connected ← {∧/, 1=∨.∧⍨⍣≡⍵}
      
      ⍝ Вычисление достижимости (∨.∧⍨⍣≡):
      ⍝ - ∨.∧ - это операция "логического матричного умножения":
      ⍝ -- Вместо умножения используется И (∧)
      ⍝ -- Вместо сложения используется ИЛИ (∨)
      ⍝ - ⍨ означает применение операции к матрице с самой собой (A ∨.∧ A)
      ⍝ - ⍣≡ - повторение до достижения фиксированной точки (когда результат перестаёт меняться)
      ⍝ Проверка условий (1=):
      ⍝ - Сравнивает каждый элемент результата с 1
      ⍝ - Получаем матрицу из 1 (истина) и 0 (ложь)
      ⍝ Проверка связности (∧/,):
      ⍝ - , - преобразует матрицу в вектор
      ⍝ - ∧/ - логическое И по всем элементам
      ⍝ - Если все элементы равны 1 → граф связный (возвращает 1)
      ⍝ - Если есть хотя бы один 0 → граф несвязный (возвращает 0)
  • Преимущество:

    • Фокус на математической сути, а не языке

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

Как попробовать APL?

Стикеры с APL-символами для наклейки на клавиатуру, от Dyalog.
Стикеры с APL-символами для наклейки на клавиатуру, от Dyalog.

В данный момент есть 3 основных реализации APL:

  • Dyalog APL (закрытый исходный код, бесплатна для некомерческого использования)

  • GNU APL (opensource, но сильно уступает Dyalog)

  • NARS2000 (представляет больше академический интерес)

Рекомендую начать знакомство с онлайн-интерпретатора Dyalog: https://www.tryapl.com. Там есть и большое количество примеров и краткий туториал.

Дополнительно можно отметить:

Для более глубоко знакомства с внутрянкой APL можно ознакомиться с:

В качестве учебных материалов могу посоветовать:

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

P.S. Лично я использую APL для быстрого прототипирования и проверки идей, а потом переношу алгоритм в код для продакшена на Go/Rust/Zig или SQL.

P.P.S. А вы пробовали APL? Какой ваш любимый пример его использования?

Комментарии (8)


  1. Gromilo
    08.08.2025 08:50

    Дело в том, что сложные инструменты - сложные. А люди любят решать простые проблемы простыми инструментами.

    Правда потом, они продолжают использовать простые инструменты для сложных проблем. Зато все всё понимают.


  1. muhachev
    08.08.2025 08:50

    Апл на нейротяге покатит наверное.


  1. bromzh
    08.08.2025 08:50

    Write-only язык, у которого только одна нормальная реализация - коммерческая? Не очень впечатляет.

    Связь с математикой тут тоже такая себе. Ну вот как A +.× B соотносится с умножением матриц? По-факту, большинство символов надо будет отдельно запомнить, и они либо не имеют ничего общего с математическими обозначениями, либо будут путаться. Потому что, например, как норма вдруг стала (+/X*2)*0.5 , хотя в математике все ее знают как ||x|| .

    Плохие инструменты требуют, чтобы вы думали о них.

    По-моему, отлично подходит к АПЛ


    1. CrazyOpossum
      08.08.2025 08:50

      Потому что, например, как норма вдруг стала (+/X*2)*0.5 , хотя в математике все ее знают как x .

      У вас нотация для произвольной нормы, а у автора описание для Гильбертова пространства.


      1. bromzh
        08.08.2025 08:50

        Да, имеет смысл. Но почему тогда не (A +.× A)*0.5 ? Или √(A +.× A)

        Cамо скалярное произведение тоже почему-то не обозначается одним привычным символом (например\cdot), а выражается через композицию.

        Ну то есть мой тейк в том, что все равно придется учить особенности языка, потому что нифига оно не соотносится с математикой. Так какая разница, писать человекочитаемые a.dot(b) или a.norm() или странные закорючки, которые иногда есть в математике, иногда нет, а иногда есть в математике, но в APL они означают другое...


  1. kmatveev
    08.08.2025 08:50

    При всём моём уважении к APL, эта статья - жуткое LLM-дерьмо с мерзким форматированием и тупейшим повторением "математическая абстракция". Если автор человек, то пусть объяснит, что такое "сортировка матрицы", существование которой он приписывает APL и K.


    1. hypermachine Автор
      08.08.2025 08:50


  1. Trifon_Ivanovitch
    08.08.2025 08:50

    Прочитав статью , вспомнил фразу из фильма «Адъютант его превосходительства»: « Викентий, что это всё значит. И при чем здесь, Юрий»… Хочется задать эти вопросы автору, изменив, Викентий - на имя автора, а имя Юрий - на математика …