Category: наука

Category was added automatically. Read all entries about "наука".

dab

Почти медаль :)

Ура, долгие часы прокрастинации на youtube оказались вознаграждены: персональное упоминание с занесением в почетный список бездельников на канале Fermilab. https://youtu.be/ZoJeWwtfdmQ?t=397

Предыдущее достижение моей карьеры в ютюб-физике - упоминание на The Science Asylum https://youtu.be/t0nGy2rsXYY?t=351 :)

Кстати, если кто интересуется популярными роликами вокруг физики и еще не знает эти каналы, рекомендую. А еще больше рекомендую PBS Space Time.
faculty of numbers

Greene

Ходили седьмого числа с сыном послушать телепроповедника популяризатора науки Брайана Грина (суперструнщик, который "Элегантную вселенную" написал и еще ряд подобных книжек).





Он там ближе к концу завел речь про Больцмановский мозг, и оказалось, что саму идею появляющегося из случайных флуктуаций вакуума мозга я раньше знал, но вот замысел, зачем эта гипотетическая штука вообще привлекалась, как-то пропустил. Речь о том, что исходя из современных представлений о будущем вселенной - когда там Солнце погубит Землю, когда галактики разлетятся, когда звезды потухнут, когда вся материя вплоть до протонов разорвется на части, когда наконец последние черные дыры испарятся - за все это время подходящая пора для нашей с вами жизни очень коротка, а пора, когда теоретически возможно случайное возникновение больцмановского мозга в вакууме, намного порядков продолжительнее, и возникает мысль, что оказаться таким мозгом для вас намного более вероятно, чем родиться тут на Земле, т.е. весьма вероятно, что все ваши знания и вся ваша память ложные, они возникли только что случайно, а через мгновение ваш больцмановский мозг погибнет. И получается, что если доверять современным представлениям/знаниям о физике, то с большой вероятностью эти представления и знания ложны, сами же предсказывают свою иллюзорность. Но только если при этом они верны (касательно рассуждений и оценок про мозги в вакууме).
office

Три книги

Недавно почитал/послушал три книжки на общую тему: физики пишут о смысле квантовой механики. О том, что она, возможно, говорит о мире, помимо формул вычисления вероятностей.

David Deutsch, "The Fabric of Reality: The Science of Parallel Universes and Its Implications", 1997.
У меня были большие надежды на эту книжку. Как-никак пионер квантовых вычислений. Который, как говорят, заявлял, что лишь многомировая интерпретация КМ объясняет мощь и работоспособность квантовых компьютеров. Дойч меня сильно разочаровал. Книжка получилось совершенно ужасная. Очень много текста, где он нудно пережевывает банальности, и несколько интересных нетривиальных моментов, которые он излагает коротко, невнятно и совсем неубедительно. Подробностей и примеров сейчас уже не назову, успел позабыть. Что в книжке занятно - интересный способ говорить о многомировой интерпретации (или чем-то вроде нее) в терминах "теневых фотонов" и "теневых частиц". Если вспомнить подход интегралов по траекториям, волновую функцию можно рассматривать как результат взаимодействия множества альтернативных траекторий частицы, по которым всем она как бы движется одновременно. Дойч все эти альтернативные траектории, летящие параллельно "копии" частицы называет "теневыми", которые при этом взаимодействуют с "настоящей" - той, что мы наблюдаем в итоге. Конечно, единственное отличие "настоящей" от "теневых" лишь в том, в каком из "миров" мы находимся, в каждом из них одна своя выглядит "настоящей", а остальные - "теневыми". Но в целом книжку эту не советую.

