LINUX.ORG.RU

Как чувствует себя Go в системном программирование ?

 , ,


0

3

Есть ли те, кто писал на Го на низком уровне? Удобно ли? И используют ли Го в кибербезопасности, а именно в написании каких-нибудь антивирусных штук?

Лучше Оберон взять. В отличии от Go, он поддерживает динамическую загрузку/выгрузку модулей. На нём можно целые ОС писать без сторонних языков/инструментов: Project Oberon, Bluebottle/AOS/A2.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 1)

И используют ли Го в кибербезопасности, а именно в написании каких-нибудь антивирусных штук?

Ибн @Petya-A вы опоздали на поезд.
Ибн @metaprog обещал все драйвера переписать на Метапрог.

anonymous ()
Ответ на: комментарий от X512

Лучше Оберон взять. В отличии от Go, он поддерживает динамическую загрузку/выгрузку модулей.

Хорошее суждение.
От меня «пятак».
Языки поддерживающие возможность динамической загрузки модулей, расширения классов, … являются хороши для разработки обобщенных алгоритмов.
Например в 1С 7.7 гениальные парни добавили такую возможность.
В результате модуль где-то в 300 строк позволяет загрузить в базу 1С данные из всех таблиц к примеру Firebird.

Ведь неплохо правда?

Владимир

anonymous ()
Ответ на: комментарий от den73

Вот как раз с точки зрения ИБ, допустим, мы хотим безопасную программу под линукс на го. Чтобы убедиться в безопасности, мы должны убедиться в безопасности линукса (потому что в нём будет исполняться), компилятора gcc (потому что к программам на go наверняка линкуются системные библиотеки, написанные на Си), потом компилятора go, и потом самой программы.

В случае оберона, мы должны убедиться в безопаности А2, её компилятора и самой программы.

Но компилятор A2 в сумме с самой A2 - всего миллион строк. А ядро линукса - 10 млн строк, плюс gcc - 7 млн строк, плюс системные библиотеки ХЗ сколько плюс компилятор go - не нагуглил слёту, но уже и так вполне достаточно.

Притом, gcc и ядро линукса написаны, либо на Си и ассемблере (а в Си даже массивов толком нет, сплошное CWE), либо на C++ и ассемблере (уязвим ввиду того, что грабли Си не устранены, зато добавлено море сложности).

А2 написана на обероне (который по безопасности примерно как сам Го) и ассемблере, которого там не слишком уж много.

Выбор очевиден.

den73 ★★★★★ ()

Есть ли те, кто писал на Го на низком уровне?

Ты хоть напиши, что ты имеешь ввиду.

И используют ли Го в кибербезопасности

Да.

а именно в написании каких-нибудь антивирусных штук?

Возможно. Я видел вакансии с Go от антивирусных вендоров.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от den73

Вот как раз с точки зрения ИБ, допустим, мы хотим безопасную программу под линукс на го. Чтобы убедиться в безопасности, мы должны убедиться в безопасности линукса (потому что в нём будет исполняться), компилятора gcc (потому что к программам на go наверняка линкуются системные библиотеки, написанные на Си), потом компилятора go, и потом самой программы.

Дяденька, а вы точно настоящий безопасник?

A2 живее всех живых, даже процессор свой сваяли.

Нет, чувак. На ЛОРе сказали, что оно сдохло, значит оно сдохло. Нет пути.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от den73

@den73 Вы МОЛОДЕЦ!

Если бы у меня деньги были, то поставил вам при вашей жизни бронзовый памятник!

Посмотрел ваши Commits, а их там - «мама-мия» …

Кто потенциальные пользователи A2?

Владимир

anonymous ()
Ответ на: Ты хоть напиши, что ты имеешь ввиду. от Petya-A

те же драйвера допустим

В исследовательских целях писали, например, сетевые драйвера https://www.net.in.tum.de/fileadmin/bibtex/publications/theses/2018-ixy-go.pdf Но нет практического смысла в написании драйверов для сишных операционок (линукса) на «безопасных» языках. По-хорошему нужно начинать с самого ядра операционки Biscuit: монолитное POSIX-совместимое ядро на Go Но чтобы взлетели убийцы линукса, нужно финансирование и мощная поддержка, которых нет (по понятным причинам).

