Блог*
#music Я всё ещё считаю, что Bytenommer незаслуженно непопулярен. И этот трек, пожалуй, пока что наилучшее из того, что он сделал. youtube.com/watch?v=Lp2TxF8KTOM
YouTube
9bit Chiptune: Bytenommer – It was the Best of Times
Happy new year 2023 with a new tune!
The chime sample is from pjcohen at Freesound: https://freesound.org/people/pjcohen/sounds/414558/
Twitter: https://twitter.com/bytenommer
Soundcloud: https://soundcloud.com/user-565017399
#9bit #fakebit #8bit #chiptune…
The chime sample is from pjcohen at Freesound: https://freesound.org/people/pjcohen/sounds/414558/
Twitter: https://twitter.com/bytenommer
Soundcloud: https://soundcloud.com/user-565017399
#9bit #fakebit #8bit #chiptune…
Forwarded from Awful Rust snippets for fun and profit
kinda obvious in retrospect
playground
there’s one deref missing and the whole Box gets coerced to dyn Any
playground
🤯5🤬1
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 и абсолютно точная и при этом бестолковая ошибка.
Пусть есть вот такой код:
Посмотрим ещё раз на blanket impl для
Запомним это и перейдём к декларации
Что же происходит в реализации по умолчанию метода
* Компилятор не находит реализации
* ...поэтому также ищет impl-ы, которые позволят скомпилировать со взятием ссылки (то есть фактически
* ...находит, поскольку у нас есть blanket impl, предоставляющий метод
* ...проверяет корректность кода
* ...и наталкивается на ошибку, поскольку для взятия мутабельной ссылки от значения нужно, чтобы само значение было мутабельным, а биндинг
В итоге компилятор и выдаёт такую ошибку, к вящему неудовольствию того несчастного, которому не повезёт напороться на такую ситуацию.
Для сравнения: в C++ нельзя присваивать новое значение this (именно самому
Пусть есть вот такой код:
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
указывает).GitHub
Improve compile error for borrowing mut while missing Sized trait bound · Issue #93078 · rust-lang/rust
Given the following code: trait Modify { fn modify(&mut self) ; } impl<T> Modify for T { fn modify(&mut self) { // ... } } trait Foo { fn mute(&mut self) { sel...
👍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👍5❤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!
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!
predr.ag
cargo-semver-checks today and in 2023
40,000 downloads, 30 lints, and many prevented semver issues in the real world. We're just getting started.
👍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.
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.
GitHub
The five-minute feedback fix
Got 5 minutes? @hillelogram has a formal feedback method you can learn to deliver high-quality software that’s cheaper and faster:
Блог*
#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.
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