Sean Carroll, "Something Deeply Hidden: Quantum Worlds and the Emergence of Spacetime", 2019.
Я "джва года ждал" (с) ее выхода. Когда эта книга уже была готова, и до выхода оставалась пара дней, автор выпустил серию своего подкаста, где за пару часов практически пересказал все содержание, может даже еще лучше, чем в самой книжке. Рекомендую ту серию послушать, она взрывает мозг и делает это несколько раз. В книжке у него примерно все то же, но более подробно. Последовательно излагается многомировая интерпретация (MWI), показывается, почему она самая простая и прямая. Что это "суровая квантовая механика" - что получается, если брать чисто формулы и их предсказания за содержание, не добавляя никаких дополнительных постулатов вроде коллапса волновой функции, различия между квантовым и классическим мирами и т.п. Недавно широко известная в узких кругах теорфизики Sabine Hossenfelder сперва похвалила эту книжку Кэрролла, а потом отдельным постом попыталась объяснить, в чем ее претензии к многомировой интерпретации, но у меня так и не получилось ухватить ее мысль, даже после некоторых ее уточнений в комментариях. По-моему, Кэрролл на все ее вопросы в книжке ответил, но ей так не кажется. Кроме изложения MWI Кэрролл понятно рассказывает про некоторые альтернативы, вроде спонтанного коллапса в GRW, Pilot wave Бома и др. Успевает поговорить "как с этим жить" - о философских и моральных следствиях из MWI. Хорошо проясняет многие околотехнические вопросы: например, как MWI сочетается с теорией относительности, как она может не нарушать локальность (в отличие от многих других подходов). Плюс отдельно рассказывает про свежие направления теоретических исследований в поисках способа подружить кванты с гравитацией. Многие моменты я раньше слышал у него и у Susskind'a, но было непонятно, а тут многое стало. Например, в каком смысле разные области вакуума квантово запутаны друг с другом. И как лежит путь (или пути) от фон-неймановской энтропии до эйнштейновской гравитации. Эта последняя часть книги очень интересная, причем излагается на пальцах, без формул. А если раньше некоторые ключевые формулы уже видел, то это очень помогает make sense of it, без них все может звучать слишком уж далеким полетом фантазии. Там и про черные дыры, и про AdS/CFT correspondence, и про голографическую вселенную, и пр. Рекомендую!
Где-то в середине Кэрролл смело берется разъяснить как в MWI возникают вероятности и правило Борна, и вот тут, имхо, получается слабо и неубедительно. Он там быстро от frequentist-ской вероятности прыгает к околобайесовской, приводит какие-то рассуждения про ее применение к self-locating uncertainty (пока мы не увидели результат измерения, мы не знаем, в котором из миров находимся, можем оценивать разные вероятности исходов), но как из этого получить обратно вероятность в смысле статистики измерений, я так и не понял пока. И не я один, если верить следующему автору.
После прочтения есть шанс с одной стороны получить ответы на многие вопросы по MWI, лучше понять ее логику и механизмы, но с другой стороны обрести новые вопросы, увидеть какие-то новые моменты, которые делают MWI еще менее понятной в итоге.

Adam Becker, "What Is Real?: The Unfinished Quest for the Meaning of Quantum Physics", 2018.
Click-baity заголовок долго меня отпугивал от этой книжки, но после явной наводки Кэрролла я все же решил ее открыть. И скажу вам, это лучшая книга, что я вообще читал/слушал в этом году, и может быть не только в этом. Книга не топит ни за одну конкретную интерпретацию (в отличие от явного эвереттиста Кэрролла), не дает окончательных ответов (увы), зато очень здорово рассказывает историю развития взглядов, идей и интерпретаций за последние 115 лет. Все основные персонажи - Планк, Эйнштейн, Бор, Гейзенберг, Шредингер, фон Нейман, Бом, Уилер, Эверетт, Белл, Дойч, Zeh, Zurek и пр. - показаны очень живыми и конкретными людьми в конкретных исторических событиях, видно, как их идеи не возникали из воздуха, а рождались в интересной борьбе на фоне других важных событий, часто не относящихся напрямую к науке. И написана очень увлекательно, читается не хуже этого вашего Джорджа Р.Р. Мартина. Почему с Бором было плохо ходить в кино. Как его вывозили на особом самолете. Как Гейзенберг участвовал в немецкой ядерной программе при Гитлере. Как Бома чуть не посадили за связи с коммунистами, как он скрывался в Бразилии и потом лишился американского гражданства за то, что обзавелся бразильским паспортом вместо изъятого ранее американского. Как Эверетт придумал многомировую интерпретацию в качестве наиболее халявной диссертации. Как он потом занимался разработкой сценариев ядерной войны, а по вечерам со стаканчиком спиртного в руке пересматривал любимый Dr. Strangelove. Кто сформулировал знаменитое "shut up and calculate!" (а вовсе не Фейнман). Как финансирование науки раздулось во время и после второй мировой, и как сдулось обратно после антивоенных протестов во время вьетнамской войны. Как попытки заниматься основаниями квантовой механики становились "черной меткой" и могли запросто поставить крест на карьере...
Бекер здорово излагает все основные интерпретации квантов в их развитии, и их связь с протекавшей тогда эволюцией философии тоже - про "махизм", логический позитивизм, научный реализм и т.д. В чем заключается копенгагенская интерпретация, и есть ли она, если она нигде толком не сформулирована... Все это собирается в большой пазл, все разные его части обретают свой смысл. И в каждой части видны свои проблемы, нигде окончательного ответа не находится, увы. Но книжку очень рекомендую!
office

