Size: a a a

Compiler Development

2019 September 29

AK

Andrei Kurosh in Compiler Development
Алексей
Фактически методы запихали внутрь одной функции (которая теперь раздуется и будет делать фактически всё, вместо собственно рендера). Ну и от классов избавились (они и так нормально не использовались и больше мешали). Если вам такого достаточно для того чтобы назвать эти штуки функциональщиной, которые кстати реализуются с помощью того самого злосчастного shared mutable state, то хорошо, называйте.
В доке кстати написано:

There are no plans to remove classes from React.
источник

M

MaxGraey in Compiler Development
источник

SK

Sergey Kucherenko in Compiler Development
Слева, понятно, Хичкок: саспенс, крюки, а справа что?
источник

VK

Val Krylov in Compiler Development
Sergey Kucherenko
Слева, понятно, Хичкок: саспенс, крюки, а справа что?
Если рассматривать именно ужастики, то ближайшей аналогией к категорным понятиям будет Society (1989). Там такие морфизмы...
источник

SK

Sergey Kucherenko in Compiler Development
принимается
источник
2019 September 30

МБ

Михаил Бахтерев in Compiler Development
MaxGraey
Непоймешь этих функциональщиков - раньше они все наперебой доказывали, что наличеие замыканий, функций и ADT это не признак функциональности, а теперь наоборот даже дедушка С стал вдруг фукциональным? =)
Так не сразу было осознано, как удобнее и полезнее всего описывать семантику языков ппограммирования. Даже ассемблер в нынешних представлениях - функциональный язык программирования. Других языков, с математической (повторюсь) точки зрения, не существует. Понятно, что не всегда нужен внешне чисто функциональный язык, но чего плохого в том, чтобы использовать математические подходы для его описания? Глядишь, 2/3 плохо компонуемых хотелок из него можно будет выкинуть, а оставшуюся 1/3 аккуратно завернуть в эффекты и функции. Не обязательно же IO и State должны быть реализованы прям точно так, как в Haskell.
источник

МБ

Михаил Бахтерев in Compiler Development
MaxGraey
Именно что на машинных кодах или универсальном ассемблере (то есть Cи или подобным ему). Потому что городить GC, CTO, СPS для того что бы более не менее генерить машинные команды - ну такое)
Так какой-нибудь ML или какой-нибудь Lisp от ассемблера ушли не так у и далеко. У всех конструкций этих языков вполне очевидная низкоуровневая семантика. Главное отличие от Си - это функции (в lisp-ах ещё тэги типов всех значений, но union-ы с тэгами и в Си часто применяются). В остальном, в этих языках всё очень примитивно. Lisp больше на ассемблер похож, чем какой-нибудь Си++.

Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти (через которую проходит каждое обращение к памяти) и операционка, которая управляет страницами (в том числе и методами сборки мусора).

Конечно, в embedded нужно обходится без этого, но там и окружение не мультипрограммное, и динамики в управлении памятью существенно меньше.

Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си. Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Поэтому Павлиашвили, то есть, so so и хз.
источник

M

MaxGraey in Compiler Development
Михаил Бахтерев
Так какой-нибудь ML или какой-нибудь Lisp от ассемблера ушли не так у и далеко. У всех конструкций этих языков вполне очевидная низкоуровневая семантика. Главное отличие от Си - это функции (в lisp-ах ещё тэги типов всех значений, но union-ы с тэгами и в Си часто применяются). В остальном, в этих языках всё очень примитивно. Lisp больше на ассемблер похож, чем какой-нибудь Си++.

Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти (через которую проходит каждое обращение к памяти) и операционка, которая управляет страницами (в том числе и методами сборки мусора).

Конечно, в embedded нужно обходится без этого, но там и окружение не мультипрограммное, и динамики в управлении памятью существенно меньше.

Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си. Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Поэтому Павлиашвили, то есть, so so и хз.
> Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком. Да на Ocaml можно написать довольно низкоуровневые приложения если у разработчика прямые руки, кто же спорит? Только там вряд ли будет чистый FP.

> Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти

Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти.

> Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си

В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks). А теперь посчитай сколько всего нужно для рантайма FP на примере Ocaml:
- GC
- OCAMLLIB в которую водит работа с bigint (Polymorphic variants) и пр

Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C
источник

