Size: a a a

Compiler Development

2020 March 04

А

Алексей in Compiler Development
не как у крестовых темплейтов
источник

EM

Evgenii Moiseenko in Compiler Development
ну так темплейты тоже в некотором роде параметрический полиморфизм
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
Evgenii Moiseenko
вопрос зачем?
темплейты/дженерики - это два способа реализации параметрического полиморфизма.
Разница в том, что темплейты реализуют его с помощью мономорфизаци, т.е. как раз когда для каждого инстанса функции/класса под тип генерируется код.
В дженериках необходимости генерировать код под каждый инстанс просто нет, потому что все значения в рантайме имеют одинаковую структуру (в первом приближении все объекты — это просто указатели в кучу), и если программа протайпчекалась, то гарантируется что в рантайме уже не будет ошибок из-за несоответствия типов.
Собственно в C/C++ как и в Rust используются мономорфизация как раз потому что переменные зачастую передаются по значению и там как раз не гарантируется какое-то унифицированное представление в рантайме.
фактически я решаю задачу рефлексии типов в TS (чтобы например сделать как в c# JsonConvert.Deserialize<MyClass>(json))
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
но в доменно-специфичном виде
источник

А

Алексей in Compiler Development
просто темплейты в использовании как раз оправдывают своё название и ведут себя как подстановка, просто чуть более умная и безопасная, нежели у макросов
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
то есть не просто затащить типы в рантайм в общем виде
а затащить их части на этапе компиляции чтобы порешать конкретные задачи
валидация json одна из них
источник

А

Алексей in Compiler Development
Алексей
просто темплейты в использовании как раз оправдывают своё название и ведут себя как подстановка, просто чуть более умная и безопасная, нежели у макросов
а у раста ближе к тайпклассам хаскеля, просто реализация идёт через мономорфизацию
источник

EM

Evgenii Moiseenko in Compiler Development
Mikhail 才藤 中村 Bashurov
то есть не просто затащить типы в рантайм в общем виде
а затащить их части на этапе компиляции чтобы порешать конкретные задачи
валидация json одна из них
вам случайно не type reification нужен?
https://eli.thegreenplace.net/2018/type-erasure-and-reification/
источник

А

Алексей in Compiler Development
Mikhail 才藤 中村 Bashurov
внутри чего?
визитор бежит по файлу
видит foo c дженериком
пробегается по телу не видит вызова validate хотя видит вызов bar
видит объявление bar
ОПА видит в его теле вызов validate

НО
1. мы уже в теле функции в визиторе, а значит поменять саму функцию bar уже нельзя
2. нам надо поменять не только bar но и foo (и еще понять это)
3. а еще вызовы foo которые опять же могли находится выше ее объявления
3 пункт вообще странный, потому что визитору уже должно быть плевать что там выше, а что ниже. По идее все символы уже должны быть полностью определены на этом этапе.
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
Алексей
3 пункт вообще странный, потому что визитору уже должно быть плевать что там выше, а что ниже. По идее все символы уже должны быть полностью определены на этом этапе.
дак там выше вызов foo<User>() который надо превратить в foo_User()
или foo(User) но не суть
источник

А

Алексей in Compiler Development
если не определены, значит первый проход ещё не сделан, а для JS подобного его делать увы придётся
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
символы уже есть
источник

EM

Evgenii Moiseenko in Compiler Development
Evgenii Moiseenko
вам случайно не type reification нужен?
https://eli.thegreenplace.net/2018/type-erasure-and-reification/
точнее это вроде называется reified generics
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
Evgenii Moiseenko
точнее это вроде называется reified generics
читаю
источник

А

Алексей in Compiler Development
Mikhail 才藤 中村 Bashurov
дак там выше вызов foo<User>() который надо превратить в foo_User()
или foo(User) но не суть
Нужно foo<User> превратить в foo_User. Значит надо посетить bar<T=User>, причём не просто посетить, а с намерением превратить его в bar_User, то есть T для bar должен уже быть конкретным
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
Алексей
Нужно foo<User> превратить в foo_User. Значит надо посетить bar<T=User>, причём не просто посетить, а с намерением превратить его в bar_User, то есть T для bar должен уже быть конкретным
да, но мы не знаем этого заранее
узнаем что в колстеке foo будет validate мы уже в теле bar
источник

M中

Mikhail 才藤 中村 Bashurov in Compiler Development
мы же не хотим трансформировать ВСЕ функции с дженериком
источник

А

Алексей in Compiler Development
мы знаем это при анализе foo<User>(...), значит мы должны знать это при посещении foo<T>, то есть вместо абстрактного T должен быть уже User
источник

А

Алексей in Compiler Development
и тоже самое для bar
источник

А

Алексей in Compiler Development
и так далее
источник