Pull to refresh

Comments 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 довольно сложная композиция функций — хуки и форки

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

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

UFO just landed and posted this here

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


{x@&x>1}    // Это просто filter в haskell

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


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


Не думаю что стоит относиться к APL/K/Q/KDB как к языку программирования, это скорее некая альтернатива Excel


— добавление ---


Думаю может быть стоит сослаться на старую статью об APL: https://habr.com/ru/post/200084/


Но там ближе к J, в котором есть ранг объекта и он учитывается при операциях.
Вообще J намного ближе к APL, там сохранилось гораздо более уникальных концепций: комбинация операторов через форки и хуки, ранги данных, инверсные операции и тд и тп.

UFO just landed and posted this here

Как часто в APL коде? Постоянно. Самый простой пример: 1+vec — немного удобнее чем в хаскеле .map(+1)

UFO just landed and posted this here

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


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

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

Я привел пример с вычислением заявки по товарам, где такой подход хорошо виден — на невекторном языке никто никогда не стал бы так реализовывать алгоритм.
UFO just landed and posted this here
Очень не хватает примеров на всех упомянутых языках, потому что мне кажется, что многие не попадают под приведенное описание векторных языков.
Интересная тема. Я с самого начала изучения программирования интересовался дизайном языков, и одно из первых чего захотелось в С/С++ — возможность «векторной» работы с массивами и 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

Sign up to leave a comment.