По Попперу

(подслушано у А. Бекера, о котором в соседнем посте)
В околонаучных обсуждениях часто любят вспоминать про фальсифицируемость, что дескать теория лишь тогда научна, когда есть некий эксперимент или возможны некие наблюдения, которые бы могли ее опровергнуть, если вдруг покажут что-то ей противоречащее.
Вот, например, законы Ньютона в применении к движению планет. Они здорово описывали движение Земли, Марса, Юпитера и пр. Но не Урана. С Ураном был косяк, не вписывался. Что тогда сделали? Выбросили ньютоновскую механику как фальсифицированную? Нет, придумали добавить еще одну гипотетическую планету, движение которой влияло на Уран. Потом ее и правда нашли - Нептун.
Затем с Меркурием тоже вышел косяк, опять ньютоновская механика не описывала его орбиту точно. Ну, тут уже понятно было, что делать, еще одна планета - Вулкан. Но нет, в этот раз таки ньютоновскую гравитацию фальсифицировали, благо уже новую подвезли - общую теорию относительности.
Спасибо Квайну, он разъяснил: не получается никакую теорию ни верифицировать (привет позитивистам), ни фальсифицировать саму по себе, всегда теории завязаны на кучу других теорий и предположений, которые мы явно или неявно полагаем истинными. И когда какое-то наблюдение противоречит гипотезе А, это наблюдение запросто может быть вызвано не ложностью А, а ложностью другого предположения Б, на которое А опирается...
office

Quantum vs. classical

В одной из ветвей волновой функции вселенной вы сегодня проснулись и задумались о том, что будет, если запрограммировать очень простую игрушечную модель квантовой механики и поиграться с ее параметрами. Не знаю, что там получилось у вас, но вот что получилось у меня.
У Ричарда Фейнмана есть чудесная "книжка" (запись публичной лекции) "QED: The Strange Theory of Light and Matter", где он наглядно на пальцах объясняет кое-какие азы, не прибегая к формулам. По сути он там излагает подход "sum over histories", он же "интегралы по траекториям". Если у нас из точки А вылетает частица, и мы хотим найти вероятность обнаружить ее позже в точке В, то мы делаем следующее. При движении частицы по некоторому пути Фейнман предлагает представить стрелку, которая крутится как на часах пока частица по этому пути летит. Дальше он предлагает взять все-все мыслимые пути из А в В, для каждого прокрутить такую стрелку, и все эти стрелки сложить как вектора. Квадрат длины такой стрелки и даст нам искомую вероятность (после нормализации). Понятно, что хотя он формулы не приводит, стрелки это комплексные числа, а их кручение это eiφ(t). На деле там eiS/h, где S это величина действия, интеграл по времени от лагранжиана вдоль траектории. У частицы нет какой-то одной определенной траектории, вместо этого она летит как бы сразу по всем, а суммирование амплитуд позаботится о том, чтобы траектории близкие к стационарному значению действия (минимуму/максимуму) складывались конструктивно и давали вклад большой, а отклонения от таких траекторий в разные стороны складывались деструктивно, с разными знаками, таким образом нейтрализуя друг друга, от них общий вклад будет маленький, отсюда автоматически возникает принцип наименьшего (стационарного на самом деле) действия, на котором вся механика стоит (и оптика). Такая формулировка может показаться очень непохожей на обычную квантовую механику 20-х годов, где есть волновая функция и ее эволюция по уравнению Шрёдингера, но одна из другой несложно выводится, см. например первые несколько страниц здесь.
Вот это и запрограммируем, делов-то. Возьмем двумерную коробку единичного размера. Из середины нижней границы будем запускать частицы. И в разных точках будем их "ловить" - считать суммарную амплитуду. Для интереса перегородим коробку стенкой, в к которой просверлим две дырки - будет у нас двухщелевой эксперимент, второй по знаменитости во всей КМ. Траектории будем прокладывать случайным образом из отрезков, проходящих через случайные точки (частица может прыгать туда-сюда совершенно не заботясь ни о каких законах движения). Если отрезок пролегает через стенку, то такую траекторию выбрасываем, не считаем, стенки у нас будут непроницаемыми для частиц. У нас есть ровно одна траектория из А в В, состоящая из одного отрезка, и сколько угодно траекторий с одной или более промежуточными точками. Осталось решить как вычислять действие - как крутить стрелки. Возьмем самый простой игрушечный вариант: действие при движении вдоль отрезка пропорционально его длине: hc * len, где hc - некоторый коэффициент, связанный с постоянной Планка h, обратно ей пропорциональный (ибо в оригинале там S/h). Вот и все. Код:
Collapse )
faculty of numbers

