Comments 25
J — сохранил APL-подобность языка. Довольно интересная академическая штука.
Форк K/Q — потерял большую часть APL, и стал больше напоминать что-то типа Scheme, о чём говорит упоминание fold, который не векторизуется в общем виде. Как язык — K/Q, к сожалению, застрял 30 лет назад.
А что скажете о Dialog APL?
Q появился исключительно под давлением менеджмента, Артур не очень хотел это делал — и Kdb/Q накидали самым быстрым способом. Но, имхо, что намного хуже — Q заменил K. Он не выполняет никаких положительных дел, кроме как быть "красивым лицом для K", но значительно уступает K в выразительности, удобстве и лаконичности.
Часто приводится следующий пример сортировки, выглядящий как бессмысленный набор знаков
Таки да!
Это прежде всего перегрузка операций для работы с векторами и предпочтительное их использование, так как в этих интерпретаторах цикл довольно накладно вызывать
Немного не понимаю что такое осмысленная перегрузка, но давайте попробую.
{x@&x>1} // Это просто filter в haskell
В данном случае > перегружена для вектора — она не делает сравнение числа, а генерирует булевый вектор, на основании которого потом выбираются числа.
Понятное дело что подобное можно изобразить практически в любом современном языке, однако мало кто будет сразу делать это через бинарый вектор.
Не думаю что стоит относиться к APL/K/Q/KDB как к языку программирования, это скорее некая альтернатива Excel
— добавление ---
Думаю может быть стоит сослаться на старую статью об APL: https://habr.com/ru/post/200084/
Но там ближе к J, в котором есть ранг объекта и он учитывается при операциях.
Вообще J намного ближе к APL, там сохранилось гораздо более уникальных концепций: комбинация операторов через форки и хуки, ранги данных, инверсные операции и тд и тп.
Как часто в APL коде? Постоянно. Самый простой пример: 1+vec — немного удобнее чем в хаскеле .map(+1)
Я привел пример с вычислением заявки по товарам, где такой подход хорошо виден — на невекторном языке никто никогда не стал бы так реализовывать алгоритм.
{i,j,k}={1,2,3};
{i,j,k}++;
Но вот с рассматриваемым вами языками я не знаком.
В основном в современных языках эта тема связана с кортежами, множественным возвратом из функций и множественным присваиванием, но дальше этого обычно не заходит. А тут оказывается есть целый мир, в котором языковые дизайнеры уже достаточно далеко продвинулись.
(def v1 [1 2 3]) ;; определение вектора v1
определим операцию ++, которой нет в языке как (def ++ (partial mapv inc))
[i j k] v1 ;; "деструктуризация" (без let) вектора v1 в виде i j k, т.е. {i,j,k}={1,2,3};
(++ [i j k]) ;;=> [2 3 4]. а тут применение ++ к i j k {i,j,k}++;
После Лиспов, в особенности Clojure, трудно найти более лаконичный и законченный дизайн языка, а также более совершенную работу с коллекциями.
Clojure все это имеет только с читаемым синтаксисом, иммутабельными и lazy коллекциями ивозможностью писать код в runtime(что вообще есть кульминация языка).)
Добрый день! В практическом примере есть небольшая опечатка:
// выполняем заказ, когда числа становятся отрицательными, он выполнен
45 -\fold 30 23 20 22 -> 15 -10 -30 -52
Должно быть вот так:
// выполняем заказ, когда числа становятся отрицательными, он выполнен
45 -\fold 30 25 20 22 -> 15 -10 -30 -52
Векторные языки — параллельный мир