<p>“Functions should not produce abstract side effects...only commands
(procedures) will be permitted to produce side effects.” - Bertrand Meyer:
ObjectOriented Software Construction</p>
Object-Oriented Software Construction</p>
<h2id="a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa"><aclass="header"href="#a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa"><ahref="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of least astonishment (POLA)</a></a></h2>
<p>a component of a system should behave in a way that most users will expect it
to behave. The behavior should not astonish or surprise users</p>
when you are deciding which argument type to use for a function argument.
In this way, the function will accept more input types.</p>
<p>This is not limited to slice-able or fat pointer types.
In fact you should always prefer using the <strong>borrowed type</strong> over
In fact, you should always prefer using the <strong>borrowed type</strong> over
<strong>borrowing the owned type</strong>.
Such as <code>&str</code> over <code>&String</code>, <code>&[T]</code> over <code>&Vec<T></code>, or <code>&T</code> over <code>&Box<T></code>.</p>
<p>Using borrowed types you can avoid layers of indirection for those instances
@ -176,7 +176,7 @@ is a technique that enables separation of concerns.
It also allows to decouple software modules through <ahref="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion</a>.</p>
<p>The basic idea behind the Strategy pattern is that, given an algorithm solving
a particular problem, we define only the skeleton of the algorithm at an abstract
level and we separate the specific algorithm’s implementation into different parts.</p>
level, and we separate the specific algorithm’s implementation into different parts.</p>
<p>In this way, a client using the algorithm may choose a specific implementation,
while the general algorithm workflow remains the same. In other words, the abstract
specification of the class does not depend on the specific implementation of the
@ -186,7 +186,7 @@ This is why we call it "Dependency Inversion".</p>
<p>Imagine we are working on a project that generates reports every month.
We need the reports to be generated in different formats (strategies), e.g.,
in <code>JSON</code> or <code>Plain Text</code> formats.
But things vary over time and we don't know what kind of requirement we may get
But things vary over time, and we don't know what kind of requirement we may get
in the future. For example, we may need to generate our report in a completly new
format, or just modify one of the existing formats.</p>
@ -205,7 +205,7 @@ characteristics, and a clean boundary of what is safe and what is <code>unsafe</
<p>The POSIX standard defines the API to access an on-file database, known as <ahref="https://web.archive.org/web/20210105035602/https://www.mankier.com/0p/ndbm.h">DBM</a>.
It is an excellent example of an "object-based" API.</p>
<p>Here is the definition in C, which hopefully should be easy to read for those
involved in FFI. The commentary below should help explaining it for those who
involved in FFI. The commentary below should help explain it for those who
<p>When developing programs, we have to solve many problems.
A program can be viewed as a solution to a problem.
It can also be viewed as a collection of solutions to many different problems.
It can also be viewed as a collection of solutions to many problems.
All of these solutions work together to solve a bigger problem.</p>
<h2id="design-patterns-in-rust"><aclass="header"href="#design-patterns-in-rust">Design patterns in Rust</a></h2>
<p>There are many problems that share the same form.
@ -220,7 +220,7 @@ goal in design, and unnecessary complexity should be avoided".</p>
when you are deciding which argument type to use for a function argument.
In this way, the function will accept more input types.</p>
<p>This is not limited to slice-able or fat pointer types.
In fact you should always prefer using the <strong>borrowed type</strong> over
In fact, you should always prefer using the <strong>borrowed type</strong> over
<strong>borrowing the owned type</strong>.
Such as <code>&str</code> over <code>&String</code>, <code>&[T]</code> over <code>&Vec<T></code>, or <code>&T</code> over <code>&Box<T></code>.</p>
<p>Using borrowed types you can avoid layers of indirection for those instances
@ -424,7 +424,7 @@ fn main() {
conf.check = true;
println!("conf = {:#?}", conf);
// partial initalization with default values, creates the same instance
// partial initialization with default values, creates the same instance
let conf1 = MyConfiguration {
check: true,
..Default::default()
@ -487,7 +487,7 @@ its data if the only way to access each datum is via the collection and the
collection is responsible for deleting the data (even in cases of shared
ownership, some kind of borrowed view may be appropriate). If a collection owns
its data, it is usually useful to provide a view of the data as borrowed so that
it can be multiply referenced.</p>
it can be multiplied referenced.</p>
<p>Most smart pointers (e.g., <code>Foo<T></code>) implement <code>Deref<Target=T></code>. However,
collections will usually dereference to a custom type. <code>[T]</code> and <code>str</code> have some
language support, but in the general case, this is not necessary. <code>Foo<T></code> can
@ -501,7 +501,7 @@ slicing syntax. The target will be the borrowed view.</p>
<divid="chapter_begin"style="break-before: page; page-break-before: always;"></div><h1id="finalisation-in-destructors"><aclass="header"href="#finalisation-in-destructors">Finalisation in destructors</a></h1>
<p>We can dynamically dispatch over multiple values, however, to do so, we need
@ -1098,7 +1098,7 @@ system's ability to return zeroed memory (which is quite fast).</p>
<divid="chapter_begin"style="break-before: page; page-break-before: always;"></div><h1id="iterating-over-an-option"><aclass="header"href="#iterating-over-an-option">Iterating over an <code>Option</code></a></h1>
<p>What if in some cases we want a type to behave similar to another type or
enforce some behaviour at compile time where using only type aliases would
enforce some behaviour at compile time when using only type aliases would
not be enough?</p>
<p>For example, if we want to create a custom <code>Display</code> implementation for <code>String</code>
due to security considerations (e.g. passwords).</p>
@ -1909,7 +1909,7 @@ is a technique that enables separation of concerns.
It also allows to decouple software modules through <ahref="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion</a>.</p>
<p>The basic idea behind the Strategy pattern is that, given an algorithm solving
a particular problem, we define only the skeleton of the algorithm at an abstract
level and we separate the specific algorithm’s implementation into different parts.</p>
level, and we separate the specific algorithm’s implementation into different parts.</p>
<p>In this way, a client using the algorithm may choose a specific implementation,
while the general algorithm workflow remains the same. In other words, the abstract
specification of the class does not depend on the specific implementation of the
@ -1919,7 +1919,7 @@ This is why we call it "Dependency Inversion".</p>
<p>Imagine we are working on a project that generates reports every month.
We need the reports to be generated in different formats (strategies), e.g.,
in <code>JSON</code> or <code>Plain Text</code> formats.
But things vary over time and we don't know what kind of requirement we may get
But things vary over time, and we don't know what kind of requirement we may get
in the future. For example, we may need to generate our report in a completly new
format, or just modify one of the existing formats.</p>
@ -2573,7 +2573,7 @@ characteristics, and a clean boundary of what is safe and what is <code>unsafe</
<p>The POSIX standard defines the API to access an on-file database, known as <ahref="https://web.archive.org/web/20210105035602/https://www.mankier.com/0p/ndbm.h">DBM</a>.
It is an excellent example of an "object-based" API.</p>
<p>Here is the definition in C, which hopefully should be easy to read for those
involved in FFI. The commentary below should help explaining it for those who
involved in FFI. The commentary below should help explain it for those who
<p>“Functions should not produce abstract side effects...only commands
(procedures) will be permitted to produce side effects.” - Bertrand Meyer:
ObjectOriented Software Construction</p>
Object-Oriented Software Construction</p>
<h2id="a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa"><aclass="header"href="#a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa"><ahref="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of least astonishment (POLA)</a></a></h2>
<p>a component of a system should behave in a way that most users will expect it
to behave. The behavior should not astonish or surprise users</p>