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

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

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

Генератор траекторий векторных полей. Генерируется в svg, так что качество не теряется. Разумеется, формулы можно задать свои.

За наводку спасибо @sv9t_channel

https://msurguy.github.io/flow-lines/
Github
🎉1
А ещё у меня сегодня день рождения. Ура, что ли
#science

А вот это действительно полезно. Там полно статей на самые разные темы
Forwarded from oleg_log (Oleg Kovalov)
Open Access to ACM Digital Library During Coronavirus Pandemic

For the next three months, there will be no fees assessed for accessing or downloading work published by ACM. We hope this will help researchers, practitioners and students maintain access to our publications as well as increasing visibility and awareness of ACM’s journals, proceedings and magazines. Please be sure to inform your colleagues that the ACM DL is now open, and will continue that way through June 30, 2020.

https://www.acm.org/articles/bulletins/2020/march/dl-access-during-covid-19
DISCLAIMER: Я НЕ БУДУ ДЕЛАТЬ РОЗЫГРЫШИ НА 1 АПРЕЛЯ
#prog #rust
Мой коллега рассказал про изящный способ контроля над фичами библиотек
# методы в трейтах под #[cfg]

Условная компиляция (aka conditional compilation) часто используется в расте, чтобы добавить какой-то функционал только если включена определённая фича. Но есть проблема — в трейтах такое сложно применять т.к. если крейт A реализует твой трейт, но не использует твою фичу, то он отдельно может компилироваться, а с крейтом B, который использует твою фичу — нет т.к. крейт A не реализует требуемую функцию. (я вас не запутал?)

Можно использовать дефолтные реализации, но это путь вникуда. Честно. Никаких unimplemented!(). Пожалуйста.

Настоящее решение проблемы /которое я подсмотрел в serde/ — сделать макрос который с фичей раскрывается то что ему передали, а без — в ничего.

#[cfg(feature = "feature")]
#[macro_export]
macro_rules! if_feature {
($($tt:tt)*) => {
$($tt)*
};
}

#[cfg(not(feature = "feature"))]
#[macro_export]
macro_rules! if_feature {
($($tt:tt)*) => {};
}

Чтобы потом пользователи библиотеки могли легко реализовать твой трейт:

impl Trait for Type {
// ...
lib::if_feature! {
fn uses_feature() {
// ...
}
}
}


#rust #tip
#prog #article

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

flak.tedunangst.com/post/features-are-faults-redux
Блог*
#prog #article Статья о том, как взаимодействие различных фич выливается в уязвимости. Автор, приверженец OpenBSD, предлагает решать проблему отсутствием фич. Радикальный подход, который мне не импонирует, но рассказывает автор убедительно. flak.tedun…
#prog #article

В той статье есть ссылка на эту:

minimal repro:
On Suffolk (one of our machines), open tmux, open vim, open new terminal tab.
Vim gets “lililililililill” inserted in current file, and beeps a lot
If the file already has content, it prepends i and appends ll to ~10 lines, and sometimes capitalizes something


Читается на одном дыхании, как неплохой детектив.

daniellesucher.com/2014/04/24/my-new-favorite-vim-tmux-bug/
#quotes

Но, конечно, это не JS виноват, это плохой код виноват, а Настоящие Программисты никогда так не делают
Forwarded from folex
Ну нет. JS – не норм. Всё имеет доступ ко всему. Всё принимает всё, и возвращает всё. Каждый на свой лад оборачивает значения в свои полупрозрачные обертки с прокидыванием методов.

Где что используется понять невозможно. Откуда берутся методы у объектов понять невозможно. У кого есть ссылка на объект понять невозможно. Всё имеет влияние не всё, сайдэффект на сайдэффекте.

Это как глобальные переменные, только они не объявлены в верхнем скоупе, а пролазят из внутренностей кода наружу, и расползаются, метастазируя стейтом.
Блог* pinned «#article @milfgard опять причиняет интерес. На этот раз — разбор деталей карточной игры в "Пиковой даме". Бы ли б у меня подобные уроки в школе — наверняка куда больше литературу любил. habr.com/ru/company/tuturu/blog/495110/»
#prog #rust #моё

В Rust в некоторых случаях можно использовать анонимный лайфтайм ('_). Практика показывает, что эта фича некоторым не до конца понятна, поэтому я решил написать об этом подробнее.

Времена жизни — пожалуй, именно та фича, которая больше всего делает Rust непохожим на мейнстримные языки программирования. В частности, их синтаксис ('identifier) — это то, что приходит первым на ум тому, кто уверяет, что у Rust нечитаемый синтаксис. Тем не менее, если взглянуть на код программы на Rust, то этих времён жизни можно увидеть очень мало. Казалось бы, как так может быть, если учесть, что каждая ссылка параметризована временем жизни, а ссылки в Rust используются достаточно активно? Дело в том, что бо́льшая часть вариантов использования времён жизни подпадает под один из достаточно простых паттернов, для которых компилятор в состоянии вывести отсутствующие времена жизни сам. Это называется lifetime elision, и правила, по которым оно происходит, перечислены в растономиконе.

Раскрытие сокращённой записи начинается с введения нового явного параметра для каждого аргумента, тип которого параметризован временем жизни (далее ВЖ), но для которого конкретное значение ВЖ не указано. Например, если у нас функция

fn do_something(a: &mut u32, b: (&u32, &u32), c: Cow<str>) { ... }

, то после первого шага преобразования она выглядит так:

fn do_something<'lt1, 'lt2, 'lt3, 'lt4>(a: &'lt1 mut u32, b: (&'lt2 u32, &'lt3 u32), c: Cow<'lt4, str>) { ... }

Обратите внимание, это работает не только с ссылками.

Далее компилятор пытается приписать времена жизни возвращаемому типу. В обычном коде произвольные времена жизни не материализуются из ничего, они появляются из ссылок на имеющиеся значения. Логично предположить, что если у тебя есть функция с ВЖ, то ВЖ возвращаемого типа должно быть связано с аргументами. Если аргументов нет вовсе, то компилятор откажется компилировать функцию. Если аргумент есть только один и с одним обобщенным параметром ВЖ, то возвращаемый тип параметризуется этим ВЖ для всех возможных обобщённых параметров. Например, если есть функция

fn first_and_second(arg: &(u32, u32, u32))- > (&u32, &u32) {
(&arg.0, &arg.1)
}

, то её развёрнутый тип будет

fn first_and_second<'a>(arg: &'a (u32, u32, u32))- > (&'a u32, &'a u32) {
(&arg.0, &arg.1)
}

Что же делать, если аргументов несколько? В случае, когда функция принимает &self или &mut self, ВЖ возвращаемого типа приравнивается ВЖ self. Из этого, кстати, следует несколько неожиданный результат, что нижеприведённый код не компилируется:

struct Foo;

impl Foo {
fn use_str(&self, s: &str) -> &str {
s
}
}

Если расписать тип полностью, то станет понятно, почему:

struct Foo;

impl Foo {
fn use_str<'foo, 's>(&'foo self, s: &'s str) -> &'foo str {
s
}
}

Действительно, lifetime elision приводит к тому, что возвращаемая строка имеет то же ВЖ, что и self, но в теле функции используется строка с другим ВЖ 's, которое никак не связано с 'foo. Для того, чтобы решить эту проблему, нужно явно ввести обобщённый параметр времени жизни и указать, что он один и тот же у аргумента и возвращаемого значения:

struct Foo;

impl Foo {
fn use_str<'s>(&self, s: &'s str) -> &'s str {
s
}
}

Такой код уже компилируется.