Сосед

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



Всего-то надо было повыше голову поднять и узреть табличку прямо у нашего входа.
Дома 86, 87 и 88 идут подряд, плечо к плечу. Наш офис в 86-м, а Ньютон в 1696-1700 годах жил в доме 88, а в 1700-1709 - в 87-м.
office

MWI

К недавним обсуждениям (elsewhere) интерпретаций квантовой механики. Шона Кэрролла всегда приятно и полезно послушать. О печальном состоянии вопроса интерпретаций КМ, о том, насколько проще и естественнее там получается многомировая, как примерно она работает, и немного тизеров с фронта теоретизирования:



(и это еще не тот пост, что я анонсировал недавно в личной переписке) Я тут после очередного просмотра Ахмедова кое-что понял на тему измерений в КМ, попробую на днях передать.
office

В искривленном пространстве. Часть 2

Ну и вот. Написал я тогда модуль символьных вычислений, который умеет арифметику, умеет частные производные, в том числе тригонометрии и сложных ф-й, умеет немного упрощать (выносить за скобки, сокращать дроби, знает, что sin^2 + cos^2 = 1) и умеет генерить код. Этот модуль используется в компайл-тайме, и из одного лишь уравнения поверхности выводит все необходимые формулы и генерит код для каждой фигуры, который тут же компилятором оптимизируется. Посмотрим на примере все той же сферы.
Задаем уравнение поверхности, отображение 2D координат (u,v) в 3D (x,y,z).

Expr[] sphereEq() {
    auto R = new Var("R");
    return [mul(R, mul(new Cos("u"), new Cos("v"))),
            mul(R, new Sin("v")),
            mul(R, mul(new Sin("u"), new Cos("v")))  ];
}

Ф-я возвращает массив из трех выражений - для x, для y и для z. X у меня идет вправо, Y вверх и Z вдаль. Координата u это долгота, координата v - широта, считается от экватора. Имея эти выражения как три компоненты ф-ии
X(u,v) = [R * cos(u) * cos(v), R * sin(v), R * cos(v) * sin(u)]
первым делом находим базисные вектора - производные X(u,v) по u и по v:
    auto Xu = X.diff("u"); 
    auto Xv = X.diff("v");

Получаем вектора
Xu: [[-1 * R * cos(v) * sin(u)], 0, [R * cos(u) * cos(v)]]
Xv: [[-1 * R * cos(u) * sin(v)], [R * cos(v)], [-1 * R * sin(u) * sin(v)]]
Collapse )
office

В искривленном пространстве. Часть 1

