Если вы когда-нибудь почувствуете себя глупым, то вспомните, что я разок опоздал на встречу с человеком из-за того, что перепутал станции Октябрьская и Октябрьское поле.
#rust
9 companies using Rust in production.
О некоторых из них я уже рассказывал, но в любом случае иметь сборник лишним не будет.
9 companies using Rust in production.
О некоторых из них я уже рассказывал, но в любом случае иметь сборник лишним не будет.
9 Companies That Use Rust in Production
Who uses Rust, and what are the benefits of choosing this programming language for your stack? Find out the answer in stories from 9 successful companies.
#prog #rust
Синтаксис для условной компиляции (
Синтаксис для условной компиляции (
#[cfg(...)]
) в Rust позволяет использовать условные выражения, но не в очень эргономичном виде: через all
, any
и not
. Библиотека efg позволяет использовать более привычный синтаксис, похожий на то, что пишут в коде на самом Rust. Пример:#[efg(feature "proc-macro" && !(target_arch "wasm32" && target_os "unknown"))]
extern crate proc_macro;
Кстати, написана Толяном.#prog #rust #article
Очередная статья про обработку ошибок в Rust, да. Но полезная: ставит под сомнения и разбирает распространённые мнения об ошибках в Rust. В частности, разбирается совет "anyhow для приложений, thiserror для библиотек".
Очередная статья про обработку ошибок в Rust, да. Но полезная: ставит под сомнения и разбирает распространённые мнения об ошибках в Rust. В частности, разбирается совет "anyhow для приложений, thiserror для библиотек".
Unwoundstack
Rust Error Handling
Some thoughts on how to handle errors in Rust
#prog #rust #моё
Пара слов о фантомных типах и авто-трейтах.
Иногда нам нужно включить нужный функционал, не привязанный к стейту. Примерно так:
Ответ очень прост: достаточно поменять определение поля
Есть, однако, и другой вариант использования фантомных типовых параметров: мы пишем тип данных, который как-то соотносится с неким параметром
Прямолинейным подходом в подобных случаях является использование
Для того, чтобы избежать этих проблем и иметь ограничения
Пара слов о фантомных типах и авто-трейтах.
Иногда нам нужно включить нужный функционал, не привязанный к стейту. Примерно так:
struct OptionA;
struct OptionB;
trait Param {
fn op();
}
impl Param for OptionA { ... }
impl Param for OptionB { ... }
struct Parametrised<P> {
data: Data,
_param: PhantomData<P>,
}
impl<P: Param> Parametrised<P> {
fn func(&mut self) {
self.data.process_foo();
P::op();
self.data.process_bar();
}
}
Вроде выглядит нормально. Однако тут есть подвох: авто-трейты, в отличие от дерайвов для большинства трейтов, смотрят не на типовые параметры, а на типы самих полей. В число авто-трейтов входят также Send
и Sync
. PhantomData (не) имеет те же реализации Send
/Sync
, что и тИповый параметр, которым параметризован. К чему это приводит? Да к тому, что если Parametrised<P>
будет использован в контексте, когда выполнение этих трейтов имеет значение, нам придётся вешать ограничение P: Send/P: Sync
, даже не смотря на то, что значения этих типов не используются вообще. Хуже, это придётся писать даже в том случае, если Data
реализует Send
/Sync
. Что мы можем с этим сделать?Ответ очень прост: достаточно поменять определение поля
_param
:struct Parametrised<P> {
data: Data,
_param: PhantomData<fn(P)>, // <--
}
Таким образом, мы всё ещё включаем тип P
в описание типа Parametrised
, но так как все функциональные указателя безусловно удовлетворяют Send
и Sync
, паразитные ограничения более не возникают.Есть, однако, и другой вариант использования фантомных типовых параметров: мы пишем тип данных, который как-то соотносится с неким параметром
T
, но не включает его напрямую. Использование PhantomData<T>
может быть неправильным в том смысле, что оно показывает, что наш тип логически владеет значением типа T
, что не обязательно является правдой. Более того, так как из-за лайфтаймов на типах в Rust есть отношение субтипизации, в полный рост встают проблемы вариантности.Прямолинейным подходом в подобных случаях является использование
PhantomData
, параметризованных *const T
и *mut T
. Этот подход опирается на тот факт, что *const T
ковариантен по T
, а *mut T
контравариантен по T
, и оба типа не требуют лайфтаймы. Однако тут легко упустить тот момент, что оба типа примитивных указателей безусловно не реализуют ни Send
, ни Sync
, что вкупе с протеканием автотрейтов через PhantomData
может привести к тем же паразитным ограничениям. Причём этот случай это даже хуже, поскольку требует написания реализаций Send
и Sync
вручную, а эти имплы очень легко могут стать неправильными при внесении изменений в код.Для того, чтобы избежать этих проблем и иметь ограничения
Send
/Sync
только на релевантные поля, мы опять воспользуемся тем фактом, что функциональные указатели реализуют Send
и Sync
безусловно, а так же тем фактом, что функциональные типы ковариантны по типу результата и контрвариантны по типу аргумента. Комбинируя эти типы с PhantomData
, мы можем получить нужную нам вариантность без головной боли, связанной с потокобезопасностью. Проиллюстрирую это псевдонимами типов:type Covariant<T> = PhantomData<fn() -> T>;
type Contravariant<T> = PhantomData<fn(T)>;
// ко- и контрвариантность — это про наложение ограничений,
// поэтому совмещение этих требований приводит к
// более строгому отношению: инвариантности (в смысле вариантности)
type Invariant<T> = PhantomData<fn(T) -> T>;
Telegram
Блог*
#prog #rust #article
Статья о #[derive(Clone)] и о том, почему стандартный дерайв-макрос ставит ограничение Clone на тИповые параметры, а не на типы полей.
Статья о #[derive(Clone)] и о том, почему стандартный дерайв-макрос ставит ограничение Clone на тИповые параметры, а не на типы полей.
Что пишут разработчики:
— Наш продукт основан на искусственном интеллекте!
Что слышу я:
— Когда наш софт сломается, мы не будем иметь ни малейшего понятия, как его чинить.
— Наш продукт основан на искусственном интеллекте!
Что слышу я:
— Когда наш софт сломается, мы не будем иметь ни малейшего понятия, как его чинить.
Forwarded from Vlad Beskrovnyi
Вообще, с майнкрафтом вечная история - приходят школьники, начинают учиться программировать и чето под майнкрафт кодят. Получается продсказуемо - всё забаговано и залаговано. Школьники постепенно учатся, вырастают и идут на нормальную работу (по собственному опыту говорю). В майнкрафт приходят новые.
В итоге вечно всё лагает и нихуя не работает. Никто не тестирует ничего под реальными нагрузками. Тесты вообще никто нигде не пишет, ни разу не видел.
В итоге вечно всё лагает и нихуя не работает. Никто не тестирует ничего под реальными нагрузками. Тесты вообще никто нигде не пишет, ни разу не видел.
#prog #lisp #amazingopensource
LISP with GC in 436 bytes (достаточно, чтобы уместиться на загрузочном секторе)
LISP with GC in 436 bytes (достаточно, чтобы уместиться на загрузочном секторе)
justine.lol
LISP with GC in 436 bytes
LISP engine that's tiny enough to fit in a 512-byte master boot record