dadd ★★★ ()
Ответ на: комментарий от dadd

Но нет практического смысла в написании драйверов для сишных операционок (линукса) на «безопасных» языках.

Угу, и всё это уже давно есть в A2. Например, вот драйвер какой-то сетевой платы:

https://gitlab.com/budden/jaos/-/blob/главная/source/BIOS.Ethernet3Com90x.Mod

А вот кусок ядра:

https://gitlab.com/budden/jaos/-/blob/главная/source/BIOS.I386.Machine.Mod

Оно уже «взлетело», для какого-то определения слова «взлетело». Т.е. есть люди, которые продают на этом свои железки и зарабатывают деньги.

den73 ★★★★★ ()
Ответ на: комментарий от anonymous

Кто потенциальные пользователи A2?

Реальные пользователи A2 занимаются всякой эмбедщиной, но они не так уж много пишут о себе. Кто потенциальные - не знаю. Я просто перевожу на русский, а дальше кто захочет - тот и воспользуется. Во всяком случае, на днях мне написал один эмбедщик, который хочет программировать на русском языке и пытается даже применить вот это:

http://compiler.su/utilita-transliteratsii-russkogo-Si-SiPlusPlus-v-standartnyj.php

Просто ему нужен ARM, а я как раз этот ARM недавно злобно выпилил из A2. Может, и зря.

den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: Ты хоть напиши, что ты имеешь ввиду. от Petya-A

писались ли какие-нибудь системные программы на го

Попробуй ответить на вопрос, что такое системная программа.

те же драйвера допустим для чего-то…

Наверняка да. Попробуй поискать. По крайней мере, причин чтобы этого никто не делал я не вижу.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от den73

Просто ему нужен ARM, а я как раз этот ARM недавно злобно выпилил из A2. Может, и зря.

Копия ваших исходников с ARM у меня имеется, так что если потерли все, то сброшу вам архив …

А у меня дрянного человека мысль возникла - «Спрятал ARM».

Имеется ли документ с описанием архитектуры A2 и спецификации форматов бинарных модулей, … /специфичные для A2/.

Вирт конечно молодчина!
Мысли у него толковые.
По существу, то что сейчас разрабатываю в многом реализует подход Вирта.

Вирт ведь тоже «Америку не открыл», а использовал архитектурный подход за который все знают, но ленятся реализовать.

Сегодня 1С 7.7 /редиска/ у меня четыре часа украла.
Нужно было программно в документик напихать циферки.
Сделал в обработке.
1С все проглатывает не на что ни ругается и все вроде ok.
А документ - ПУСТ. И наконец через интернет открыл для себя Америку.
С документом можно, что-то сделать лишь в модуле документа!

Жаль время потерянное.
Вот редиски.
М-да.
У меня то всегда код был «правильный» и вот на тебе.

Вообщем то мог бы «запилить» а-ля 1С 7.7 так как с ней и так работаю без 1С, но ее объекты СЛАБЕНЬКИЕ.
Пустая трата времени пилить а-ля 1С 7.7.

Хвастану.
Есть кое-что от чего 1С «потылицу чесать будет», но всему свое время.

GUI - НУУУУУУУУУУУЖЖЖЖЖЖЖЖЖЖЖНО разработать.

Владимир

anonymous ()
Ответ на: комментарий от anonymous

Да они и у меня в репозитории есть, просто я в последнее время там делаю движок перевода, ARM чем-то мешал, я его выпилил. Наверное, это обратимо, но чем дальше, тем труднее это будет.

den73 ★★★★★ ()
Ответ на: комментарий от anonymous

С документом можно, что-то сделать лишь в модуле документа!

Бред же!
В моей объектной системе такого нет.
От того в «ступор» и вошел.
Не мог даже помыслить, что пишу неправильный код. Перенес его в ПослеОткрытия нужного документа и все Ok!
Вот редиски …

Владимир

anonymous ()
Ответ на: комментарий от den73