MV

Mikhail Voronov in Compiler Development
Михаил Бахтерев
Так какой-нибудь ML или какой-нибудь Lisp от ассемблера ушли не так у и далеко. У всех конструкций этих языков вполне очевидная низкоуровневая семантика. Главное отличие от Си - это функции (в lisp-ах ещё тэги типов всех значений, но union-ы с тэгами и в Си часто применяются). В остальном, в этих языках всё очень примитивно. Lisp больше на ассемблер похож, чем какой-нибудь Си++.

Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти (через которую проходит каждое обращение к памяти) и операционка, которая управляет страницами (в том числе и методами сборки мусора).

Конечно, в embedded нужно обходится без этого, но там и окружение не мультипрограммное, и динамики в управлении памятью существенно меньше.

Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си. Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Поэтому Павлиашвили, то есть, so so и хз.
А как GC влияет на фрагментацию памяти
источник

MV

Mikhail Voronov in Compiler Development
MaxGraey
> Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком. Да на Ocaml можно написать довольно низкоуровневые приложения если у разработчика прямые руки, кто же спорит? Только там вряд ли будет чистый FP.

> Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти

Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти.

> Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си

В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks). А теперь посчитай сколько всего нужно для рантайма FP на примере Ocaml:
- GC
- OCAMLLIB в которую водит работа с bigint (Polymorphic variants) и пр

Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C
В расте же есть vtable для trait objects.
источник

MV

Mikhail Voronov in Compiler Development
Thunks нет, потому что структуры не могут наследоваться друг от друга и this/self не нужно аджастить
источник

M

MaxGraey in Compiler Development
Mikhail Voronov
В расте же есть vtable для trait objects.
Да, чего забыл про трейты
источник

MO

Mar Ort in Compiler Development
Mikhail Voronov
А как GC влияет на фрагментацию памяти
В Jvm по крайней мере за счет перемещения живых объектов они хранятся компактно и память не фрагментируется
источник

E

EgorBo in Compiler Development
помню раньше в андроиде гц не умел в дефраг хипа, поэтому можно было на изичах изрешетить хип битмапами
источник

E

EgorBo in Compiler Development
хотя там до сих пор на первых уроках учат реюзать объекты картинок -_-
источник

МБ

Михаил Бахтерев in Compiler Development
MaxGraey
> Вон разработчики MirageOS хвалятся, что их runtime загружается на холодной виртуалке за время ответа на DNS-запрос.

Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком. Да на Ocaml можно написать довольно низкоуровневые приложения если у разработчика прямые руки, кто же спорит? Только там вряд ли будет чистый FP.

> Возможность обойтись без GC тоже не очевидна. Чтобы на Си/Си++ писать относительно безопасно, без фрагментации памяти, нужны аппаратная подсистема виртуальной памяти

Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти.

> Из этого всего: чёрт его знет, что в runtime тащит больше зависимостей. Экосистема ФП или экосистема Си

В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks). А теперь посчитай сколько всего нужно для рантайма FP на примере Ocaml:
- GC
- OCAMLLIB в которую водит работа с bigint (Polymorphic variants) и пр

Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C
"Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком."

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

"Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти."

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

"В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks)."

Я не знаю в деталях, как Rust устроен, но из общеизвестных соображений, параметрический полиморфизм с мономорфизацией кода (это когда всё разрешается статически и инлайнится) приводит к экспоненциальному (от количества типов) росту объёмов кода.  Это не подходит для embedded-приложений. А в обычных условиях создаёт нагрузку на кэши и внутренние буферы микроопераций. Поэтому so so. Не очевидно, что делать так быстрее. Видел случаи, когда интерпретаторы языка J работали гораздо быстрее аналогичного Си++ кода по этой причине.

"Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C"

ML может с этими 200KB работать на голом железе. А 10KB Си не смогут. Runtime полноценного Си - это, в том числе, POSIX. И для Rust тоже это верно. Не очень понятно, как Rust может работать без поддержки операционки, особенно в управлении памятью. Конечно, можно написать операционку на Rust, но каков будет её размер? Я боюсь, что из-за проверки заимствований, код придётся делать более громоздким, потому что сложно будет пользоваться обычными для ядер операционок структурами данных, которые очень-очень-очень shared и dynamic.

