Хотя, я туплю: если изначально считать переменные «указателями на место на стеке», и оператор . - взятием адреса на элемент структуры, то всё выходит более-менее стройно без вырвиглазного синтаксиса:
type Vec2 struct {
x: float
y: float
}
type VecPair struct {
v1: Vec2
v2: ^Vec2
}
var v VecPair
v.v1.x ^= 1 // используя адрес v, получить адрес v1,
// потом адрес x и записать по этому адресу 1
v.v1.y ^= v.v1.x^ + 4 // нужно получить значение, лежащее по адресу v.v1.x
v.v2 ^= malloc(sizeof(Vec2)) // записали поинтер на выделенную память
// по адресу поля v.v2
v.v2^ ^= v.v1^ // получили значение v.v1, как структуру (а не её адрес),
// и записали её по адресу, хранящемуся в v.v2
v.v2^.x ^+= v.v2^.y^
Конечно, получение значения полей через разименование всё ещё выглядит наркомански.
К тому же возникает вопрос, какова сущность v.v1^ ? Это получается «значение структуры без адреса». Можно ли у него взять значение поля x(тоже без адреса)? Каждой для этого может быть синтаксис? Можно ли дать ему имя, не копируя по другому адресу? И потом получить значение его поля x?
Можно предположить, что оператор ., примененный к безадресному значению, возвращает безадресное значение:
xv = v.v1^ // xv - безадресное значение, и потому "иммутабельно"
// xv.x = 3 - так сделать нельзя
// xv.x ^= 3 - и так тоже
v.v2^.x ^= xv.x // а так можно. xv.x не нужно разименовывать,
// т.к. это уже значение, а не адрес
v.v2^ ^= xv // и так можно
Но не очень нравится, что оператор . становится полиморфным.
Нашел язык: https://austral-lang.org/tutorial/borrowing . Они, правда, обзывают поинтеры ссылками (reference). Проблему решают несколько иначе: вместо неявного взятия значения и явного взятия адреса поступают ровно наоборот - цепочка перехода по поинтерам имеет простой синтаксис, а вот взятие значения по принтеру потом явное.
Мне кажется, должен быть какой-то третий вариант. И синтаксис разименования ближе к паскалевскому.
type Vec2 struct {
x: float
y: float
}
type VecPair struct {
v1: Vec2
v2: ^Vec2
}
var v VecPair
&v^&v1^&x ^= 1
&v^&v1^&y ^= v.v1.x + 4
&v^&v2 ^= malloc(sizeof(Vec2))
v.v2^&x ^= 2
v.v2^&y ^= v.v2^.x + 5
Выглядит, правда, по-наркомански или слегка шизоидно. Зато все операции довольно однозначны, и нет «ссылок».
Вдохновляюще! Меня постоянно останавливают сомнения, а Вы взяли и сделали.
Понимаю, откуда берётся обилие амперсандов: пытаетесь не допустить «ссылки» как сущности в концепт языка. Если задуматься, то в C «ссылки» возникают помтоянно, но о них не принято говорить, прикрываясь терминами lvalue. Но когда в C++ пытаются обобщить внутренние механики разименования C на результаты вызовов функций (а не только проход по полям структур и поинтерам), то без явной сущности «ссылка» уже не вырулить. Мне не очень понятно, смогли вы распутать клубок или пошли не в ту сторону. В любом случае, о причине мы явно думаем похожим образом.
Попытку уйти от «ссылки» я видел еще в одном языке. К сожалению, быстро не вспомню. Поищу в закладках потом.
else в циклах - это зачёт! Питон имеет else в циклах, но почему функциональные языки до него не «догадываются» (тот же Ocaml, например), для меня загадка.
Что плохо - способ описания примитивных типов и поинтеров на типы. Вырвиглазненько.
Ещё не очень понимаю потребность в eval. Зачем вам такое хардкорное разделение на стейтменты и экспрешены? Мне кажется, разделения на декларации и экспрешены будет достаточно: если следующий элемент не декларация, начинающаяся с ключевого слова (тот же func), значит это - экспрешн. Присвоение тоже можно оставит экспрешеном, как в С.
У списка нет элементов, окститесь. Список - это массив с поинтерами на объекты. Можете это проверить, сохранив один и тот же объект в список (или даже в разные списки), и так же на итерации позвав id от «элемента»
Подсказка: замыкание где? В «контейнере», или в code object?
Кузнечик сделан по канонам, позволяющим эффективную хардварную реализацию. Увы, они же обрекают софтварную на тормоза. Эта проблема была и у AES, пока во все процессоры не завезли соответствующие инструкции. Но, по не понятной причине, даже Эльбрус не содержит инструкций для Магмы и Кузнечика.
В том-то и дело, что у Helix - не Vim, а дальнейшее развитие идеи. Причём первым «post-Vim» был Kakoune, и его вариант мне нравится больше. Автор Helix решил, что сделает ещё лучше, и сделал по своему. На мой взгляд, получилось хуже, чем у Kakoune.
Но как IDE , Helix превзошёл Kakoune на текущий момент.
У LLVM JIT есть одна беда: компилирует он достаточно долго. Потому успешные применения его замечены только применительно к математике, когда время выполнения кода изначально подразумевается гораздо больше, чем время компиляции: Julia, Numba, … Либо его применяют как «самый крутой уровень jit для супер горячих циклов», как в каком-то из JS движков.
В том же PostgreSQL приходится настройкой (выставленной по умолчанию) подсказывать оптимизатору, что JIT на быстрых запросах делать вредно. Как раз потому, что компиляция LLVM может занять времени больше, чем выполнение запроса без неё.
Потому все адекватные JIT, заточенные под код общего назначения, самописные.
Чтобы эксперимент считался корректным, Вы должны были повторить его с отключенным HT. Если просадки не будет, то Вы правы. А пока лишь вывод «не запускайте числодробилку в сервере БД».
Хотя, я туплю: если изначально считать переменные «указателями на место на стеке», и оператор
.- взятием адреса на элемент структуры, то всё выходит более-менее стройно без вырвиглазного синтаксиса:Конечно, получение значения полей через разименование всё ещё выглядит наркомански.
К тому же возникает вопрос, какова сущность
v.v1^? Это получается «значение структуры без адреса». Можно ли у него взять значение поляx(тоже без адреса)? Каждой для этого может быть синтаксис? Можно ли дать ему имя, не копируя по другому адресу? И потом получить значение его поляx?Можно предположить, что оператор
., примененный к безадресному значению, возвращает безадресное значение:Но не очень нравится, что оператор
.становится полиморфным.Нашел язык: https://austral-lang.org/tutorial/borrowing . Они, правда, обзывают поинтеры ссылками (reference). Проблему решают несколько иначе: вместо неявного взятия значения и явного взятия адреса поступают ровно наоборот - цепочка перехода по поинтерам имеет простой синтаксис, а вот взятие значения по принтеру потом явное.
Мне кажется, должен быть какой-то третий вариант. И синтаксис разименования ближе к паскалевскому.
Выглядит, правда, по-наркомански или слегка шизоидно. Зато все операции довольно однозначны, и нет «ссылок».
Вдохновляюще! Меня постоянно останавливают сомнения, а Вы взяли и сделали.
Понимаю, откуда берётся обилие амперсандов: пытаетесь не допустить «ссылки» как сущности в концепт языка. Если задуматься, то в C «ссылки» возникают помтоянно, но о них не принято говорить, прикрываясь терминами lvalue. Но когда в C++ пытаются обобщить внутренние механики разименования C на результаты вызовов функций (а не только проход по полям структур и поинтерам), то без явной сущности «ссылка» уже не вырулить. Мне не очень понятно, смогли вы распутать клубок или пошли не в ту сторону. В любом случае, о причине мы явно думаем похожим образом.
Попытку уйти от «ссылки» я видел еще в одном языке. К сожалению, быстро не вспомню. Поищу в закладках потом.
else в циклах - это зачёт! Питон имеет else в циклах, но почему функциональные языки до него не «догадываются» (тот же Ocaml, например), для меня загадка.
Что плохо - способ описания примитивных типов и поинтеров на типы. Вырвиглазненько.
Ещё не очень понимаю потребность в eval. Зачем вам такое хардкорное разделение на стейтменты и экспрешены? Мне кажется, разделения на декларации и экспрешены будет достаточно: если следующий элемент не декларация, начинающаяся с ключевого слова (тот же func), значит это - экспрешн. Присвоение тоже можно оставит экспрешеном, как в С.
У списка нет элементов, окститесь. Список - это массив с поинтерами на объекты. Можете это проверить, сохранив один и тот же объект в список (или даже в разные списки), и так же на итерации позвав id от «элемента»
Подсказка: замыкание где? В «контейнере», или в code object?
userver использует boost context, вроде.
В питоне тоже на каждой итерации создаётся лямбда-объект. Можете легко это проверить с помощью
print(id(l))во втором цикле.Wild?
Скорость?
Кузнечик сделан по канонам, позволяющим эффективную хардварную реализацию. Увы, они же обрекают софтварную на тормоза. Эта проблема была и у AES, пока во все процессоры не завезли соответствующие инструкции. Но, по не понятной причине, даже Эльбрус не содержит инструкций для Магмы и Кузнечика.
Сколько получилось выжать?
В том-то и дело, что у Helix - не Vim, а дальнейшее развитие идеи. Причём первым «post-Vim» был Kakoune, и его вариант мне нравится больше. Автор Helix решил, что сделает ещё лучше, и сделал по своему. На мой взгляд, получилось хуже, чем у Kakoune.
Но как IDE , Helix превзошёл Kakoune на текущий момент.
Нет, у ARM уже давно есть микрокод. Но может только для отдельных, особо заковыристых инструкций.
У LLVM JIT есть одна беда: компилирует он достаточно долго. Потому успешные применения его замечены только применительно к математике, когда время выполнения кода изначально подразумевается гораздо больше, чем время компиляции: Julia, Numba, … Либо его применяют как «самый крутой уровень jit для супер горячих циклов», как в каком-то из JS движков.
В том же PostgreSQL приходится настройкой (выставленной по умолчанию) подсказывать оптимизатору, что JIT на быстрых запросах делать вредно. Как раз потому, что компиляция LLVM может занять времени больше, чем выполнение запроса без неё.
Потому все адекватные JIT, заточенные под код общего назначения, самописные.
Kate довольно хорошо умеет LSP. Правда, сам по себе не всегда удобный и стабильный.
Консольный Helix тоже умеет хорошо LSP и TreeSitter. Он шустрый и стабильный. Но система движения не всегда удобная (post-vim).
Хмм… а я issue открыл на эту тему…
Я конечно нуб в теме парсеров, но идею со стеком считаю великолепной!
В первый раз вижу такое сочетание парсер-комбинаторов и стэка.
До момента фактического увольнения всегда можно включить заднюю. Конечно, смотреть будут потом косо. Но технически это возможно.
Тема
сисеквзлома RSA-4096, SHA-256 и AES не раскрыта.Надо бы обновить Wiki
Если это DDoS, то 1000-3000 запросов - это только на один сервер. И ещё на тысячи других серверов по 1-3т. Получаются уже миллионы.
Не знаю, сколько всего ntp серверов в мире, потому «миллионы запросов» скорее всего маленькая оценка.
Чтобы эксперимент считался корректным, Вы должны были повторить его с отключенным HT. Если просадки не будет, то Вы правы. А пока лишь вывод «не запускайте числодробилку в сервере БД».
А как с циклами боролись?