Из того же семейства что и APL, A+, J.
Сайт производителя.
Краткое
введение в язык (на буржуйском) и даже с картинками.
Обширная статья о нём:
A Shallow Introduction to the K Programming Language.
С "сурьёзностью" у языка "усё-у-порядке": в списке клиентов сплошь банки да Уолл-стриты. Скорость исполнения зашкаливает. Краткость на уровне алгоритма zip (программы усыхают где-то на порядок, на два). Правда из-за этого и выглядят программы на нём очень безизбыточно, как алфавитно-цифровой мусор.
Дистрибутив так просто не скачать, надо их об этом вежливо попросить в личном обращении по электронной почте с
этой странички.
Вот, накропал тут некоторую самоописательную вводную в язык:
Код:
2+2
/ вывод: 4
2+(1 2)
/ вывод: 3 4
/ можно и без скобок, тоже самое (в K справа налево):
2+1 2
/ вывод: 3 4
fact:{*/1+!x} / факториал x
/ fact -- функция. Тело её в фигурных скобках.
/ Через использованный x подразумевается что у функции есть один аргумент.
/ !x -- сделать список натуральных чисел от 0 до x-1
/ 1+!x -- прибавить к каждому элементу этого списка 1
/ */ -- умножение с модификатором, заставляет операцию встревать между
/ всеми поочерёдными элементами ряда:
/ */(1 2 3) означает 1*2*3
/ */1+!x -- перемножить между собой все элементы списка
/ проверка:
fact(3)
/ вывод: 6
/ можно без скобок:
fact 3
/ вывод: 6
fact' !10
/ выводит десять первых факториалов: 1 1 2 6 24 120 720 5040 40320 362880
/ !10 -- создаёт ряд натуральных чисел от 0 до 9
/ fact' -- для каждого элемента ряда применяет новосозданную функцию fact
isprime:{&/x!/:2_!x}
/ функция простейшей проверки на простое число.
/ !x -- ряд чисел
/ 2_!x -- убираем из этого ряда два первых элемента, то есть 0 и 1,
/ получается [2, ..., x-1]
/ !/: -- в этом случае ! означает уже определение остатка от деления, а /:
/ является модификатором действия, означающим множественное применение
/ правого операнда.
/ x!/:2_!x -- Операция у нас -- ! то есть определение остатка от деления.
/ Слева операнд только один -- само число x. Справа образовался ряд чисел.
/ Модификатор заставляет выполнять операцию для каждого элемента второго
/ операнда, сохраняя при этом первый операнд таким же.
/ После этой операции мы должны получить (для x=6):
/ ( (6 mod 5) (6 mod 4) (6 mod 3) ) => ( 1 2 0 )
/ &/ -- a&b находит минимум между двумя числами, поэтому в сочетании с
/ модификатором / & вычисляет минимум ряда.
/ &/x!/:2_!x находит минимум в этом ряду образованном остатками. Если это 0,
/ значит число x всё-таки на что-то поделилось нацело. Если минимум равен 1,
/ значит число -- простое, и ни на что не поделилось.
/ Обратите внимание на "в лоб"-овость реализации. Алгоритм выражается на
/ человеческом языке так: "чтобы проверить простое число или нет, надо
/ попробовать поделить его на что только можно, если на что-то оно поделится
/ без остатка, значит оно простое". На K эта фраза выглядит так:
/ isprime:{&/x!/:2_!x}
primes:{&isprime'!x} / выдаёт все простые числа, меньшие x
/ isprime'!x -- те кто не спал, читая предыдущие заметки, уже должны понять
/ что эта последовательность выдаст ряд нулей и единиц которые соответствуют
/ простоте их индекса. То есть isprime'!20 выдаст:
/ 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1
/ теперь нам чтобы превратить эти нули-единички в нужный нам набор чисел
/ надо использовать магическую функцию & . Нет, это уже другая функция &, не
/ та что использовалась в isprime. Там & был бинарный, а здесь он унарный,
/ у него только один операнд -- наш массив единиц и нулей. В этом случае
/ функция & делает очень интересную вещь: проходит по каждому элементу ряда,
/ и пишет в выходной ряд номер индекса каждого элемента столько раз сколько
/ стоит в соответствующей позиции ряда. То есть: &1 2 3 делает 0 1 1 2 2 2.
/ И так как наш ряд состоит только из нулей и единиц, то в результате мы
/ имеем список индексов ряда у которых значение было 1 (ведь нулевые элементы
/ в результат вообще не записались). А вспоминая, что значения в этом ряду
/ проставляются в зависимости от простоты индекса понимаем что получаем то
/ что дано в описании функции.
Кроме продемонстрированных в коде особенностей: заточенность на обработку массивов, модификаторов действий, отсутствие циклов язык K имеет также зависимые переменные и K-tree, который дико напоминает на первый взгляд Фортовые контекстных словари. Но, так как K (в отличии от Форта) -- язык полностью интерпретируемый, то контекст по идее, должен играть роль не при компиляции определений (которой нет), а непосредственно при исполнении.
Обязательно перенесу что-нибудь из его элементов в Форт. Собственно
уже.
Крутятся всякие мысли по реализации модификаторов...