Когда читаешь в книжках по теории относительности про искривленное пространство-время, довольно сложно представить себе визуально как это все выглядит. И у меня давно засела в голове затея сделать самому рендерилку каких-нибудь не очень сложных, понятных пространств, где свет двигался бы по геодезическим, как и велит ОТО, увидеть, как это все изнутри смотрится. Потом был пост nponeccop'a, подкинувший идей. И вот, время пришло.
Какие бывают простые искривленные пространства? Одномерные пространства не имеют кривизны. А вот двумерные уже могут. Самое знакомое нам - поверхность сферы. Если двигаешься по сфере прямо, не сворачивая ни влево, ни вправо, на любой плоской карте такой путь будет выглядеть искривленным. Знаете ли вы, что корабль может доплыть из Пакистана на Камчатку, двигаясь по прямой, ни разу не поворачивая? Кстати, что вообще значит "двигаться прямо"? В случае таких вот 2D поверхностей, вложенных в обычное евклидово 3D пространство, ответ довольно простой. Если мы посмотрим на 3-хмерный вектор направления движения, вектор скорости, и посмотрим, как он изменяется по мере движения по нашей траектории на поверхности, возьмем предел разности между новым и старым значеними, это будет вектор ускорения, так вот, это ускорение всегда должно быть направлено ровно "вниз", перпендикулярно касательной плоскости к поверхности, и так в каждой точке пути. В каждой точке мы можем представить систему координат, где две оси лежат в касательной плоскости ("горизонтально"), а третья перпендикулярна поверхности. Такая система ближе всего к тому, как локально для нас поверхность выглядит, и в ней получается, что вектор ускорения в горизонтальных координатах нулевой (ускорение строго вертикально), т.е. какое бы у нас ни было направление движения, оно не меняется. Это называется параллельный перенос. И геодезическая определяется как траектория, получаемая параллельным переносом вектора направления движения вдоль него самого. Движение строго прямо, с сохранением направления движения. Кстати, не всегда это самый короткий путь - из Пакистана на Камчатку можно и покороче добраться, чем вокруг Африки. Геодезическая - это самый прямой путь. На сфере это большие окружности вроде меридианов и экватора. А вот ненулевая параллель - это уже не геодезическая, не прямая, чтобы лететь и на одной параллели оставаться, надо все время заворачивать, что особенно хорошо видно ближе к полюсам.Collapse )
office

задачка с типами

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

foobar :: Int -> String -> String -> String
foobar a b c = if a > 0 then b++c else c++b

fun1 :: Double -> Int -> String
fun2 :: String -> Int
fun3 :: Int -> Double -> Double -> Double
и т.д.

Есть "динамический" тип - сумма вышеназванных, простой алгебраик

data Var = Integer Int | Number Double | Str String

и нужно реализовать такую функцию callFun, которая получает список этих вот Var'ов и одну из ф-й выше, и вызывает переданную функцию с переданными аргументами, распаковав их из списка алгебраиков в конкретные типы. Если, конечно, переданный список значений подходит по типам и количеству к вызываемой ф-ии. Ну а не подходит - так выдать ошибку. Чтобы можно было вызвать ее навроде

callFun foobar [Integer (-3), Str "bb", Str "cc"]

и вернуть ее результат. По сути это такой FFI для интерпретатора.
Как бы вы такое сделали на вашем любимом статически типизированном ЯП?

Вот как решение выглядит на D. Сначала покажу результат, как оно выглядит в использовании:

union MyTypes {
    int integer;
    double number;
    string str;
}

alias Var = Sum!MyTypes;

string foobar(int a, string b, string c) {
    return a > 0 ? b~c : c~b;
}

double nsqrt(double x, int n) {
    import std.math : pow;
    return pow(x, 1.0/n);
}

void main() {
    Var a = -3;
    Var b = "bbb", c = "ccc";
    callFun!foobar([a,b,c]).writeln; // выводит cccbbb

    [Var(256.0), Var(4)].callFun!nsqrt.writeln; // выводит 4
}


По мотивам библиотечки taggedalgebraic, описываем типы для суммы в виде union'a. Конструктор типов Sum берет такой юнион и делает из него discriminated union, структуру, где кроме исходного union'a еще тэг, дискриминатор, сделанный типом-перечислением, причем имена тэгов берутся из имен полей данного юниона.

struct Sum(U) {
    alias Names = AliasSeq!(__traits(allMembers, U));
    mixin(`enum Tag {` ~ [Names].join(", ") ~ `}`);
    U data;
    Tag tag;

    this(T)(T x) {
        enum name = Names[staticIndexOf!(T, Fields!U)];
        __traits(getMember, data, name) = x;
        tag = __traits(getMember, Tag, name);
    }
}


Генерик конструктор отыскивает нужный тип в юнионе и устанавливает нужное значение тэга. Теперь мы умеем конструировать Var'ы, надо еще научиться их использовать. Обычно в библиотечных реализациях алгебраиков и вариантов делают ф-ю visit, которая берет разные обработчики для разных типов данных и вызывает один из них, подходящий по типу текущему хранимому значению. Мы же пойдем чуть другим путем: пусть передается всего один обработчик в виде полиморфной лямбды, куда будут попадать значения разных типов, а она уже сама разберется что с ними делать.