Наверное, это обратимо, но чем дальше, тем труднее это будет.

Обратимо, труднее, преодолимо - что вы хотели сказать не запутывая нас?

Жил человек рассеянный На улице Бассейной. Сел он утром на кровать, Стал рубашку надевать, В рукава просунул руки - Оказалось, это брюки.

Владимир

anonymous ()
Ответ на: комментарий от den73

Выпиливание ARM-а обратимо, но чем дальше, тем сложнее его впилить обратно в ЯОС. В изначальной A2 он никуда не делся и остаётся флагманской платформой.

Вот говорят форумчане, что мол легко анонимусов различать …
Брехня!

Владимир

anonymous ()
Ответ на: комментарий от anonymous

что мол легко анонимусов

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

Владимир

anonymous ()
Ответ на: комментарий от sqq

сейчас вроде Pony наследник Ada, Modula и Oberon подобных языков.

не то чтобы наследник, он немного про другое – про акторную модель.

объекты в Pony это по сути акторы (но и обычные объекты там тоже есть). отличаются тем, что у акторов методы асинхронно вызываются, а у объектов синхронно (синхронно – в место после вызова метода возвращается только после отработки return метода, асинхронно – типа горутины, запустил и пошёл, а оно дальше само как-то наподобие продолжений/futures когда захочет тогда отработает).

если сравнивать с Ada, где task это почти unit модуля, и выделены явно точки синхронизации (и тоже можно писать асинхронный код) – тут более похоже на классические объекты с++/java подобные, только из-за асинхронщины нужно более продумывать взаимодействие и жизненный цикл объектов (в аде это как-то более явно выделено).

если сравнивать с Обероном – то тогда скорее с Active Oberon из A2 где есть явные точки синхронизации наподобие async/await или «методы активных объектов». ну ещё есть Zonnon где «компонентное композитное ПО» пытались более явно выделить протоколы взаимодействия, и реакции наподобие конечных автоматов по протоколам (и композитное что-то там параметрически синтезировать).

по BlackBox Component Pascal реализации оберона, кстати была статья И. Ермакова что он реализовывал аналогичные Active Oberon фишки (вроде кооперативной многозадачности) на обычном обероне.

про модулу — ну не совсем в эту степь, хотя да, какие-то корутины уже в модуле пытались реализовывать.

в целом, в Pony нормальный синтаксис для объектов акторной модели и асинхронщины.

anonymous ()
Ответ на: комментарий от sqq

ещё там в Pony есть система типов с поддержкой «reference capabilities»:

By sharing only immutable data and exchanging only isolated data we can have safe concurrent programs without locks. The problem is that it’s very difficult to do that correctly. If you accidentally hang on to a reference to some isolated data you’ve handed over or change something you’ve shared as immutable then everything goes wrong. What you need is for the compiler to force you to live up to your promises. Pony reference capabilities allow the compiler to do just that.

в общем гарантии языка компилятору позволяют довольно легко писать параллельный, конкурентный и асинхронный код.

те же самые акторы, например.

anonymous ()
Ответ на: комментарий от X512

Лучше Оберон взять. В отличии от Go, он поддерживает динамическую загрузку/выгрузку модулей. На нём можно целые ОС писать без сторонних языков/инструментов

Посмотрел я на Оберон... Дело в том, что Algol-60 опередил свое время на 10-15 лет, потому что в то время какой-нибудь кобол не имел циклов, бейсик не имел функций, а Algol-60 уже имел структурированное программирование. Паскаль вирта стал развитием Algol-60, изначально паскаль назывался Algol-W — это язык соответствовал своему времени (1970-1975).

Oberon-2 1991 года дал примитивные динамические типы и унаследовал модули от модулы, что по уровню развития значительно превосходит Си, Кобол, Бейсик, Algol-68, PL/I, и прочие. Где-то на уровне C++ (1983) и Standard ML (1984) это превосходство заканчивается, потому что они привносят высокий уровень полиморфизма с малыми накладными расходами. Oberon-2 выпущен во время начала стандартизации UTF-8, уже в 1990 был ISO 10646, который определял UTF-1, а в 1991 году выпускается Oberon-2, в который безальтернативно прошиты числа и строки без намека на перспективу. Напомню, что в 1986 уже существовал Object Pascal от Apple, который уже имел фишки оберона с динамическими типами и модулями.

Писать системщину на Oberon-2 можно, как и на Си, как и на паскале — но это тупо неэффективно. Потому тот же GCC пишут на Си, но с элементами крестов. И только Торвальдс решительно стоит на своем, не давая вносить кресты в ядро.

byko3y ★★★ ()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от byko3y

Посмотрел я на Оберон…

Вы забыли главное преимущество: безопасность языка и наличие сборщика мусора. Все варианты Паскаля принципиально не сильно лучше C/C++, в них легко испортить память и сделать утечку памяти или double free. Есть 2 подхода обеспечения безопасности памяти: сборщик мусора как в Обероне и Go или контроль владения как в Rust. Rust слишком сложный, содержит недостатки и дыры в архитектуре и медленно компилируется, в нём нет нормальных модулей (динамическая загрузка, инициализаторы/финализаторы модулей, детерминированный порядок инициализации).

Где-то на уровне C++ (1983) и Standard ML (1984) это превосходство заканчивается, потому что они привносят высокий уровень полиморфизма с малыми накладными расходами.

В Обероне dynamic_cast эффективнее, чем в C++. Типичной практикой является обработка сообщений через проверку расширений типов:

PROCEDURE (c: Controller) HandleCtrlMsg* (
	f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View
), NEW, EXTENSIBLE;
BEGIN
	focus := c.focus;
	WITH msg: Controllers.PollCursorMsg DO
		PollCursor(c, f, msg, focus)
	| msg: Controllers.PollOpsMsg DO
		PollOps(c, f, msg, focus)
	| msg: PollFocusMsg DO
		IF msg.all OR (c.opts * modeOpts # mask) & (c.focus # NIL) THEN msg.ctrl := c END
	| msg: Controllers.TrackMsg DO
		Track(c, f, msg, focus)
	| msg: Controllers.EditMsg DO
		Edit(c, f, msg, focus)
	| msg: Controllers.TransferMessage DO
		Transfer(c, f, msg, focus)
	| msg: Controllers.SelectMsg DO
		IF focus = NIL THEN c.SelectAll(msg.set) END
	| msg: Controllers.TickMsg DO
		FadeMarks(c, show);
		CheckMaskFocus(c, f, focus)
	| msg: Controllers.MarkMsg DO
		c.bVis := msg.show;
		c.Mark(f, f.l, f.t, f.r, f.b, msg.show)
	| msg: Controllers.ReplaceViewMsg DO
		ReplaceView(c, msg.old, msg.new)
	| msg: Properties.CollectMsg DO
		IF focus = NIL THEN
			msg.poll.prop := ThisProp(c, direct)
		END
	| msg: Properties.EmitMsg DO
		IF focus = NIL THEN
			SetProp(c, msg.set.old, msg.set.prop, direct)
		END
	ELSE
	END
END HandleCtrlMsg;

В C++ аналогичный код будет страшно выглядеть и медленнее работать.

а в 1991 году выпускается Oberon-2, в который безальтернативно прошиты числа и строки без намека на перспективу.

Не понял что вы имеете в виду.

без намека на перспективу

В Component Pascal - наследнике Oberon 2 есть 4 числовых типа (BYTE, SHORTINT, INTEGER, LONGINT, 1, 2, 4 и 8 байт соответственно), а также 2 символьных типа SHORTCHAR (1 байт), CHAR (2 байта). Язык ничего не знает о кодировке кроме того, что во встроенных строковых операциях массив из символов должен оканчиваться на нулевой символ. Обработка кодировок выполняется в библиотеках.

Писать системщину на Oberon-2 можно, как и на Си, как и на паскале — но это тупо неэффективно.

Очень даже эффективно: не надо бороться с порчей памяти и нарушением консистентности указателей. Любой сколь-нибудь сложный код на Си/C++ полон багов и уязвимостей, позволяющих осуществить удалённое выполнение кода.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Есть 2 подхода обеспечения безопасности памяти: сборщик мусора как в Обероне и Go или контроль владения как в Rust.

Нет. Подходов ровно столько, сколько придумаешь. Ты имеешь в виду подходов, реализованных в более-менее мейнстримовых ЯП.

Для Mercury есть компилятор (чья-то PhD дипломная работа), имеющий compile time сборщик мусора (т.е. и не сборщик мусора в классическом понимании вовсе). Есть ещё менее популярные toy проекты, которые разными способами добиваются того же (либо автомизируют сборку мусора на этапе компиляции, либо требуют формальной верификации безопасности).

Не Владимир.

anonymous ()
Ответ на: комментарий от anonymous

Для Mercury есть компилятор (чья-то PhD дипломная работа), имеющий compile time сборщик мусора (т.е. и не сборщик мусора в классическом понимании вовсе).

Это подход Rust и он имеет ограничения. Насколько мне известно алгоритм сборки мусора без трассировки, работающий во всех случаях, пока не придумали.

The current Mercury implementation supports two different methods of memory management: conservative garbage collection, or no garbage collection. The latter is suitable only for programs with very short running times (less than a second), which makes the former the standard method for almost all Mercury programs.

Отсюда.

То есть там либо обычный сборщик мусора, либо выделение памяти вообще без освобождения и постоянной утечкой.

Или имелось ввиду это? Это подход близкий к Rust когда создаются кучи памяти с единичным владением. Сборки мусора там нет.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

https://mercurylang.org/documentation/papers/CW2004_03_mazur.pdf

Самый универсальный на все случаи жизни сборщик и не нужен. Автоматический вывод реализации из спецификации в общем случае тоже задача нерешаемая. Но Idris, например, это не мешает реализацию выводить там, где можно, а для остального кода спрашивать подсказки (я про \o, \p).

И ещё скажи ка, дядя, с.уяли это «подход, близкий к Раст», если region based memory management с 60х пилят, а раст недавно отрыгнули?

anonymous ()
Ответ на: комментарий от anonymous

гипертекст на зависимых типах, который мы потеряли

я вот тут подумал, что и гипертекст можно было бы реализовать поэффективнее чем HTML и «XML embedded markup considered harmful».

подходов столько сколько выдумаешь

например, тот же гипертекст – с 60х и особенно в 90х было много альтернативных дизайнов, в контекстном хелпе и прочих местах.

если как-то попытаться формализовать тот дизайн гипертекста из Xanadu изначального Теодора Холм Нельсона – то это:

  1. отдельный клиент-серверный API для «монадического» изменения, редактирования, публикации, обработки (11 принципов Xanadu).

  2. такой гипертекст по сути = данные+метаданные. где данные – иммутабельный поток текста (все правки делаются отдельным потоком, исходный поток не меняется). а метаданные = индексы в данных.

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

  4. ссылки – на оверлеи, блоки текста, которые могут перекрываться. и ссылки принципиально типизированные. ссылка может быть на скрипт, «переход» запускает скрипт. ссылка может быть на абзац, элемент списка литературы №1, дважды косвенная и т.п. есть ссылки цитирования, «трансклюзии» – трансклюзируемый контент собирается динамически на клиенте (и может меняться если в документе куда ссылается такая ссылка это место изменилось).

  5. итак, есть исходный иммутабельный поток текста (данные). и метаданные (индексы).

метаданные уровня 0 = блоки, оверлеи, span текста (слайсы как в D, срезы строк). могут быть вложенными или перекрываться.

метаданные уровня 1 = ссылки на блоки, типизированные

метаданные уровня 2 = индексы на метаданные уровня 0,1. например, можно Btree организовать.

  1. это изоморфно представлению компилятора: исходный текст, лексер, парсер. только вот тут не дерево строится, а лес. более общие гиперструктуры на чём-то типа зависимых типов над метаданными уровня 0, 1,2, … 3, 4, 5, …..

  2. возможно сделать потоковый парсер, который не требует жрать память для DOM и вообще древесного представления.

что делает Xanadu браузер? *автомагически динамически вычисляет * по текущему месту в окне из исходного потока текста место в потоке или индексах метаданных, которое нужно чтобы текущее окно показать.

то есть, потоковый парсер, без дерева. хотя наверное можно на метаданных уровне 2 сделать Btree индексы типа «текстовых BSP деревьев», чтобы вычислять только видимое подмножество.

  1. что делает Xanadu редактор? реализует интерфейсы клиент-серверного API (11 принципов Xanadu) для дополнительных операций редактирования типа моноида редактирования (добавить, вставить с заменой, удалить блоки) – наподобие «алгебры патчей» в Darcs. то есть, принципиально важно что «embedded markup considered harmful» это всё – исходный поток не меняется, иммутабельный. дописываются другие потоки патчей.
anonymous ()

Re: гипертекст на зависимых типах, который мы потеряли

  1. что делает Xanadu компилятор? тут сложно сказать, поскольку они пытались делать интерактивную тыкалку сразу с редактором (клиент-серверным, ога) – прям аки метапрог. формальное описание и данных, и протокола есть. другое дело, что прототип у них был довольно малофункциональный.

имхо, было бы разумнее на примерах осознать скриптование чем-то типа pandoc, troff, lout, tex тот же.

есть ощущение, что подобный транслятор можно написать различными способами. как функционально-реактивное программирование, на зависимых типах типа type driven development в Idris, что-то вроде region based, linear typing (или те же reference capabilities в понятине), наконец как метаинтерпретаторы/метакомпиляторы на основе лиспа или пролога, куда-то в метаязыковое надмножество расширенные

  1. ещё есть ощущение, что Literate Programming – это тоже оно. как и его можно реализовать посредством подобного гипертекста на зависимых типах, так и наоборот – использовать LitProg среду разработки для реализации Xanadu.

  2. получается такой довольно универсальный метакомпилятор «из всего во всё», на самом себе. *аки истинный метапрог *

  3. если исходный поток иммутабелен, то далее можно метапрограммировать гипертекст второго порядка. то есть: метаданные уровня 0 текста = исходный поток (уровень -1) метатекста, его метаданные уровня 0 метатекста = исходный поток (уровень -1) метаметатекста и т.п. с метамоделированием во все поля.

  4. если далее какую-то обработку делать такого вот гипертекста, то она а) работает на уровне БД б)не требует закачки всего дерева – только обрабатываемого, начиная с индексов через типизированные ссылки на блоки до самих блоков, слайсов строк и строк исходного потока.

