Как стать автором
Обновить

Комментарии 25

J — сохранил APL-подобность языка. Довольно интересная академическая штука.
Форк K/Q — потерял большую часть APL, и стал больше напоминать что-то типа Scheme, о чём говорит упоминание fold, который не векторизуется в общем виде. Как язык — K/Q, к сожалению, застрял 30 лет назад.

А что скажете о Dialog APL?

На Dyalog APL — я начал смотреть, но, к сожалению, далеко не копал. Меня больше заинтересовал IBM APL/2, в который тогда пытались добавить подобие толи статической типизации или просто кастомный типы, к сожалению что именно привлекло внимание к APL/2 я сейчас точно найти не могу.

Это верно, K/Q чем-то очень похожи на лисп, но fold я использовал потому, что это самое популярное имя для подобной функции в ФЯ. Q как раз сильно развился, но в сторону практичности (бизнесовости) и идеологии — любое выражение должно быть осмысленным и возвращать что-то полезное.

Q появился исключительно под давлением менеджмента, Артур не очень хотел это делал — и Kdb/Q накидали самым быстрым способом. Но, имхо, что намного хуже — Q заменил K. Он не выполняет никаких положительных дел, кроме как быть "красивым лицом для K", но значительно уступает K в выразительности, удобстве и лаконичности.

Часто приводится следующий пример сортировки, выглядящий как бессмысленный набор знаков

Таки да!

Тут скорее просто незнание словаря. Вероятно, если бы вы не знали значение английских слов, то и языки основной группы казались бы непонятной мешаниной. Хотя тут надо бы разделить — Q значительно проще чем J, в J довольно сложная композиция функций — хуки и форки

НЛО прилетело и опубликовало эту надпись здесь
Функциональный язык — это слишком общее понятие. Лисп тоже очень сильно отличается от Хаскеля по стилю. Векторные языки функциональны в том смысле, что программа состоит из коротких функций, как правило без сторонних эффектов, и функции равноправный тип данных.
НЛО прилетело и опубликовало эту надпись здесь

Это прежде всего перегрузка операций для работы с векторами и предпочтительное их использование, так как в этих интерпретаторах цикл довольно накладно вызывать

НЛО прилетело и опубликовало эту надпись здесь

Немного не понимаю что такое осмысленная перегрузка, но давайте попробую.


{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)

НЛО прилетело и опубликовало эту надпись здесь

(+):: Int -> Int -> Int
(+):: Int -> [Int] -> [Int]
(+):: [Int] -> [Int] -> [Int]


это не перегрузка по типу параметра? Видимо у нас разное понимание этого слова

НЛО прилетело и опубликовало эту надпись здесь
В векторных языках большинство операций (особенно базовых) применяются к массивам. В других языках мы думаем в терминах отдельных значений — спускаемся по циклам и т.п. к ним и там уже работаем с ними. Этот способ мышления нам гораздо привычнее — типа взяли чайник, налили воды, поставили на плиту. Все операции с простыми объектами. В векторном языке мы берем 1000 чайников, где пусто, наливаем воду, а может просто наливаем воду не обращая внимания, есть она или нет. Как-то ставим на плиту и т.д. Операции сразу над множеством объектов.

Я привел пример с вычислением заявки по товарам, где такой подход хорошо виден — на невекторном языке никто никогда не стал бы так реализовывать алгоритм.
НЛО прилетело и опубликовало эту надпись здесь
Очень не хватает примеров на всех упомянутых языках, потому что мне кажется, что многие не попадают под приведенное описание векторных языков.
Интересная тема. Я с самого начала изучения программирования интересовался дизайном языков, и одно из первых чего захотелось в С/С++ — возможность «векторной» работы с массивами и compile-time группами объектов. Типа такого:
{i,j,k}={1,2,3};
{i,j,k}++;

Но вот с рассматриваемым вами языками я не знаком.
В основном в современных языках эта тема связана с кортежами, множественным возвратом из функций и множественным присваиванием, но дальше этого обычно не заходит. А тут оказывается есть целый мир, в котором языковые дизайнеры уже достаточно далеко продвинулись.
Посмотрите на Clojure. Приведенные вами типы примеров там сделаны лучше, чем где либо.

(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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий