Я опытный инженер-программист, начинающий изучать APL, и для того, чтобы лучше понять язык на раннем этапе, я хотел бы понять, почему язык показывает программисту разницу между скалярами и векторами. Насколько я могу судить по моим исследованиям, это только ограничивает гибкость, не давая никакой выгоды, чтобы компенсировать это. В результате код APL загроможден ненужными обходными путями, такими как распутывание, вложение и раскрытие.
Поскольку APL такой причудливый и трудный для чтения язык, я создаю свою собственную вспомогательную библиотеку в APL, чтобы сделать свой собственный APL-подобный интерфейс и отказаться от использования шатких «идиом» в необработанном APL для выполнения повседневных задач. Прежде чем я встрою абстракцию скалярного/векторного различия во всю свою вспомогательную библиотеку, должен ли я знать, какой полезностью я могу пожертвовать, делая это?
Спасибо!
матрицы 2d, векторы 1d, скаляры 0d - зачем обрезать на 1? что будет оцениваться цепью (0)(1)
- простым вектором, таким как 0 1
, или вложенным вектором, таким как (,0)(,1)
?
Я просто не вижу практической пользы от различия между скаляром и вектором. Когда я пишу функции, аргументы которых могут быть векторами, я обнаруживаю, что всегда беру аргументы и преобразовываю их во вложенные векторы, чтобы избежать неожиданного поведения в случае передачи одного скалярного значения. Я абстрагирую различие между ними, потому что я не вижу никакой пользы в сохранении различия. Так что да, я всегда предпочитаю работать с вложенными векторами, такими как (,value1)(,value2) или даже просто (,value1), потому что это делает мой код чище. Я что-то неправильно понимаю?
А что касается согласованности, я нахожу странным, что форма 1 2 3 равна 3, форма 1 2 равна 2, а форма 1 равна нулю.
Форма 1 2 3, равная 3, и форма 1, равная йоте нуля, является синтаксической аномалией APL. Рассмотрим разницу между "c" и "c" в некоторых многословных языках, таких как C#, - здесь существует синтаксис для однозначного различения скаляра "c" с одноэлементным вектором "c". Могло быть реализовано в APL, но не было. Для чисел лучшее, что вы можете сделать, это 1.
В других языках код-гольф обычно не одобряется. В АПЛ это норма.
"Код Гольф"!! Никогда не слышал этого выражения, но оно очень умное. И на самом деле среди знакомых мне APL-игроков код-гольф — это не просто «норма», это на самом деле явная цель. Я предполагаю, что это потому, что когда они только начинали программировать, оперативная память стоила 10 долларов за байт, и это было в то время, когда за 1 доллар можно было купить приличный обед на рабочий день.
Если вы пишете функцию, для которой требуется вектор, я бы предложил вам забывать о возможности того, что входные данные являются скалярными (считайте, что это неопределенное поведение), и заставить абонент преобразовать аргумент в вектор. Это должно быть далеко в меньшинстве (а если это не так, вы делаете что-то не так). Точно так же, как если бы вы написали функцию, принимающую матрицу, вы бы не ожидали, что ей будет задан вектор. Использование скаляра вместо векторов так же странно, как использование вектора вместо матрицы.
Действительно странно, что 1 2 3
и 1 2
являются векторами, но только 1
является скаляром, поэтому, если вам нужна согласованность, не создавайте векторы с нотацией A B C
(также известной как нотация цепочек) и забудьте, что массивы могут быть созданы таким образом полностью. Конечно, фактически я не ожидаю, что вы сделаете это, и я хотел бы, чтобы существовала нотация, которая могла бы одинаково создавать векторы любого размера.
Кроме того, не забывайте, что APL поддерживает массивы с рангом > 1, правильное использование которых является важной частью хорошего написания APL. Скаляры имеют ранг 0 (0-мерные), векторы — 1 (1D), матрицы — 2 (2D) и т. д.
Может быть, упомянуть, что использовать вместо обозначения нити?
Прохладный. Спасибо за руководство. В мире APL, кажется, есть много документации о том, как работает язык, но мало в области лучших практик. Я пришел из мира Java/C#, где практичность и безопасность (т. е. предотвращение ошибок) предпочтительнее приверженности теоретической структуре (какой бы элегантной эта структура ни выглядела на бумаге). Я ищу способы сгладить острые углы и уменьшая вероятность ошибок, которые возникают только спустя долгое время после запуска кода. Тогда спасибо!
Единственное универсальное место, где скаляры действуют иначе, чем любой другой массив рангов (помимо встроенных функций, которые могут требовать все, что угодно) — это
scalar + array
(с любой скалярной функцией, а не только+
), где скаляр повторяется для каждого элемента массива. множество. Что вы подразумеваете под "абстрагироваться от этого"?