то есть, не требует построения полного DOM и там могут использоваться вот как раз подобные техники типа CTFE GC region-based.

  1. linear typing, linear temporal logic для model checking тоже в ту же тему.

в общем, вот такие вот соображения насчёт «гипертекста, который мы потеряли»

point в том, что наверное, для подобного гипертекста возможна какая-то формальная верификация, какая-то оптимизиция и переработка времени компиляции, времени хранения в БД.

например, исходных потоков может быть несколько (со своим набором индексов).

например, исходный plain text или markdown, asciidoc (1). что-то вроде того же troff(2) или XML (3). что-то вроде lout с функциональной разметкой (4) или tex с императивной (5) – логической, не физической.

если данные+метаданные=моноид, который согласованно обрабатывает все индексы (всех уровней) – то эквивалентные представления могут быть на основе любого (1),(2),(3),(5) (с соответствующими разными, но изоморфными друг другу набором индексов).

то есть, можно например взять какой-то тот же XHTML и к нему примонстрячить такой вот поток индексов для потокового представления, не требуя полного DOM (который жрёт память и неэффективен).

или какой-то другой исходный язык разметки (например, метаязык. например, литературного программирования или ещё что-то удобное).

anonymous ()
Ответ на: комментарий от anonymous

к примеру, вот ролики на факторе

там гипертекст на основе гофера (последним примером). довольно интерактивно.

вот, почему бы далее эту интерактивность и не допиливать в зависимые типы, какую-то litProg среду разработки и такой вот «гипертекст на зависимых типов» из потоков данных+метаданных ???

векторный (даже тензорный, ога) гипертекстовый изначальный – на зависимых типах region-based compile time optimized ???

anonymous ()