Не изучал этот вопрос. Есть какие-нибудь непримитивные примеры ядер на Rust?
источник

AT

Alexander Tchitchigin in Compiler Development
Михаил Бахтерев
"Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком."

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

"Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти."

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

"В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks)."

Я не знаю в деталях, как Rust устроен, но из общеизвестных соображений, параметрический полиморфизм с мономорфизацией кода (это когда всё разрешается статически и инлайнится) приводит к экспоненциальному (от количества типов) росту объёмов кода.  Это не подходит для embedded-приложений. А в обычных условиях создаёт нагрузку на кэши и внутренние буферы микроопераций. Поэтому so so. Не очевидно, что делать так быстрее. Видел случаи, когда интерпретаторы языка J работали гораздо быстрее аналогичного Си++ кода по этой причине.

"Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C"

ML может с этими 200KB работать на голом железе. А 10KB Си не смогут. Runtime полноценного Си - это, в том числе, POSIX. И для Rust тоже это верно. Не очень понятно, как Rust может работать без поддержки операционки, особенно в управлении памятью. Конечно, можно написать операционку на Rust, но каков будет её размер? Я боюсь, что из-за проверки заимствований, код придётся делать более громоздким, потому что сложно будет пользоваться обычными для ядер операционок структурами данных, которые очень-очень-очень shared и dynamic.

Не изучал этот вопрос. Есть какие-нибудь непримитивные примеры ядер на Rust?
Само собой. https://www.redox-os.org/
источник

AT

Alexander Tchitchigin in Compiler Development
В Фуксии от Гугла что на Расте написано? Ядро не? Я не помню.
источник

M

MaxGraey in Compiler Development
Михаил Бахтерев
"Так парадигма у OCaml не прибита гвоздями, это мультипарадигмальный язык программирования с одним из самых быстрых компиляторов среди ML додобных языком."

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

"Rust отлично обходиться без GC и ARC (ну почти). Насчет фрагментации - это уже удел аллокатора а не высокоуровневого менеджера памяти."

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

"В Rust есть такое поняти как zero-cost abstactions. То есть, если что то ты не используешь - это не будет включено в рантайм вообще, а если используешь, то это будет максимально развернуто, заинлайнено и частично эвалюировано, там даже есть MIR (middleware) для этого, только пока он работает не на полную мощь. Добавь сюда параметрический полиморфизм и отсутсвие/минимизация динамической диспечеризации как таковой (нет vtable "поправка - есть" или thunks)."

Я не знаю в деталях, как Rust устроен, но из общеизвестных соображений, параметрический полиморфизм с мономорфизацией кода (это когда всё разрешается статически и инлайнится) приводит к экспоненциальному (от количества типов) росту объёмов кода.  Это не подходит для embedded-приложений. А в обычных условиях создаёт нагрузку на кэши и внутренние буферы микроопераций. Поэтому so so. Не очевидно, что делать так быстрее. Видел случаи, когда интерпретаторы языка J работали гораздо быстрее аналогичного Си++ кода по этой причине.

"Самое лучшее что удавалось добиться судя по комментариям на SO это 200 KB для минимального приложения против 10 КВ в среднем для такой же программы на C"

ML может с этими 200KB работать на голом железе. А 10KB Си не смогут. Runtime полноценного Си - это, в том числе, POSIX. И для Rust тоже это верно. Не очень понятно, как Rust может работать без поддержки операционки, особенно в управлении памятью. Конечно, можно написать операционку на Rust, но каков будет её размер? Я боюсь, что из-за проверки заимствований, код придётся делать более громоздким, потому что сложно будет пользоваться обычными для ядер операционок структурами данных, которые очень-очень-очень shared и dynamic.

Не изучал этот вопрос. Есть какие-нибудь непримитивные примеры ядер на Rust?
Да есть Redox. Но как по мне намного интерестнее бараузер (тоже почти так же сложно как и ОС)
https://servo.org

Еще более интерестный проект с точки зрения низкоуровневости и профессионального интерееса - это Cranelift:
https://github.com/CraneStation/cranelift
источник

M

MaxGraey in Compiler Development
Ну и эмбеддерам он тоже полюбился:
https://github.com/rust-embedded/awesome-embedded-rust
источник