auto use(alias fun, A)(A a) {
    final switch(a.tag)
        foreach(name; A.Names)
            case __traits(getMember, A.Tag, name):
                return fun(__traits(getMember, a.data, name));
}

Тут мы делаем switch по тэгу, а все возможные варианты тэгов у нас перечисляет foreach по компайл-тайм списку их имен, хранящемуся в переданном алгебраике А. Такой цикл по компайл-тайм списку разворачивается при компиляции, так что на каждой итерации получается своя ветка свича, в разных ветках идет обращение к разным полям юниона, значение извлекается по имени через __traits(getMember), при этом на разных итерациях цикла (ветках свича) у нас разный тип этого значения, и оно передается в хэндлер fun.
Теперь уже можно реализовать callFun:

auto callFun(alias fun)(Var[] args) {
    alias PS = Parameters!fun;
    assert(PS.length == args.length, "Error: expecting " ~ PS.length.text ~ " arguments.");
    Tuple!PS params;
    foreach(i, T; PS)
        args[i].use!((x) {
            static if (is(typeof(x)==T)) params[i] = x;
            else throw new Exception("type error: passing " ~ typeof(x).stringof
                                ~ " instead of " ~ T.stringof);
        });
    return fun(params.expand);
}


callFun получает на вход какую-то ф-ю fun (известна в момент компиляции) и массив из Var'ов.
В первой строчке получаем компайл-тайм список PS типов агрументов переданной функции.
Если по длине не совпадает с переданным набором значений - бросаем ошибку.
Заводим тупл params, содержимое которого по типам совпадает с типами аргументов переданной ф-ии. Т.е. если fun принимает string и int, то params будет иметь тип Tuple!(string, int).
Проходимся разворачивающимся в компайл-тайме циклом по этому списку типов и заодно по массиву переданных Var'ов:
для очередного переданного значения args[i] типа Var (наш алгебраик), передаем его в use вместе с лямбдой, которая получит содержащееся внутри args[i] значение уже конкретного типа. Внутри use будет скомпилирована попытка применения лямбды ко всем возможным типам, которые могут хранится в том алгебраике. Поэтому внутри лямбды мы смотрим на тип аргумента - typeof(x) - и если он совпадает с нужным типом из списка типов аргументов fun, то значит это значение x может быть записано в тупл params. Например, если PS это (string, int), и в массиве Var'ов args элемент с индекcом 1 содержит внутри целое число, то use, сделав switch по тэгу, перейдет в ветку про int и передаст целочисленное значение из юниона в лямбду. Когда оно будет передано в эту лямбду, мы сможем его записать в params[1]. Если же в args[i] было передано значение не того типа, сработотает другая ветка свича по тэгу, то когда то значение попадет в эту лямбду, static if выведет на альтернативную ветку, где мы бросим исключение - переданное значение по типу не подошло.
Ну вот, успешно заполнив таким образом тупл params, где уже сидят значения конкретных типов, осталось вызвать требуемую ф-ию с этими значениями, что и делается в последней строчке. Вот и все!
Несколько строчек, и получился универсальный код, который априори вообще не знает, с какими алгебраиками, какими наборами типов ему придется работать, и работает с любыми. При этом тут нет никакой рантайм рефлексии помимо одного switch'a по тэгу, что мы написали явно. Все проверки вроде typeof(x)==T делаются при компиляции, в рантайме их нет, все имеющиеся циклы тоже разворачиваются в компайл-тайме. В требуемую функцию передаются только правильные типы, это проверяется статически. Но вот что интересно, некоторые части программы не подпадают ни под обычное определение статической типизации, ни под динамической. Тип переменной x в callFun нельзя так просто рядом написать карандашом, как это предполагает статическая типизация. Но и динамическим в обычном смысле он не является. Вот если все вызовы callFun с разными ф-ями и все циклы внутри развернуть, получится уже вполне код уровня привычных статически типизированных языков, где каждой переменной можно статически сопоставить какой-то тип. Такое ощущение, что шаблонов/макросов в типизированных языках не хватает какого-то своего раздела в теории типов / PLT. Когда один терм в исходнике у нас обозначает несколько разных термов после раскрытия шаблона, и у них разные типы.
  • Tags