1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
#gamedev

Прототип игры в 3D-ASCII графике. Вещь несколько бессмысленная, но впечатляющая.

https://www.squidi.net/threep/p083/
#prog #rust

Чтобы ускорить сборку своего проекта, достаточно всего лишь... Читать продолжение
#prog #rust #gamedev

Потрясающий туториал по созданию своего рогалика на расте. Уже больше 70 глав!

https://bfnightly.bracketproductions.com/rustbook/chapter_0.html
#quotes (автор, к сожалению, неизвестен)
Forwarded from The Wacky Yellow Dog
@aikidos @Psilon

THE RESTRICT CONTRACT
I, [insert your name], a PROFESSIONAL or AMATEUR [circle one] programmer recognize that there are limits to what a compiler can do. I certify that, to the best of my knowledge, there are no magic elves or monkeys in the compiler which through the forces of fairy dust can always make code faster. I understand that there are some problems for which there is not enough information to solve. I hereby declare that given the opportunity to provide the compiler with sufficient information, perhaps through some key word, I will gladly use said keyword and not bitch and moan about how «the compiler should be doing this for me.»

In this case, I promise that the pointer declared along with the restrict qualifier is not aliased. I certify that writes through this pointer will not effect the values read through any other pointer available in the same context which is also declared as restricted.
#meme

Когда в программисткий чатик заходит девушка
#meme #bio

Простите
Хотел написать что-то по поводу сегодняшней даты, но... Серьёзно, вы же умные люди, вы и так знаете, какой сегодня день. Будет хорошо, если вы поздравите сегодня кого надо. Спасибо.
Forwarded from 💮
В питоне удобно сделали, совместили параллелизм зелёных потоков и накладные расходы нативных тредов.
#prog #моё

Сегодня я хотел бы рассказать о возможных способах реализации полиморфизма в языках программирования и о том, какие выгоды и издержки они имеют. Disclaimer: я не особо шарю, так что могу наговорить глупостей.

Полиморфизм — это свойство кода обрабатывать данные разных типов единым образом. Замечательная вещь, не так ли? К сожалению, истинно полиморфного кода мало: если полиморфная функция делает что-то помимо тасовки аргументов, рано или поздно нужно будет выполнить операцию, специфичную для конкретного типа. Для того, чтобы исполнить полиморфный код, нужно каким-то образом передать в него эти функции для конкретного типа. О том, как это можно сделать и на какие компромиссы при этом приходится идти, я сегодня и расскажу.

1. ad hoc полиморфизм (aka полиморфизм для бедных). В этом варианте мы не прилагаем никаких специальных усилий к обеспечению полиморфизма: достаточно разрешить иметь в языке перегрузку функций. При подстановке конкретного типа в обобщённый код компилятор ищет перегрузки с соответствующими типами и вставляет нужные вызовы.

Достоинства:
* Легко реализовать.

Недостатки:
* Наличие перегрузки сразу ставит вопрос о том, какая перегрузка более специфичная, что усложняет рассуждения о коде.
* Требует наличия в языке механизма написания кода с отложенной проверкой типов (макросы в C и шаблоны в C++ под это определение в данном контексте подходят).
* Непосредственное следствие из предыдущего пункта: ошибки несоответствия типов ловятся по месту использования, а не по месту определения, что затрудняет отладку кода и написание высокообобщённого кода ("У меня не сошлись типы потому, что я неправильно вызвал функцию или потому. что сама функция определена ошибочно?").
* Сам факт обобщённости затруднительно переносить между границами отдельных единиц компиляции (читай, фиг вам, а не динамическая линковка).

Резюмируя: использовать имеет смысл тогда, когда нет других альтернатив.
Блог*
#prog #моё Сегодня я хотел бы рассказать о возможных способах реализации полиморфизма в языках программирования и о том, какие выгоды и издержки они имеют. Disclaimer: я не особо шарю, так что могу наговорить глупостей. Полиморфизм — это свойство кода обрабатывать…
2. Если нам нужно иметь таблицу функций для каждого значения некоего типа, наиболее прямолинейный способ достичь этого — это включить эту таблицу в каждое значение. Так поступают компиляторы всех мейнстримных объектно-ориентированных языков программирования (Java, C#, C++ при использовании классов).

Достоинства:
* Обобщённая функция в скомпилированном коде всего одна для каждой комбинации типов, поэтому итоговый бинарник остаётся достаточно маленьким.
* Если в языке есть интерфейсы, которые могут расширять друг друга, то можно организовать таблицы функций (vtable) таким образом, чтобы vtable для интерфейса Bar, расширяющего интерфейс Foo, начиналась с vtable интерфейса Foo. Таким образом можно получить повышающее преобразование (upcast), которое ничего не стоит в рантайме.
* Нормальная проверка типов: ошибки ловятся в определении обобщённой функции, если функция неправильна определена, и на месте использования при вызове с неправильными типами аргументов.
* Нормально работает с динамической линковкой.

К сожалению, в этом бочонке мёда есть ковш дёгтя:
* (Этот пункт относится главным образом к вышеупомянутым мейнстримным ООП ЯП, которые смешивают наследование интерфейса и наследование данных) Так как размер конкретного типа вызываемой функции неизвестен, аргументы приходится передавать по указателю (это можно обойти, но с весьма нетривиальными ухищрениями), то есть как минимум первое обращение к аргументу косвенное (последующие могут быть напрямую, если данные остались в кеше процессора). Если созданный аргумент выходит за пределы функции, в которой был создан, то его приходится выделять в куче.
* Если мы хотим иметь в языке расширяемые интерфейсы (а мы хотим, чтобы не копипастить всё руками), то мы не можем напрямую включать vtable в само значение, потому что мы не знаем размера этой vtable наперёд. Поэтому обращение к функциям проходит через ещё один указатель. Конечно, если мы знаем, что интерфейс нерасширяем, то мы можем включить эти функции напрямую, но: а) в этом случае upcast сломается; б) vtable будет занимать в кеше место, оставляя меньше места под поля аргумента.
* Если мы хотим иметь возможность реализовывать несколько интерфейсов для типов (а мы хотим), то придётся держать несколько таблиц, и так как их число наперёд неизвестно, то их придётся держать в динамическом списке (+1 индирекция) и при апкасте к разным интерфейсам либо при каждом обращении искать нужную таблицу, либо менять порядок таблиц в рантайме, так что по факту бесплатный upcast мы теряем.
* Так как у каждого отдельного аргумента потенциально своя vtable, мы не можем толком иметь функции вида fn<T>(arg1 T, arg T) -> T, что очень — нет, не так — ОЧЕНЬ сильно ограничивает выразительность системы типов.
* Получить доступ к vtable можно только в том случае, если у нас есть на руках значение нужного типа, поэтому мы не можем иметь функции вида fn default<T>() -> T и fn from_str<T>(string s) -> T.