APL vs MatLab
Курс программирования на УБЗ. Глава 5. Часть 1. A Programming Language или Уроки Практической Магии.
Удивительно, но я не только не знал до сих пор APL, но и услышал о нём, мне кажется, впервые. Хотя, как можно было не выучить язык, на котором программа выглядит следующим образом:
(((1,A)/B)⌊1+⍴Y)[(⍴Y)↓(+\1,A←(1↓A)≠¯1↓A←A[B])[⍋B←⍋A←Y,X]]
Удивительно ещё и из-за того, что (судя по первой части описания) язык очень похож на MatLab, с которым я работаю каждый день. MatLab сильно проигрывает в моих глазах зацикленностью на символах латинского алфавита, за счёт чего получается некая многословность. А функциональность пока что совпадающая.
1. «⍳x» — это, очевидно, «1 : x». Даже «⍳0» эквивалентно «1 : 0» в том смысле, что оба возвращают «ничто». От себя замечу, что в Матлабе не бывает просто «ничего», оно всегда размерное. Данное ничего имеет размерность 1×0, оно так и называется «1×0 empty double row vector». Для удобства пользователя есть отдельная функция empty, позволяющая создать пустоты разного размера, например, double.empty(0, 0, 1, 2) создаёт пустую матрицу 0×0×1×2.
2. «⍴» - это MatLab’овский repmat. Отличие от APL в том, что приходится явно указывать, сколько раз плодить исходную матрицу в каждом из измерений — поскольку просто «пустоты» не бывает.
3. Минимум и максимум, конечно же, пишутся min и max. Небольшое отличие от примера из первой главы APL в том, что они снова ищут минимумы и максимумы вдоль одного из измерений (по умолчанию первого, но, к сожалению, есть нюансы). То есть, min возвращает матрицу той же размерности, что исходная, за исключением размерности, по которой проходил поиск, где размерность будет равняться 1. Т.о. min(0 : 1) вернёт ничего размерности 1×0.
4. Но нельзя же работать без самого большого и самого маленького чисел, для них в MatLab есть специальные литеры: Inf и -Inf. А в добавок ещё и eps — это тоже «самое маленькое число», но в другом смысле: это самое близкое к нулю число, которое ещё отличается от нуля (на моей машине это 2,22e-16).
5. Унитарный вариант «⍴» — это буквальный аналог MatLab’овского size. Хотя нет, аналог не полный — из каких-то своих соображений size никогда не возвращает скаляр. Даже для скаляра он возвращает вектор из двух элементов — действительно, скаляр эквивалентен матрице 1×1. Но он же эквивалентен и матрице 1×1×1×1×1×1. Очевидно, на двух измерениях остановились в силу каких-то исторических причин (в языке полно рудиментов, когда первые два измерения трактуются отлично от следующих).
Конечно, редкая программа на MatLab помещается в одну строчку (у нас кода на 4MB), но это не мешает мне любить свою работу. Но клавиатура как в статье УБЗ мне не помешала бы :-)
Удивительно, но я не только не знал до сих пор APL, но и услышал о нём, мне кажется, впервые. Хотя, как можно было не выучить язык, на котором программа выглядит следующим образом:
(((1,A)/B)⌊1+⍴Y)[(⍴Y)↓(+\1,A←(1↓A)≠¯1↓A←A[B])[⍋B←⍋A←Y,X]]
Удивительно ещё и из-за того, что (судя по первой части описания) язык очень похож на MatLab, с которым я работаю каждый день. MatLab сильно проигрывает в моих глазах зацикленностью на символах латинского алфавита, за счёт чего получается некая многословность. А функциональность пока что совпадающая.
1. «⍳x» — это, очевидно, «1 : x». Даже «⍳0» эквивалентно «1 : 0» в том смысле, что оба возвращают «ничто». От себя замечу, что в Матлабе не бывает просто «ничего», оно всегда размерное. Данное ничего имеет размерность 1×0, оно так и называется «1×0 empty double row vector». Для удобства пользователя есть отдельная функция empty, позволяющая создать пустоты разного размера, например, double.empty(0, 0, 1, 2) создаёт пустую матрицу 0×0×1×2.
2. «⍴» - это MatLab’овский repmat. Отличие от APL в том, что приходится явно указывать, сколько раз плодить исходную матрицу в каждом из измерений — поскольку просто «пустоты» не бывает.
3. Минимум и максимум, конечно же, пишутся min и max. Небольшое отличие от примера из первой главы APL в том, что они снова ищут минимумы и максимумы вдоль одного из измерений (по умолчанию первого, но, к сожалению, есть нюансы). То есть, min возвращает матрицу той же размерности, что исходная, за исключением размерности, по которой проходил поиск, где размерность будет равняться 1. Т.о. min(0 : 1) вернёт ничего размерности 1×0.
4. Но нельзя же работать без самого большого и самого маленького чисел, для них в MatLab есть специальные литеры: Inf и -Inf. А в добавок ещё и eps — это тоже «самое маленькое число», но в другом смысле: это самое близкое к нулю число, которое ещё отличается от нуля (на моей машине это 2,22e-16).
5. Унитарный вариант «⍴» — это буквальный аналог MatLab’овского size. Хотя нет, аналог не полный — из каких-то своих соображений size никогда не возвращает скаляр. Даже для скаляра он возвращает вектор из двух элементов — действительно, скаляр эквивалентен матрице 1×1. Но он же эквивалентен и матрице 1×1×1×1×1×1. Очевидно, на двух измерениях остановились в силу каких-то исторических причин (в языке полно рудиментов, когда первые два измерения трактуются отлично от следующих).
Конечно, редкая программа на MatLab помещается в одну строчку (у нас кода на 4MB), но это не мешает мне любить свою работу. Но клавиатура как в статье УБЗ мне не помешала бы :-)
no subject
Погоди, то ли ещё будет во второй части!
no subject
мои коллеги любят говорить про прекрасные языки white space и brainfuck:)
no subject
А то вот еще Перл, говорят, немногословный язык в котором любая комбинация символов имеет смысл. Да и в С со звездочками и скобками можно далеко заплутать.
no subject
Вотъ рѣшенiе задачи 8 ферзей:
queens =
%np+~command.options.&h.keyword.&iNC; -+
~&iNC+ file$[contents: --<''>+ %nLP*=; * '<'%='[ '+ ','%=', '+ '>'%=' ]']+ ~&rSSs+ nleq-<&l*rFlhthPXPSPS,
~&i&& ~&lNrNCXX; ~&rr->rl %tLnLtXLLWXMk+ ^/~&l ~&lrrhrSiF4E?/~&rrlPlCrtPX ~&r; ^|/~& ^|T\~& -+
-<&l^|*DlrTS/~& ~&iiDlSzyCK9hlPNNXXtCS,
^jrX/~& ~&rZK20lrpblPOlrEkPK13lhPK2; ~&i&& nleq$-&lh+-,
^/~&NNXS+iota -<&l+ ~&plll2llr2lrPrNCCCCNXS*=irSxPSp+ ^H/block iota; *iiK0 ^/~& sum+-
Вотъ рѣшенiе головоломокъ "судоку":
sudoku =
~command.files; <.file$[contents: --<''>]>+ *= ~contents.&F; * -+
~&rSL+ (psort (nleq+)* <~&blrl,~&blrr>)+ ~&arg^& -+
~&al?\~&ar ~&aa^&~&afahPRPfafatPJPRY+ ~&farlthlriNCSPDPDrlCS2DlrTS2J,
^|J/~& ~&rt!=+ ^= ~&s+ ~&H(
-+.|=&lrr;,|=&lrl;,|=≪+-,
~&rgg&& ~&irtPFXlrjrXPS; ~&lrK2tkZ2g&& ~&llrSL2rDrlPrrPljXSPTSL)+-,
//~&p ^|DlrDSLlrlPXrrPDSL(~&,num*+ rep2 block3)*= num block27 ~&iiK0 iota9,
* `0?=\~&iNC ! ~&t digits+-
Тамъ тоже есть "iota", однако, превращать ее въ особый символъ совершенно не требуется. Язык и такъ достаточно кратокъ.
no subject
no subject
no subject
no subject
no subject
Краткость ради краткости мне наоборот не нравится. Когда я писал на perl, я там нарочно переобозначал все эти доллары-точки на длинные, но читаемые названия, и ни в коем случае не использовал анонимные переменные типа "результат последней операции". Это как раз мне кажется уродством. Равно как и ваш вот ужас - не возникает даже желания искать там какую-то структуру. Типичный Base64 :-)))
no subject
Именно поэтому так полезен УБЗ. Вроде пишешь всем известные вещи - ан нет, это иллюзия.
А это ты там в мессенджере написал, что хочешь в оффлайне делать лекции ? (Я там запутался уже, он не показывает, кто пишет, кошмар какой-то).
Это было бы очень круто! И можно прямую трансляцию в ФБ вести.
(Ну и маечки подготовим само собой :)
no subject
no subject
А епсилон, кстати, обычно не "ближайшее к нулю, но не ноль", это минимальное такое, что 1.0+eps > 1.0.
no subject
no subject
no subject
no subject
Кстати, чтобы облегчить дело, на смену APL придумали язык J, который делал примерно то же самое, но все функции были уже написаны обычными словами. Ну и что ж - сгинул язык J, никто не стал им пользоваться!
no subject
Ты попробуй других умных людей привлечь в профессора тоже.
Маечки печатать пока не буду, но к сентябрю буду готовиться :)
no subject
Да, J это ужас-ужас, гораздо хуже читается, чем APL
no subject
Если бы словами - там сплошные цепочки знаков пунктуации
no subject
Получается, что весь фокус APL как раз в них-то и состоял!