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

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
kinda obvious in retrospect
playground
there’s one deref missing and the whole Box gets coerced to dyn Any
🤯5🤬1
😁14👍61🔥1🤔1
#prog #rust и преступления по игнорированию статусов стабильности
from lib never-say-never
GitHub
🤯7🤨2
Forwarded from Discussing Rust snippets for fun and profit
Awful Rust snippets for fun and profit
from lib never-say-never GitHub
причём это в целом усложнение
pub trait Get { type Never; }
impl<R> Get for fn() -> R { type Never = R; }
pub type Never = <fn() -> ! as Get>::Never;
👍4
#prog #rust и абсолютно точная и при этом бестолковая ошибка.

Пусть есть вот такой код:

trait Modify {
fn modify(&mut self);
}

impl<T> Modify for T {
fn modify(&mut self) {
// ...
}
}

trait Foo {
fn mute(&mut self) {
self.modify();
}
}

Этот код не компилируется и выдаёт вот такое сообщение об ошибке:

error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> src/lib.rs:13:9
|
13 | self.modify();
| ^^^^^^^^^^^^^ cannot borrow as mutable

На первый взгляд это выглядит, как полная чепуха: у нас же &mut self, параметр прямо объявлен мутабельным! Однако не всё так просто.

Посмотрим ещё раз на blanket impl для Modify:

impl<T> Modify for T {
fn modify(&mut self) {
// ...
}
}

Тут написано, что трейт Modify реализовывается для некоторого типа T. А вот что тут не написано — так это то, что T удовлетворяет ограничению Sized. Этот трейт — единственный, который добавляется к обобщённым параметрам по умолчанию и, соответственно, Rust имеет синтаксис для того, чтобы это ограничение убрать: ?Sized.

Запомним это и перейдём к декларации Foo:

trait Foo {
fn mute(&mut self) {
self.modify();
}
}

Метод mute имеет реализацию по умолчанию, и так как метод, для которого эта реализация имеется, определён на Self, этот тип не получает никаких ограничений вовсе, в том числе и Sized (и об этом сказано в документации к Sized). Но это не значит, что метод вызвать нельзя! Синтаксис вызова метода может брать ссылку на значение для того, чтобы удовлетворить сигнатуре метода. А подходящая реализация, как ни странно, имеется! Потому что T в impl<T> Modify for T покрывает любые (Sized) типы. Вообще любые. В том числе и... Ссылки.

Что же происходит в реализации по умолчанию метода mute?

* Компилятор не находит реализации Modify для Self...
* ...поэтому также ищет impl-ы, которые позволят скомпилировать со взятием ссылки (то есть фактически (&mut self).modify())...
* ...находит, поскольку у нас есть blanket impl, предоставляющий метод modify для &mut Self (а ссылка — всегда Sized тип)...
* ...проверяет корректность кода <&mut Self as Modify>::modify(&mut self)...
* ...и наталкивается на ошибку, поскольку для взятия мутабельной ссылки от значения нужно, чтобы само значение было мутабельным, а биндинг self — который можно написать явно, как fn mute(self_: &mut Self) { ... } (и за вычетом потери возможности использования синтаксиса вызова через точку это определение эквивалентно) — сам мутабельным не является.

В итоге компилятор и выдаёт такую ошибку, к вящему неудовольствию того несчастного, которому не повезёт напороться на такую ситуацию.

Для сравнения: в C++ нельзя присваивать новое значение this (именно самому this, а не тому, на что this указывает).
👍10🔥1
Блог*
#prog #rust и абсолютно точная и при этом бестолковая ошибка. Пусть есть вот такой код: trait Modify { fn modify(&mut self); } impl<T> Modify for T { fn modify(&mut self) { // ... } } trait Foo { fn mute(&mut self) { self.modify();…
Пока писал пост — вспомнил анекдот про математика и воздушный шар. Попытался найти текст и обнаружил, что к нему придумали продолжение:

...
— А вы, похоже, из управленцев, — заметил математик.
— Я действительно топ-менеджер серьезной компании, — воспрял воздухоплаватель, — Но как вы догадались? Вы видели меня по телевизору?
— Зачем? — удивился математик, — Судите сами: вы не понимаете ни где вы находитесь, ни что вам следует делать, в этом вы полагаетесь на нижестоящих. Спрашивая совета у эксперта, вы ни на секунду не задумываетесь, способны ли вы понять его ответ, и когда оказывается, что это не так — вы возмущаетесь вместо того, чтобы переспросить. Вы находитесь ровно в том же положении, что и до моего ответа, но теперь почему-то обвиняете в этом меня. Наконец, вы находитесь выше других только благодаря дутому пузырю, и если с ним что-то случится — падение станет для вас фатальным.
😁20👍52
#meme про WinRar
Why the heck is it called autotools if it barely automates anything
😁151👍1
Собаки выше всех существ, потому что пёс — это ко-кот, то есть T
🤯4😁3🤔3👍2💩2🥴2
Блог*
#prog #rust #rustlib #article Toward fearless cargo update I recently built cargo-semver-checks, a linter that ensures crates adhere to semantic versioning. This is why and how I built it. В FAQ также есть сравнение с аналогичными инструментами.
#prog #rust #rustlib #article

cargo-semver-checks today and in 2023

Following semver in Rust is a perfect example of a workflow worth automating:

* Important to get right, painful if done wrong: cargo requires all crates to follow semver, so breaking semver in one crate can have a ripple effect across the ecosystem. But if done right, semver is completely invisible.
* Countless complex rules: There are hundreds of ways to cause a breaking change, many of them non-obvious.
* Code that violates semver doesn't look wrong: No code reviewer can be expected to reliably flag most of the semver issues, even assuming they are well-versed in all the semver rules. The evidence on this point is particularly overwhelming (
1, 2, 3, 4, 5).

Some might say the solution is to "git gud". I deeply respect operational excellence, but this is not the way.

Civilization advances at the rate at which we develop robust abstractions. I am writing this on a computer I cannot build, under a blanket I cannot weave, having enjoyed a meal with ingredients I cannot grow. I dedicated ten years to math competitions, and I can't even calculate a logarithm by hand! Can you?

Gatekeeping to only include people with a PhD in "Semver in Rust" won't cut it.

Yosh Wuyts quotes another Rust contributor as saying: "The job of an expert is to learn everything about a field there is to learn, and then distill it so that others don't have to." I couldn't agree more!
👍5
#article

The five-minute feedback fix

We universally accept that shorter feedback cycles are good—working them in between coding and testing, sprint planning and sprint retro, merging and deployment. But two critical areas lack early feedback: requirements and design.<...>

It doesn’t have to be this way. There’s nothing special about designs or requirements that make them impossible to analyze. It’s just that, historically, almost all of our feedback tools are built to analyze code. We never consider requirements or designs as something we can test, too. If we could, we could shorten the feedback cycle on thinking through our code, saving us and our clients a lot of time and money.

<...>

There are other design languages with other tradeoffs, but simply listing a bunch of technologies does not make for a good essay. Instead, let’s take a deep dive into an introductory technique called decision tables. Not only is it effective and widely used in specification, it’s so simple that you’ll be proficient enough to use it yourself by the end of this essay.

Но автор предупреждает:

I like decision tables because they are simple, easy, and powerful. Anybody can learn them in five minutes and use them, even without a technical background. But one thing we didn’t do with them is directly connect the decision table to our code. And this is the main limitation of modern formal specification: There’s no built-in way to guarantee that you faithfully implemented your design. It’s possible, and people have done it, but it takes a lot of hard work to do this.

This is an intentional choice. From experience we know that tools which connect design to code are much, much harder to use, making them less accessible for most programmers. Instead, it focuses on what it is best at: shortening the feedback loop from design to design.
Блог*
#prog #моё Если вы используете регулярные выражения — вам должно быть за это стыдно У регулярных выражений есть куча недостатков, и, на мой взгляд, их слишком часто используют там, где не надо. Сейчас я расскажу о том, что же с ними не так. Проблемы 1.…
#prog #regex #article

The true power of regular expressions

<...>

As the article was quite long, here a summary of the main points:

* The “regular expressions” used by programmers have very little in common with the original notion of regularity in the context of formal language theory.
* Regular expressions (at least PCRE) can match all context-free languages. As such they can also match well-formed HTML and pretty much all other programming languages.
* Regular expressions can match at least some context-sensitive languages.
* Matching of regular expressions is NP-complete. As such you can solve any other NP problem using regular expressions.

But don’t forget: Just because you can, doesn’t mean that you should. Processing HTML with regular expressions is a really bad idea in some cases. In other cases it’s probably the best thing to do.
5