История изменений
Исправление quasimoto, (текущая версия) :
подумай, как его реализовать например в системе кодов x86, и всё поймёшь
А как реализовать в системе кодов x86
(a + b) * (c + d)
? Очевидно
r0 = a
r0 += b
r1 = c
r1 += d
r0 *= r1
А теперь паттерн-матчинг:
data Term a = a :+ a | a :* a | L a
t x = case x of
(L a :+ L b) :* (L c :+ L d) -> (a + b) * (c + d)
...
и (наиболее тупой) результат компиляции:
t2 x =
if isProd x
then let l1 = getProdLeft x
r1 = getProdRight x
in if isSum l1
then let l2 = getSumLeft l1
r2 = getSumRight l1
in if isSum r1
then let l3 = getSumLeft r1
r3 = getSumRight r1
in if isLit l2
then let l2' = getLit l2
in if isLit r2
then let r2' = getLit r2
in if isLit l3
then let l3' = getLit l3
in if isLit r3
then let r3' = getLit r3
in (l2' + r2') * (l3' + r3')
else ...
else ...
else ...
else ...
else ...
else ...
else ...
дальше нужны тайптеги у типов-сумм, typeof-ы для них и акцессоры. Это можно оптимизировать минимизируя branching, но в целом всё довольно просто и в духе zero cost (Страуструп одобряет, вместе с разработчиками Rust и Cyclone). Необходимость в тайптегах подобна необходимости в vtbl у виртуальных функций, сам паттерн-матчинг даёт лёгкость расширения наборов функций для фиксированных (закрытых) типов данных (по отношению к expression problem, виртуальные функции ООП наоборот — лёгкость расширения данных предоставляющих фиксированные наборы интерфейсных функций).
Исходная версия quasimoto, :
подумай, как его реализовать например в системе кодов x86, и всё поймёшь
А как реализовать в системе кодов x86
(a + b) * (c + d)
? Очевидно
r0 = a
r0 += b
r1 = c
r1 += d
r0 *= r2
А теперь паттерн-матчинг:
data Term a = a :+ a | a :* a | L a
t x = case x of
(L a :+ L b) :* (L c :+ L d) -> (a + b) * (c + d)
...
и (наиболее тупой) результат компиляции:
t2 x =
if isProd x
then let l1 = getProdLeft x
r1 = getProdRight x
in if isSum l1
then let l2 = getSumLeft l1
r2 = getSumRight l1
in if isSum r1
then let l3 = getSumLeft r1
r3 = getSumRight r1
in if isLit l2
then let l2' = getLit l2
in if isLit r2
then let r2' = getLit r2
in if isLit l3
then let l3' = getLit l3
in if isLit r3
then let r3' = getLit r3
in (l2' + r2') * (l3' + r3')
else ...
else ...
else ...
else ...
else ...
else ...
else ...
дальше нужны тайптеги у типов-сумм, typeof-ы для них и акцессоры. Это можно оптимизировать минимизируя branching, но в целом всё довольно просто и в духе zero cost (Страуструп одобряет, вместе с разработчиками Rust и Cyclone). Необходимость в тайптегах подобна необходимости в vtbl у виртуальных функций, сам паттерн-матчинг даёт лёгкость расширения наборов функций для фиксированных (закрытых) типов данных (по отношению к expression problem, виртуальные функции ООП наоборот — лёгкость расширения данных предоставляющих фиксированные наборы интерфейсных функций).