<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Home on A journey into a wild pointer</title>
    <link>https://carette.xyz/</link>
    <description>Recent content in Home on A journey into a wild pointer</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 14 Aug 2026 12:00:00 +0200</lastBuildDate><atom:link href="https://carette.xyz/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Free of GitHub</title>
      <link>https://carette.xyz/posts/free-of-github/</link>
      <pubDate>Fri, 14 Aug 2026 12:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/free-of-github/</guid>
      <description>&lt;p&gt;GitHub was a source of joy for me since day one: a platform to connect with other nerds, discover new cool projects, read code and learn, which made me better&amp;hellip;
This was great.&lt;/p&gt;
&lt;p&gt;But over time, the platform, and the internet, has deeply changed.&lt;/p&gt;
&lt;p&gt;I don’t follow the current AI trend (and I don’t share the enthusiasm for AI agents), and I no longer learn anything new on this platform. Except that GitHub is now poorly managed and maintained by developers who don’t seem to care&amp;hellip;&lt;/p&gt;
&lt;p&gt;I’ve been gradually deprecating my GitHub account over the past few months.&lt;br&gt;
And as of today, it’s been a month since I last touched, contributed to, or pushed anything to the platform.&lt;br&gt;
I decided to write software for me, on my own place, on my own terms, and to expose it if I really think this can benefit for anyone else.&lt;/p&gt;
&lt;p&gt;Before the AI shift, my default was to make everything public, and on GitHub.&lt;br&gt;
But as the internet has become more agent-driven, I’ve switched to keeping things private and local by default.&lt;br&gt;
This won’t have any impact on the internet at all.
However, this will have a positive impact on the way I work, and on how I manage my time for my hobbies such as programming or making games.&lt;/p&gt;
&lt;p&gt;I will keep the account open to publish or respond to issues, or to submit pull requests. Otherwise, I won’t publish new projects or updates there.&lt;/p&gt;
&lt;p&gt;Thank you if you were a follower of my GitHub account.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Blame</title>
      <link>https://carette.xyz/blame/</link>
      <pubDate>Sat, 08 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://carette.xyz/blame/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;The ideas shared here are mine alone and are not endorsed by my past or current employers.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I am a senior systems engineer and game engine programmer, living in Grand-Est region (France).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;contact&#34;&gt;
  Contact
  &lt;a class=&#34;anchor&#34; href=&#34;#contact&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Feel free to send &amp;ldquo;hi&amp;rdquo; at &lt;a href=&#34;mailto:dev@carette.xyz&#34;&gt;dev[at]carette[dot]xyz&lt;/a&gt;.&lt;br&gt;
My public GPG key to contact me privately is available &lt;a href=&#34;https://carette.xyz/dev@carette.xyz.key&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;work-experience&#34;&gt;
  Work experience
  &lt;a class=&#34;anchor&#34; href=&#34;#work-experience&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My resume, in &lt;a href=&#34;https://carette.xyz/CARETTE_EN_cv.pdf&#34;&gt;English&lt;/a&gt;.&lt;br&gt;
My &lt;a href=&#34;https://www.mobygames.com/person/1368928/antonin-carette/&#34;&gt;MobyGames profile&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please take a look at &lt;a href=&#34;https://carette.xyz/projects&#34;&gt;this page&lt;/a&gt; for my past projects and publications.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;interesting-links&#34;&gt;
  Interesting links
  &lt;a class=&#34;anchor&#34; href=&#34;#interesting-links&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://users.ece.utexas.edu/~adnan/pike.html&#34;&gt;Blog Article - Rob Pike&amp;rsquo;s 5 Rules of Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://highscalability.com/numbers-everyone-should-know&#34;&gt;Blog Article - Jeff Dean&amp;rsquo;s Numbers Everyone Should Know&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kotaku.com/the-exceptional-beauty-of-doom-3s-source-code-5975610&#34;&gt;Blog Article - The Exceptional Beauty of Doom 3&amp;rsquo;s Source Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.usc.edu/~douglast/202/lecture23/manifesto.html&#34;&gt;Manifesto - The Hacker&amp;rsquo;s Manifesto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=9vz06QO3UkQ&#34;&gt;Youtube - The Internet&amp;rsquo;s Own Boy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=ZSRHeXYDLko&#34;&gt;Youtube - Jonathan Blow, Preventing the End of Civilization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=0SARbwvhupQ&#34;&gt;Youtube - The Myth of the Genius Programmer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Projects</title>
      <link>https://carette.xyz/projects/</link>
      <pubDate>Sat, 08 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://carette.xyz/projects/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;books-and-research-papers&#34;&gt;
  Books and research papers
  &lt;a class=&#34;anchor&#34; href=&#34;#books-and-research-papers&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;books&#34;&gt;
  Books
  &lt;a class=&#34;anchor&#34; href=&#34;#books&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2017, &lt;a href=&#34;https://www.packtpub.com/application-development/mastering-rust&#34;&gt;Mastering Rust, Vesa Kaihlavirta (PACKT)&lt;/a&gt; - official reviewer&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;research-papers&#34;&gt;
  Research papers
  &lt;a class=&#34;anchor&#34; href=&#34;#research-papers&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2016, &lt;a href=&#34;https://hal.inria.fr/hal-01403485&#34;&gt;Investigating the Energy Impact of Android Smells&lt;/a&gt; - &lt;em&gt;accepted to &lt;a href=&#34;http://saner.aau.at&#34;&gt;SANER 2017&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;2015, &lt;a href=&#34;https://hal.inria.fr/hal-01279620&#34;&gt;A Learning Algorithm for Change Impact Prediction: Experimentation on 7 Java Applications&lt;/a&gt; - &lt;a href=&#34;http://promisedata.org/raise/2016/&#34;&gt;RAISE 2016&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;blog-posts-talks--presentations&#34;&gt;
  Blog posts, talks &amp;amp; presentations
  &lt;a class=&#34;anchor&#34; href=&#34;#blog-posts-talks--presentations&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;professional-blog-posts&#34;&gt;
  Professional blog posts
  &lt;a class=&#34;anchor&#34; href=&#34;#professional-blog-posts&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2020, &lt;a href=&#34;https://medium.com/tadaweb/security-by-design-a-brief-introduction-to-rust-378060e45038&#34;&gt;Security By Design, A Brief Introduction to Rust&lt;/a&gt;, &lt;a href=&#34;https://www.tadaweb.com&#34;&gt;Tadaweb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2017, &lt;a href=&#34;https://blog.derniercri.io/julia-le-langage-qui-les-r%C3%A9unifiera-tous-3a274cb8794f/&#34;&gt;Julia, le langage qui les réunifiera tous ?&lt;/a&gt;, &lt;a href=&#34;http://www.derniercri.io&#34;&gt;Dernier Cri&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2017, &lt;a href=&#34;https://blog.derniercri.io/d%C3%A9ployer-une-app-phoenix-sur-heroku-sans-conna%C3%AEtre-phoenix-29f3bfb95411/&#34;&gt;Déployer une app Phoenix sur Heroku, sans connaître Phoenix&lt;/a&gt;, &lt;a href=&#34;http://www.derniercri.io&#34;&gt;Dernier Cri&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2016, &lt;a href=&#34;https://blog.derniercri.io/fausse-id%C3%A9es-sur-le-big-data-777114dd763e/&#34;&gt;Fausses idées sur le big data&lt;/a&gt;, &lt;a href=&#34;http://www.derniercri.io&#34;&gt;Dernier Cri&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;talks--public-presentations&#34;&gt;
  Talks &amp;amp; Public presentations
  &lt;a class=&#34;anchor&#34; href=&#34;#talks--public-presentations&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2018, &lt;a href=&#34;https://www.youtube.com/watch?v=TJsPCI81Kzo&#34;&gt;L&amp;rsquo;apprentissage automatique, c&amp;rsquo;est pas automatique (Machine Learning is not magic)&lt;/a&gt;, &lt;a href=&#34;http://takeoff.rocks/past-events/2018-05-15-lille/&#34;&gt;TakeOff Talks&lt;/a&gt;, Lille (France)&lt;/li&gt;
&lt;li&gt;2018, &lt;a href=&#34;https://www.youtube.com/watch?v=Fn0TZCt_Fno&#34;&gt;Why you should take a look at Rust - an easy introduction to the Rust programming language&lt;/a&gt;, &lt;a href=&#34;https://fosdem.org/2018/&#34;&gt;FOSDEM&lt;/a&gt;, Bruxelles (Belgium)&lt;/li&gt;
&lt;li&gt;2017, &lt;a href=&#34;https://carette.xyz/presentations/lillefp_rust_2302.pdf&#34;&gt;Why you should take a look at Rust&lt;/a&gt;, &lt;a href=&#34;https://www.meetup.com/fr-FR/Lille-FP/events/237497716/&#34;&gt;LilleFP Meetup&lt;/a&gt;, Lille (France)&lt;/li&gt;
&lt;li&gt;2016, &lt;a href=&#34;https://carette.xyz/presentations/rust_talk_derniercri_1412.pdf&#34;&gt;Why you should take a look at Rust&lt;/a&gt;, &lt;a href=&#34;http://www.derniercri.io&#34;&gt;Dernier Cri&lt;/a&gt;, Lille (France)&lt;/li&gt;
&lt;li&gt;2016, &lt;a href=&#34;https://carette.xyz/presentations/m2-mocad-internship.pdf&#34;&gt;Eco-design of Android applications&lt;/a&gt;, &lt;a href=&#34;http://www.latece.uqam.ca&#34;&gt;Latece team&lt;/a&gt;, UQAM (Canada)&lt;/li&gt;
&lt;li&gt;2016, &lt;a href=&#34;https://carette.xyz/presentations/m2-mocad-projet.pdf&#34;&gt;State of art about energy consumption models, for mobile devices&lt;/a&gt;, &lt;a href=&#34;http://www.lifl.fr/emeraude/&#34;&gt;Emeraude team&lt;/a&gt;, IRCICA (France)&lt;/li&gt;
&lt;li&gt;2015, &lt;a href=&#34;https://github.com/k0pernicus/PropL&#34;&gt;Software development to study bugs propagation in Java applications&lt;/a&gt;, &lt;a href=&#34;https://sequel.lille.inria.fr&#34;&gt;SequeL team&lt;/a&gt;, INRIA (France)&lt;/li&gt;
&lt;li&gt;2015, &lt;a href=&#34;https://github.com/k0pernicus/PJI2015/blob/master/rapport/Rapport.pdf&#34;&gt;Serious-game development, based on distributed artificial intelligence&lt;/a&gt;, &lt;a href=&#34;https://www.cristal.univ-lille.fr/?rubrique29&amp;amp;eid=17&#34;&gt;SMAC team&lt;/a&gt;, CRIStAL (France)&lt;/li&gt;
&lt;li&gt;2014, &lt;a href=&#34;https://github.com/k0pernicus/Rapport_Stage_S6/blob/master/Rapport_Stage_Vidjil_CARETTE_ANTONIN.pdf&#34;&gt;Software developer for the Vidjil project&lt;/a&gt;, &lt;a href=&#34;http://www.lifl.fr/bonsai/&#34;&gt;Bonsai team&lt;/a&gt;, LIFL (France)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;video-games&#34;&gt;
  Video games
  &lt;a class=&#34;anchor&#34; href=&#34;#video-games&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;pico-8-cartridges&#34;&gt;
  Pico-8 cartridges
  &lt;a class=&#34;anchor&#34; href=&#34;#pico-8-cartridges&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;figure class=&#34;pico-8-cartridge&#34;&gt;&lt;img src=&#34;https://carette.xyz/pico_8/galactica.p8.png&#34;
			alt=&#34;Galactica cartridge&#34;&gt;&lt;figcaption&gt;
			&lt;h4&gt;Galactica, a (basic) space shooter&lt;/h4&gt;
		&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 class=&#34;heading&#34; id=&#34;personal-projects&#34;&gt;
  Personal projects
  &lt;a class=&#34;anchor&#34; href=&#34;#personal-projects&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Please check my &lt;a href=&#34;https://git.carette.xyz/k0pernicus&#34;&gt;Forgejo account&lt;/a&gt; for my recent personal projects.&lt;/p&gt;
&lt;p&gt;My &lt;a href=&#34;https://github.com/k0pernicus&#34;&gt;Github account&lt;/a&gt; is no longer in use (but I will keep it for legacy reasons) because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I don’t trust Microsoft and GitHub engineers to do good work,&lt;/li&gt;
&lt;li&gt;I don’t want my code to be used to train unethical LLM models or &amp;lsquo;AI agents&amp;rsquo;.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Moving forward</title>
      <link>https://carette.xyz/posts/moving-forward/</link>
      <pubDate>Tue, 21 Jul 2026 10:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/moving-forward/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/lofigirl_mental_health.jpg#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; The lofi girl was right &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sometimes, fighting for a change isn&amp;rsquo;t worth it&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You try. Again and again. And as hard as you can.&lt;br&gt;
You see the problems. You feel their weight. And you have solutions to propose: clear, practical, good ones.&lt;/p&gt;
&lt;p&gt;So you speak up. Naively, you assume others will care.&lt;br&gt;
Why? Because you believe in something simple: &lt;strong&gt;that people value integrity&lt;/strong&gt;.&lt;br&gt;
That a company thrives when its employees do.&lt;/p&gt;
&lt;p&gt;But it fails.&lt;/p&gt;
&lt;p&gt;Not because your arguments lacked clarity.&lt;br&gt;
Not because the issue was yours alone to bear.&lt;br&gt;
Not because you didn&amp;rsquo;t reach the right persons.&lt;br&gt;
Not because you didn’t try hard enough.&lt;/p&gt;
&lt;p&gt;It fails because &lt;strong&gt;people don’t want to change&lt;/strong&gt;.
Ego, laziness, short-term gain, apathy&amp;hellip; none of these follow your logic.&lt;br&gt;
And then, you realize something: &lt;strong&gt;logic is not the currency here&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So, after being drained by all those efforts, you step back.&lt;br&gt;
Not in defeat, but in self-preservation.&lt;/p&gt;
&lt;p&gt;You let go of the illusion that reason will win.
Because in the end, &lt;strong&gt;the only thing left to fight for is yourself&lt;/strong&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A story of screwdriver drivers</title>
      <link>https://carette.xyz/posts/a_story_of_screwdriver_drivers/</link>
      <pubDate>Sun, 05 Jul 2026 12:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/a_story_of_screwdriver_drivers/</guid>
      <description>&lt;blockquote class=&#34;note&#34;&gt;&lt;p&gt;Any relation between this tale and modern software engineering is entirely up to your own interpretation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the story of a building company CEO named Matthew.
Matthew is a simple person: he likes to build buildings, and he likes it when people appreciate his buildings.&lt;/p&gt;
&lt;p&gt;Compared to other construction companies, Matthew always checks for quality over quantity.
He believes that clients are happier with clean and well-constructed building, and will come back to him more often if the final quality is high rather than just delivered fast.&lt;/p&gt;
&lt;p&gt;However, recently, the market changed entirely.&lt;br&gt;
A massive new trend took over the world: &lt;strong&gt;screwing things on walls&lt;/strong&gt;.
Clients no longer want standard, empty rooms. They suddenly want custom shelves, heavy cabinets, and complex fixtures screwed onto every available surface.&lt;br&gt;
The trend is so massive that if a building doesn&amp;rsquo;t have hundreds of beautifully screwed-in assets, no one wants to buy it. Stocks of screw manufacturers skyrocketed, and they paid hardware shops to make weird videos on TikTok to promote that, again and again&amp;hellip;&lt;/p&gt;
&lt;p&gt;This put Matthew in a difficult position.&lt;br&gt;
When he started his company, he built his first houses entirely by himself.&lt;br&gt;
But today, as a CEO, he spends all his time drawing blueprints, managing budgets, and talking to clients. His hands haven&amp;rsquo;t touched a physical tool in years. When he tried to adapt to this new trend, he realized he couldn&amp;rsquo;t just pick up a screwdriver and finish the work himself. Modern screws are complex, he has no time for it, and honestly, he has lost all interest in the repetitive, manual labor of twisting a wrist all day&amp;hellip;&lt;/p&gt;
&lt;p&gt;On the other side, if he doesn&amp;rsquo;t adapt to the trend quickly, his competitors will steal all his clients.&lt;/p&gt;
&lt;p&gt;So, on Monday, Matthew urgently posted an announcement: he is hiring a screwdriver driver with a great benefits package and a high salary. He has the budget for one screwdriver driver, and he wants the best one of all.&lt;/p&gt;
&lt;p&gt;By Friday, he already had 100 applications.&lt;br&gt;
Overwhelmed with the number of applications, he decided to close the job posting and to start processing the list of candidates.&lt;/p&gt;
&lt;p&gt;Looking at the applicant profiles, they seemed great!&lt;br&gt;
They knew how to use a screwdriver!&lt;br&gt;
They even had their own screwdrivers! &lt;strong&gt;AMAZING&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;But then, Matthew asked himself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How can I actually choose the best one among these 100 applications?&lt;/li&gt;
&lt;li&gt;Should I take the first one?&lt;/li&gt;
&lt;li&gt;Should I take the one who has the most experience with a screwdriver?&lt;/li&gt;
&lt;li&gt;Should I take the one who has the most expensive screwdriver?&lt;/li&gt;
&lt;li&gt;Or maybe I should take the one with the most used screwdriver?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So many questions made Matthew worried that he couldn&amp;rsquo;t choose the right person for the job&amp;hellip;&lt;/p&gt;
&lt;p&gt;But, he had suddenly an idea.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-contest&#34;&gt;
  The contest
  &lt;a class=&#34;anchor&#34; href=&#34;#the-contest&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Matthew decided to run a contest.&lt;/p&gt;
&lt;p&gt;He already had four buildings waiting &amp;ldquo;to be screwed&amp;rdquo;, for four different clients who were strongly following this #SCREW trend.
His idea was to hire four different people &lt;strong&gt;for one week&lt;/strong&gt;, one building per applicant, and choose the one who made his clients the happiest.&lt;/p&gt;
&lt;p&gt;Among those 100 applications he chose:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the youngest: very enthousiast to start working, who dream of screwdrivers at night, learned everything on the internet, and spent his time endlessly customizing his screwdriver for years,&lt;/li&gt;
&lt;li&gt;the dandy: his profile was incredibly clean, and he had spent thousands of euros on his gold screwdriver&amp;hellip; surely he must know how to use it well, right?&lt;/li&gt;
&lt;li&gt;the pragmatic: he had recently converted from a hammer driver to a screwdriver driver, but could his past experience translate from one tool to another?&lt;/li&gt;
&lt;li&gt;the 10x rockstar: very famous in the Builders community on YouTube (though criticized by another minor community in a specialized forum), known for delivering things fast.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each applicant was given one job: one building, one client, and a strict list of requirements.
The requirements consisted of a plan detailing exactly what needed to be screwed, and where, provided by the client of the building.&lt;br&gt;
The goal was to finish all the screwdriver work in their assigned building within the week.
As soon as the week was over, Matthew would visit each building with the clients and listen to their feedback.&lt;/p&gt;
&lt;p&gt;All applicants agreed, and the contest started.&lt;br&gt;
In the meantime, Matthew took a week off in the mountains, forgeting his phone and the world behind him.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-first-building&#34;&gt;
  The first building
  &lt;a class=&#34;anchor&#34; href=&#34;#the-first-building&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One week after, Matthew came back from holidays and visited the first building with his clients, assigned to the youngest applicant.&lt;/p&gt;
&lt;p&gt;All the screwdriver work was done! Great!&lt;br&gt;
The clients looked happy at first, but upon closer inspection&amp;hellip; it wasn&amp;rsquo;t good at all.&lt;/p&gt;
&lt;p&gt;Paintings and kitchen cabinets were not aligned properly.
Some small objects had way too many screws, while large shelves meant to hold 100+ kilos of books were held up by only one or two.
The clients tested a few fixtures, and they immediately fell off the wall.
Worse, some screws had punctured holes in the plumbing, causing water to leak in several places.&lt;/p&gt;
&lt;p&gt;Matthew asked the applicant &amp;ldquo;&lt;em&gt;Why did you do this? Did you followed the requirements?&lt;/em&gt;&amp;rdquo;&lt;br&gt;
The applicant simply answered that he might not have understood the requirements. In the end, it was clear he didn&amp;rsquo;t even understand the client&amp;rsquo;s actual needs, he needed support and mentoring, even if he built a lot of stuff on his own at home.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-second-building&#34;&gt;
  The second building
  &lt;a class=&#34;anchor&#34; href=&#34;#the-second-building&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Matthew moved on to the second building, full of hope, to meet the dandy applicant.&lt;/p&gt;
&lt;p&gt;The screwdriver work wasn&amp;rsquo;t done&amp;hellip; in fact, it wasn&amp;rsquo;t even 20% finished.
The clients were not happy at all and demanded to know why the delivery was so late.&lt;/p&gt;
&lt;p&gt;Matthew asked the applicant &amp;ldquo;&lt;em&gt;But, why are you so far behind?&lt;/em&gt;&amp;rdquo;&lt;br&gt;
The applicant replied that the original requirements were weak, so he had to rework a lot of things himself.
He handed Matthew a brand new plan, which looked nothing like the original. Some of the building&amp;rsquo;s foundations had been entirely redesigned from the ground up because the applicant felt structural modifications were necessary.&lt;br&gt;
At the end of the discussion applicant asked for one more week just to finish planning, before he could even start the real work.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-third-building&#34;&gt;
  The third building
  &lt;a class=&#34;anchor&#34; href=&#34;#the-third-building&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Matthew moved to the third building, feeling desperate, to meet the pragmatic builder.&lt;/p&gt;
&lt;p&gt;The screwdriver work was 80% done, but things were slightly out of place.
Matthew and the clients were annoyed, and Matthew asked the applicant &amp;ldquo;&lt;em&gt;Why didn&amp;rsquo;t you finish the work? And why did you change a bit the plan?&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The pragmatic applicant explained his reasoning.
The original plan was just theory: it assumed everything had a perfect place for a perfect reason.
However, he explained that some things needed to deviate slightly from the plan. For instance, some screws were originally planned to go dangerously close to pipes, while others were supposed to be driven into brittle materials.
He spotted these risks based on his broad knowledge of building materials and his past experience with hammers.&lt;br&gt;
In his defense regarding the timing issue, he had tried to call Matthew several times but, as he was on holidays with no phone, he couldn&amp;rsquo;t get the answers in time.&lt;/p&gt;
&lt;p&gt;The applicant explained he needed two more days to finish the work, but only after Matthew and the clients answered a list of clarifying questions to fix the flawed requirements.&lt;/p&gt;
&lt;p&gt;The clients and Matthew understood, agreeing that the changes were ultimately necessary.
Not because the applicant manipulated them, but because he was a true expert, and all his explanations made perfect sense.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-fourth-building&#34;&gt;
  The fourth building
  &lt;a class=&#34;anchor&#34; href=&#34;#the-fourth-building&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Matthew moved to the fourth building, with mixed feelings.&lt;/p&gt;
&lt;p&gt;But, once he reached the door of the building&amp;hellip; The screwdriver work was completely done! Actually, the 10x rockstar had finished everything in &lt;strong&gt;only four days&lt;/strong&gt;! And the clients were actually very happy!&lt;/p&gt;
&lt;p&gt;Matthew and the clients, very enthousiastic, asked the screwdriver driver &amp;ldquo;&lt;em&gt;But, how did you do this so fast?&lt;/em&gt;&amp;rdquo;.&lt;br&gt;
The builder explained: instead of a normal screwdriver, he had brought a heavy, custom-made electric drill that seemed to do all the thinking and spinning for him.&lt;br&gt;
He just had to point it, pull the trigger, and let the tool do the magic.&lt;br&gt;
He said that screwdrivers were tools of the past, and that electric drills are the future.&lt;/p&gt;
&lt;p&gt;Matthew was relieved, and the clients left, a big smile on their face.&lt;/p&gt;
&lt;p&gt;But as Matthew took a quiet walk through the building, his expert eyes started to notice terrifying details. The applicant had driven heavy screws directly into fragile drywall, completely missing the solid wooden foundations behind it. He had mixed incompatible metals together and forced thick screws into thin glass edges.
The cabinets and shelves were holding up for today, but the mistakes were deep and entirely invisible to a normal client. They required an expert to even spot them. Eventually, under the weight of time, the entire wall would rip open, and some levels of the building would need to be rebuilt from scratch.&lt;/p&gt;
&lt;p&gt;It was an hidden disaster.&lt;/p&gt;
&lt;p&gt;Matthew asked the applicant &amp;ldquo;&lt;em&gt;What did you do? Did you understand how weight distribution and structural foundations actually work?&lt;/em&gt;&amp;rdquo;&lt;br&gt;
The applicant just shrugged. He admitted he didn&amp;rsquo;t really know how the walls were built inside, but he had no time to learn as he wants to build things.
His shiny drill just made things stick together, it looked fine on the surface, and that was all that mattered.&lt;/p&gt;
&lt;p&gt;Matthew then noticed a shelf was a bit crooked. He decided to adjust it, but he didn&amp;rsquo;t have a screwdriver on him, neither the screwdriver driver.
So, he went to the nearest hardware store and bought one.
When he came back, he tried to unscrew the shelf a little bit, but he couldn&amp;rsquo;t.
He looked closely at the screw, and then at all the other screws. Every single screw head on the shelf was completely destroyed. They were totally flat and stripped.&lt;/p&gt;
&lt;p&gt;Matthew called the applicant back, and asked &amp;ldquo;&lt;em&gt;What will happen when the wall inevitably starts cracking, or if the clients need to move a kitchen cabinet later?&lt;/em&gt;&amp;rdquo;&lt;br&gt;
The applicant answered that he delivered faster than anyone else, which is what clients always want. He pointed out that the original plan never explicitly said the building needed to survive for the next ten years.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Also&amp;rdquo;, he raised, &amp;ldquo;is there a real purpose to maintain this big building for more than 10 years&amp;hellip;?&amp;rdquo;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-hiring&#34;&gt;
  The hiring
  &lt;a class=&#34;anchor&#34; href=&#34;#the-hiring&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;At the end of the day, Matthew sat down at his desk, staring at the four files.&lt;/p&gt;
&lt;p&gt;He reviewed the results of the contest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the youngest applicant had punctured pipes and caused water leaks in several rooms. He had finished the work, sure, and Matthew knew that with mentoring and real-world experience, this young kid could become one of the greatest screwdriver drivers in the world. But Matthew simply didn&amp;rsquo;t have the budget or the time to provide that guidance&amp;hellip;&lt;/li&gt;
&lt;li&gt;the dandy applicant hadn&amp;rsquo;t even started the real work, trapped in endless planning and rewriting the original plans,&lt;/li&gt;
&lt;li&gt;the pragmatic applicant did not finish the work, and had paused at 80% to question the requirements, but his questions and worries made sense,&lt;/li&gt;
&lt;li&gt;and the 10x rockstar had finished all his tasks in just four days, despite critical and foundational flaws.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Matthew smiled warmly as he looked at the pragmatic screwdriver driver profile.&lt;br&gt;
Matthew knew by intuition this was the absolute perfect fit for his company values. Yes, he was a bit slower, but that was because he actually cared. He didn&amp;rsquo;t just blindly force screws into a flawed plan, he actually paused to understand the true needs of the client in order to provide the most qualitative, enduring solution possible.&lt;br&gt;
The clients would be genuinely safe and happy for years to come.&lt;/p&gt;
&lt;p&gt;Matthew picked up the phone, and called back the 10x rockstar. He was hired.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Bringing Swift through Distrobox on NixOS</title>
      <link>https://carette.xyz/posts/distrobox_and_swift/</link>
      <pubDate>Sun, 28 Jun 2026 19:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/distrobox_and_swift/</guid>
      <description>&lt;p&gt;I am working on a &lt;a href=&#34;https://git.carette.xyz/k0pernicus/recreational-swift-raylib-game&#34;&gt;project that combines Swift, Raylib, and Raygui&lt;/a&gt;.&lt;br&gt;
I don&amp;rsquo;t really know what the end-goal is here, but I am having fun. That&amp;rsquo;s enough for me to work occasionally on that.&lt;/p&gt;
&lt;p&gt;I like Swift very much, and I have had more fun developing in Swift than in Rust or C++ recently.
But, there is a small catch with Swift outside the Apple ecosystem: its adaptability to other platforms sometimes, mostly on some Linux distributions.
As an example, even though Swift is a general-purpose programming language for multiple platforms and OSs, its official support does not include NixOS, a Linux distribution I have been using for a few months now.&lt;/p&gt;
&lt;p&gt;The latest version of Swift, maintained by the NixOS community, is &lt;a href=&#34;https://search.nixos.org/packages?channel=26.05&amp;amp;query=swift#show=swift&#34;&gt;5.10.1&lt;/a&gt;.&lt;br&gt;
&lt;a href=&#34;https://github.com/lucasly-ba/swift-nixos&#34;&gt;People are actually trying to bring the latest version of Swift to nix systems&lt;/a&gt;, but it is not ready yet, and the installation today is still a loud, highly manual process with very specific steps.&lt;/p&gt;
&lt;p&gt;I wish I had more time and knowledge to contribute to &lt;code&gt;swift-nixos&lt;/code&gt;, but I also wanted to test my project very quickly on my small linux machine, under 15 minutes.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; &lt;a href=&#34;https://github.com/89luca89/distrobox&#34;&gt;distrobox&lt;/a&gt; to the rescue!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-configuration&#34;&gt;
  The configuration
  &lt;a class=&#34;anchor&#34; href=&#34;#the-configuration&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/89luca89/distrobox&#34;&gt;Distrobox&lt;/a&gt; is a pretty cool project.&lt;br&gt;
Its main objective is to bring any Linux distribution inside your terminal, via containers.
Compatibility is great, and the created container will communicate tightly with the host, sharing the HOME directory of the user, graphical apps (X11, Wayland), audio, &amp;hellip; which is absolutely perfect for my needs!&lt;/p&gt;
&lt;p&gt;On NixOS I enabled both rootless containers (via &lt;code&gt;podman&lt;/code&gt;) and &lt;code&gt;distrobox&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;virtualisation.podman = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  enable = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# This makes typing &amp;#39;docker&amp;#39; under the hood use podman&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  dockerCompat = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  defaultNetwork.settings.dns_enabled = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;environment.systemPackages = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;with&lt;/span&gt; pkgs; [ distrobox ];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the quick system rebuild is finished, I can finally set up my distrobox environment for Swift:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;distrobox create --name swift-env --image ubuntu:26.04
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even though Swift is compatible with Ubuntu 24.04, I preferred to use the 26.04 LTS version instead.&lt;/p&gt;
&lt;p&gt;This will need an extra step, as a dependency uses a different version than the one provided by apt (we will come to that later in this blog post).&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s enter the Ubuntu container:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;distrobox enter swift-env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and&amp;hellip; that&amp;rsquo;s it! I am in an Ubuntu environment, on my NixOS machine. Great!&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s set up that container as if it were a true local Ubuntu system:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo apt update &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt install -y mesa-utils x11-apps git make libxml2-dev &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -O https://download.swift.org/swiftly/linux/swiftly-&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;)&lt;/span&gt;.tar.gz &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar zxf swiftly-&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;)&lt;/span&gt;.tar.gz &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./swiftly init --quiet-shell-followup &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;. &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;SWIFTLY_HOME_DIR&lt;/span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;:-&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$HOME&lt;/span&gt;/.local/share/swiftly&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;/env.sh&amp;#34;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;hash&lt;/span&gt; -r
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;swiftly&lt;/code&gt; and the Swift programming language are now installed in that Ubuntu container.&lt;/p&gt;
&lt;p&gt;I can now go to my local project, and try to run it (debug mode):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cd&lt;/span&gt; ~/Devel/recreational-swift-raylib-game &amp;amp;&amp;amp; swift run -c debug
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; /home/user/.local/share/swiftly/toolchains/6.3.2/usr/bin/lldb: error &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; loading shared libraries: libxml2.so.2: cannot open shared object file: No such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So close. But this makes sense!&lt;/p&gt;
&lt;p&gt;I said earlier that the Swift installer proposes the Ubuntu 24.04 version, but not the 26.04 one.
In this newer Ubuntu release, the &lt;code&gt;libxml2&lt;/code&gt; developers introduced a backwards-incompatible update that bumped the shared library name from &lt;code&gt;libxml2.so.2&lt;/code&gt; to &lt;code&gt;libxml2.so.16&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, the pre-compiled Swift toolchains available through swiftly were built in environments that strictly expect the older &lt;code&gt;libxml2.so.2&lt;/code&gt;. So, even though we have the latest version of the library installed, lldb is completely blind to it.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s use the good old hack to trick the Swift toolchain into using the new version of the library by creating a symbolic link from the old filename to the new one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo ln -s /usr/lib/x86_64-linux-gnu/libxml2.so.16 /usr/lib/x86_64-linux-gnu/libxml2.so.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and it finally works!&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A native linux game using Swift and Distrobox on NixOS&#34; src=&#34;https://carette.xyz/images/distrobox_swift_test.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-distrobox-ini-file&#34;&gt;
  The distrobox ini file
  &lt;a class=&#34;anchor&#34; href=&#34;#the-distrobox-ini-file&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;To automate the setup, distrobox allows you to create an ini file that processes things automatically for you:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;[swift-env]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;image=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;ubuntu:26.04&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;init_hooks=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;apt-get update&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;init_hooks=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;apt-get -y install mesa-utils x11-apps git make libxml2-dev&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;init_hooks=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ln -sf /usr/lib/x86_64-linux-gnu/libxml2.so.16 /usr/lib/x86_64-linux-gnu/libxml2.so.2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Pull the latest version of the image if it isn&amp;#39;t cached&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pull=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;init_hooks&lt;/code&gt; calls run as root to install system libraries and apply our symlink hack.
&lt;code&gt;swiftly&lt;/code&gt; is intentionally excluded here, as my &lt;code&gt;~/.local/share&lt;/code&gt; directory is shared with the NixOS host, meaning &lt;code&gt;swiftly&lt;/code&gt; only needs to be installed once manually!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-praise-to-nixpkgs-maintainers&#34;&gt;
  A praise to nixpkgs maintainers
  &lt;a class=&#34;anchor&#34; href=&#34;#a-praise-to-nixpkgs-maintainers&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Hopefully, this post will be helpful for anyone looking for a quick way to test their Swift projects on unsupported Linux distributions.&lt;/p&gt;
&lt;p&gt;Even though this quick hack is great to quickly test a build on a Linux system, it does not fit the philosophy of NixOS: an automatic, deterministic system.&lt;/p&gt;
&lt;p&gt;I want to thank all contributors and maintainers of the Swift programming language for Nix to dedicate their (mostly personal) time to bring this programming language, and ecosystem, to Nix systems.&lt;br&gt;
So, a big thanks to Daniel Duan, Samasaur, Stéphan Kochen and Tom Repetti for maintaining Swift for Nix systems. Also, thanks to &lt;a href=&#34;https://github.com/lucasly-ba&#34;&gt;Lucas Ly Ba&lt;/a&gt; for his contributions in &lt;a href=&#34;https://github.com/lucasly-ba/swift-nixos&#34;&gt;bringing a new way to build Swift from source on NixOS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I plan to spend more time contributing to that topic as well, and on the LLVM side (trying to contribute to Swift WASM), as soon as I get more time to focus and contribute to open source projects.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The mud and the mind</title>
      <link>https://carette.xyz/posts/the_mud_and_the_mind/</link>
      <pubDate>Sat, 13 Jun 2026 11:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_mud_and_the_mind/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;https://carette.xyz/posts/the_five_pillars_of_post_ai_interview&#34;&gt;my previous article&lt;/a&gt; I discussed about the necessary evil to change the coding tests to filter engineers.&lt;/p&gt;
&lt;p&gt;As LLMs become the ultimate coders (producing boilerplate infinitely, instantly, and without fatigue) the software engineering workflow is rapidly shifting, and day-to-day work is moving heavily toward auditing and reviewing AI-generated code.&lt;br&gt;
But because of this shift, a dangerous corporate fantasy is taking root: the belief that engineers should simply become project managers. But let us not confuse this evolution with a retreat.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Becoming an auditor does not mean keeping your hands clean.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Expecting engineers to simply shuffle tickets and prompt LLMs is a profound misunderstanding of the craft. An engineer’s primary output has never been code but has always been &lt;strong&gt;deep thought&lt;/strong&gt; on how to efficiently solve a problem.&lt;/p&gt;
&lt;p&gt;To solve a problem, you will need &lt;em&gt;intuition&lt;/em&gt;.&lt;br&gt;
To develop intuition you need &lt;em&gt;experience&lt;/em&gt;.&lt;br&gt;
And to gain experience you definitely need to &lt;strong&gt;&lt;em&gt;put your hands in the mud&lt;/em&gt;&lt;/strong&gt; and break your teeth on walls of complex archiecture.&lt;/p&gt;
&lt;p&gt;You might ask yourself: &amp;ldquo;&lt;em&gt;if writing boilerplate syntax is no longer the mud, so what is?&lt;/em&gt;&amp;rdquo;.&lt;br&gt;
We need to redefine where the hard work actually happens in software engineering. The mud is no longer writing REST controllers, or scaffolding a CRUD application. The mud is profiling memory leaks in production. It is tracing unpredictable latency spikes across a distributed system. It is staring at obscure telemetry logs at 3 AM because your beautifully Claude-generated architecture introduced a silent race condition that only appears under heavy load.&lt;/p&gt;
&lt;p&gt;That is where engineering happens and where engineers are needed.&lt;br&gt;
That is the mud.&lt;/p&gt;
&lt;p&gt;And this brings us to the ultimate reality check: &lt;em&gt;accountability&lt;/em&gt;.&lt;br&gt;
You can automate the creation, but you cannot automate the responsibility, because
LLMs and Agents can write the boilerplate but they cannot suffer the consequences of a bad design.
At the end of the day, &lt;strong&gt;you do&lt;/strong&gt;, and this is what you get paid for.&lt;/p&gt;
&lt;p&gt;Companies that confuse engineering with mere ticket-shuffling will inevitably build fragile, incomprehensible black boxes, and if an organization expects you to be a PM rather than a deep technical thinker, they have already lost the plot.&lt;br&gt;
In this special case I have an advice: ignore them, and &lt;strong&gt;solve problems in places where the real problems to solve are&lt;/strong&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The five pillars of the post-AI interview</title>
      <link>https://carette.xyz/posts/the_five_pillars_of_post_ai_interview/</link>
      <pubDate>Fri, 12 Jun 2026 23:15:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_five_pillars_of_post_ai_interview/</guid>
      <description>&lt;p&gt;Programming tests used to be our primary filter to separate profiles.&lt;/p&gt;
&lt;p&gt;In software engineering, they historically differentiated three distinct ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;engineers&lt;/strong&gt;, the ones who solve the fundamental problems.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;developers&lt;/strong&gt;, the ones who apply the right patterns and orchestrate the architecture depending on the needs.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;coders&lt;/strong&gt;, the ones who just write code, code, and code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We used to put candidates through exhausting steps to check everything: their writing, their communication, their &amp;ldquo;syntax recall&amp;rdquo;, and if their mind fit the culture of the team.&lt;/p&gt;
&lt;p&gt;Before the LLM boom, the live coding interview was already questionable as, most of the time, it was a &amp;ldquo;performance of memorization&amp;rdquo;.
However, today, it became pointless.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;shifting&#34;&gt;
  Shifting
  &lt;a class=&#34;anchor&#34; href=&#34;#shifting&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Culture fit remains the immovable constant. A toxic genius or an uncommunicative teammate is still a catastrophic hire, regardless of the tools they use. And, as you might already know, AI doesn&amp;rsquo;t fix human behaviours.&lt;/p&gt;
&lt;p&gt;But the coding test itself &lt;strong&gt;is dead&lt;/strong&gt;, not because writing code isn&amp;rsquo;t useful (I will always be the one who considers that making a thing is the best way to understand that thing), but because &lt;strong&gt;cheating the test is easier than ever&lt;/strong&gt;. We are entering an era where a Builder agent can generate a 500-line pull request in a matter of seconds, mostly slop, and submit it directly in an ocean of slops.&lt;/p&gt;
&lt;p&gt;In order to improve the workflow, the primary job of the human is shifting. Some of us are no longer just creators, but (unfortunately, in my own opinion) editors and auditors.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-five-new-pillars&#34;&gt;
  The five new pillars
  &lt;a class=&#34;anchor&#34; href=&#34;#the-five-new-pillars&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If we strip away the obsolete rituals, we are left with a new reality.&lt;/p&gt;
&lt;p&gt;In order to reflect this reality, I personally would replace the traditional tests with five distinct checks, or pillars:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;cultural fit check&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;algorithmic core&lt;/strong&gt;: if you can’t design an algorithm with nothing but pseudo-code, you will write unscalable, unmaintainable software. Worse: you will let an LLM write it for you, and you won’t even get the intuition to realize it is fundamentally flawed.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;architectural feeling&lt;/strong&gt;: the hardest problems today are not about writing isolated functions but managing data flow, handling asynchronous events, defining strict API contracts, and surviving the chaos of distributed architectures. This is still a valuable skill (&lt;a href=&#34;(https://status.claude.com/).&#34;&gt;which is not even owned at Anthropic apparently&amp;hellip;&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;code review&lt;/strong&gt;: if you can’t review code, you can’t direct AI tools. You cannot lead a team. You cannot even trust your own work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;debugging code&lt;/strong&gt;: if LLMs are doing the heavy lifting of writing the boilerplate, the human is left with the hardest part: debugging. A great modern interview test would hand a candidate a codebase riddled with subtle, AI-generated logic flaws and ask them to find and fix the bugs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;At the end, if a candidate cannot critique, debug, and verify code, they are not an asset but a liability.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Previously, we had room for all three profiles, and our tests were designed to expose those specific skills.&lt;/p&gt;
&lt;p&gt;Today, there is a catch.&lt;br&gt;
The trend is undeniable: LLMs are the ultimate coders. They produce boilerplate infinitely, instantly, and without fatigue. We are leaving the coders behind, returning, by necessity, to a future built entirely by engineers.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Made (by humans) in California</title>
      <link>https://carette.xyz/posts/made_by_humans_in_california/</link>
      <pubDate>Tue, 26 May 2026 23:15:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/made_by_humans_in_california/</guid>
      <description>&lt;p&gt;Very recently, I was hunting for a new TV show and clicked on Apple TV, drawn in by the buzz surrounding &lt;em&gt;Margo Has Money Troubles&lt;/em&gt;. I launched the first episode and got hooked by the new intro logo.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/6sX_BfDnyrg?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;It caught my eye because it felt weirdly alive. There was a specific, imperfect flicker of light across what looked like &amp;ldquo;organic glass&amp;rdquo;. It lacked the sterile, mathematically perfect glare we&amp;rsquo;ve become numb to in modern streaming intros.&lt;/p&gt;
&lt;p&gt;Then a friend told me how it was actually made: this wasn&amp;rsquo;t rendered on a server farm but carved from &lt;strong&gt;actual glass&lt;/strong&gt;, lit by hand, and filmed in a blacked-out studio like a 1960s Kubrick shot.&lt;/p&gt;
&lt;p&gt;In 2026, when every piece of motion design can be generated by typing a text prompt, choosing a physical rig feels less like a throwback and more like a &lt;em&gt;&lt;strong&gt;provocation&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;from-crush-to-craftsmanship&#34;&gt;
  From &amp;ldquo;crush&amp;rdquo; to craftsmanship
  &lt;a class=&#34;anchor&#34; href=&#34;#from-crush-to-craftsmanship&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apple has always built its brand premium on human craftsmanship.&lt;/p&gt;
&lt;p&gt;In 1984, &lt;a href=&#34;https://youtu.be/ErwS24cBZPc?si=onaZufPA4oko8tVa&#34;&gt;Ridley Scott’s dystopian &amp;ldquo;1984&amp;rdquo; ad&lt;/a&gt; didn&amp;rsquo;t just sell Macintosh computers, it used practical sets and real actors to position Apple as the ultimate anti-establishment tool (against Big Blue at that time). Even today, &amp;ldquo;1984&amp;rdquo; is still used as a reference for commercial ads.&lt;/p&gt;
&lt;p&gt;In 1997, &lt;a href=&#34;https://www.youtube.com/watch?v=5sMBhDv4sik&#34;&gt;the &amp;ldquo;Think Different&amp;rdquo; campaign&lt;/a&gt; didn’t show products at all (and that is weird for a commercial ad).
Lee Clow, Craig Tanimoto, and Jessica Edelstein filled billboards with raw, black-and-white portraits of Einstein, Lennon, MLK, and Picasso.&lt;br&gt;
The subtext was arrogant but brilliant: &lt;strong&gt;Apple stood with the creators, not the systems&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But, in 2024, that relationship fractured.&lt;br&gt;
Some of us remember &lt;a href=&#34;https://www.youtube.com/watch?v=v3AyOUjriJ8&#34;&gt;the disastrous &amp;ldquo;Crush!&amp;rdquo; ad for the iPad Pro&lt;/a&gt;, where a hydraulic press crushed pianos, cameras, and paint tubes into a thin sheet of silicon. At first, it looked like Apple was finally siding with the machines, celebrating the compression of human culture into a sterile tablet. The creative community felt betrayed, expressed it, and Apple remove the ad after a few weeks.&lt;/p&gt;
&lt;p&gt;Today, the new glass logo feels like a calculated, multi-million-dollar apology tour.&lt;br&gt;
At Cannes Lions, Tor Myhren, Apple’s VP of marketing communications, stated: &lt;em&gt;“AI will not save advertising. The human touch is our superpower.”&lt;/em&gt;.&lt;br&gt;
And their decade-long partnership with TBWA\Media Arts Lab, &lt;a href=&#34;https://lbbonline.com/news/TBWAMedia-Arts-Lab-Apple-One-Show-Penta-Pencil&#34;&gt;recently awarded the One Show’s Penta Pencil&lt;/a&gt;, proves they are trying hard to pivot back to their roots.&lt;/p&gt;
&lt;p&gt;So when it came time to rebrand Apple TV, the choice did not feel aesthetic, but political.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;glass-and-light&#34;&gt;
  Glass and light
  &lt;a class=&#34;anchor&#34; href=&#34;#glass-and-light&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The new intro is a lesson in intentional friction. In a world where you can click &amp;ldquo;render&amp;rdquo; and get perfection in a matter of minutes, Apple chose to solve brutal physics problems on a physical stage.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/V95nfAEXlZ4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;Apple’s New TV Made up&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;The asset exists in three lengths: a brief one-second trailer pop, a five-second television intro, and a full 12-second cinematic version for features.&lt;/p&gt;
&lt;p&gt;As the &amp;ldquo;behind the scenes&amp;rdquo; footage reveals, there are no digital shortcuts here. Full-scale glass panels were cut, polished into the Apple logo shape, and mounted on precision rigs. The shifting colors and organic refractions weren&amp;rsquo;t mapped in software. Instead, a studio crew physically choreographed lights around a static camera rig. A single smudge on the glass or a misaligned light beam meant resetting the entire take.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.mediaartslab.com/&#34;&gt;TBWA\Media Arts Lab&lt;/a&gt; and the directors at &lt;a href=&#34;https://opticalarts.studio/&#34;&gt;Optical Arts&lt;/a&gt; explicitly chose &lt;strong&gt;practical effects over CGI&lt;/strong&gt;. Even the audio (a sparse, tactile composition by Finneas) and the typography (a customized variant of Apple’s in-house San Francisco font) were tuned to feel &amp;ldquo;physical&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Instead of simulating light bouncing off a polygon, they let actual glass bend, scatter, and pool light in ways that path-tracing algorithms still can&amp;rsquo;t entirely replicate without looking &amp;ldquo;uncanny&amp;rdquo;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-the-roots&#34;&gt;
  To the roots
  &lt;a class=&#34;anchor&#34; href=&#34;#to-the-roots&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In an era where the tech industry is rushing to automate every creative impulse, Apple’s glass logo is a quiet, deliberate act of resistance.&lt;/p&gt;
&lt;p&gt;It marks a profound moment of self-correction. If the &amp;ldquo;Crush!&amp;rdquo; ad was a clumsy misstep that valued the machine over the medium, this logo is a humble return to the roots that made Apple a beloved brand in the first place. It is a reminder that technology should be a tool &lt;em&gt;&lt;strong&gt;for&lt;/strong&gt;&lt;/em&gt; the creator, not a replacement &lt;em&gt;&lt;strong&gt;of&lt;/strong&gt;&lt;/em&gt; the creator.&lt;/p&gt;
&lt;p&gt;When digital perfection becomes the default, it loses its soul. By choosing the messy, unpredictable choreography of physical glass and studio lights, Apple didn&amp;rsquo;t just take the hard road, but proved that human intention still possesses a warmth that code cannot replicate.&lt;/p&gt;
&lt;p&gt;They looked at a future dominated by synthetic generation, and chose to bet on the unmatched superpower of human touch.&lt;/p&gt;
&lt;p&gt;Made (&lt;strong&gt;by humans&lt;/strong&gt;) in California.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Who is gonna buy your services if you fire us all?</title>
      <link>https://carette.xyz/posts/who_is_gonna_buy_your_services/</link>
      <pubDate>Mon, 18 May 2026 23:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/who_is_gonna_buy_your_services/</guid>
      <description>&lt;p&gt;Silicon Valley executives used to complain about &amp;ldquo;the Great Resignation&amp;rdquo; to justify replacing people with machines. Now, they have suddenly changed their tune to sound like generous givers. Figures like Sam Altman and Elon Musk now claim that &lt;a href=&#34;https://www.aol.com/articles/future-without-elon-musk-bill-085901000.html&#34;&gt;artificial intelligence will culminate in a liberated society characterized by truncated 32-hour workweeks and Universal Basic Income (UBI)&lt;/a&gt;. In their view, automation is a tool that will finally free humans from the need to work to survive.&lt;/p&gt;
&lt;p&gt;Stripping away this corporate talk reveals a simple paradox for AI: if automation destroys human jobs, it also destroys the customer base needed to buy AI subscriptions like ChatGPT, Claude, or Gemini.&lt;/p&gt;
&lt;p&gt;The sudden trend of supporting universal cash payouts does not come from a kind heart. It comes from &lt;strong&gt;self-preservation&lt;/strong&gt;. Looking at history, this plan is just a modern version of the same economic tricks used in the 19th century to turn workers into &lt;strong&gt;forced&lt;/strong&gt; consumers.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;rebranding-the-cost-of-labor&#34;&gt;
  Rebranding the cost of labor
  &lt;a class=&#34;anchor&#34; href=&#34;#rebranding-the-cost-of-labor&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To understand why elites love UBI today, we have to look at what happened after slavery ended. In the early 19th century, forced labor was the ultimate way for business owners to make money without paying wages. When slavery was legally abolished across European colonies, the old economic system did not disappear. It simply changed its name to keep power in the same hands.&lt;/p&gt;
&lt;p&gt;A perfect example happened in the French colony of Réunion after &lt;a href=&#34;https://heritage.bnf.fr/france-ameriques/en/abolition-slavery-1848&#34;&gt;the 1848 abolition decree&lt;/a&gt;. The government paid former slave owners for losing their &amp;ldquo;property,&amp;rdquo; but gave the freed workers abstract legal freedom without any money or land to survive. Because freedom without money is just another way to stay trapped, the sugar plantations quickly created the &lt;em&gt;engagisme&lt;/em&gt; (indentured labor) system.&lt;/p&gt;
&lt;p&gt;Former slaves were replaced by workers tied to strict five-year contracts. They were paid in a tightly controlled mix of tiny wages and basic food. Trapped by manufactured debt and harsh laws, their exploitation never actually ended. The British Empire did the exact same thing after its &lt;a href=&#34;https://en.wikipedia.org/wiki/Slavery_Abolition_Act_1833&#34;&gt;1833 abolition act&lt;/a&gt;, replacing Caribbean slaves with waves of contract workers from India and China. This proves that moving from slavery to contract labor was just a modern way to keep extracting wealth from workers.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-creation-of-the-working-consumer&#34;&gt;
  The creation of the working consumer
  &lt;a class=&#34;anchor&#34; href=&#34;#the-creation-of-the-working-consumer&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As the industrial revolution grew, Western factories ran into a major bottleneck: machines were making huge amounts of goods, but the working class was paid too little to buy them. From this crisis, elites realized a foundational rule of modern capitalism: &lt;strong&gt;to keep selling goods, the worker had to be turned into a consumer&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This shift is often romanticized as an act of kindness by early industrial titans, especially Henry Ford&amp;rsquo;s creation of the five-day workweek and the five-dollar daily wage. However, &lt;a href=&#34;https://agriculture.institute/cost-concepts/henry-ford-labour-management-approach/&#34;&gt;historical data demonstrates that Ford’s adjustments were entirely transactional optimization strategies designed to solve catastrophic employee turnover and secure an adequate domestic market for mass-produced vehicles&lt;/a&gt;. Workers needed both free time and cash to buy the very cars they were building on the assembly lines.&lt;/p&gt;
&lt;p&gt;When wages stopped growing naturally in the late 20th century, corporations kept this buying loop going by building a massive system of debt. This allowed the working class to keep buying goods today by borrowing against their future labor.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-closed-loop-feudalism-of-the-ai-era&#34;&gt;
  The closed-loop feudalism of the AI era
  &lt;a class=&#34;anchor&#34; href=&#34;#the-closed-loop-feudalism-of-the-ai-era&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The modern rise of large language models and AI agents is the next step in this history. As corporations replace human workers with AI to cut costs, they hit a major capitalist contradiction: &lt;strong&gt;an economy devoid of salaried workers is an economy devoid of aggregate demand&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This mathematical problem explains the true purpose of UBI. When tech billionaires push for a government allowance, they are not trying to redistribute wealth fairly, but they are designing an emergency money injection to stop the consumer market from collapsing.&lt;/p&gt;
&lt;p&gt;In an AI economy where a few massive tech giants own all the tools and data infrastructure, UBI is just a closed loop. The government hands cash to displaced people, who immediately send that money right back to the tech companies to pay for subscriptions, automated food delivery, or digital entertainment.&lt;/p&gt;
&lt;p&gt;This plan shows a complete lack of real bravery. Instead of sharing the ownership of AI, the tech elite wants to build a modern version of &lt;a href=&#34;https://simple.wikipedia.org/wiki/Technofeudalism&#34;&gt;technofeudalism&lt;/a&gt;. Just like the contract workers of 1848 who were legally free but forced to spend their wages at the plantation store, modern citizens under this system are freed from work only to be permanently trapped as captive consumers.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-tech-formula&#34;&gt;
  The tech formula
  &lt;a class=&#34;anchor&#34; href=&#34;#the-tech-formula&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The tech sector is currently solving its profit problem in three clear steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;eliminate human labor&lt;/strong&gt; using scalable AI systems to maximize corporate profits,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;launch UBI&lt;/strong&gt; as an economic cushion, ensuring people have just enough cash to keep buying products and subscribe to services,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lock down control of capital&lt;/strong&gt;, keeping the core code, hardware, and billions in profits in private hands.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The real issue is not whether machines will take our jobs, but why we should accept a system where we only exist to pass cash back to tech corporations. These AI systems were trained on data created by the collective history of human knowledge.&lt;br&gt;
Because of this, &lt;strong&gt;the wealth generated by automation should be treated as something that belongs to the public, rather than a private monopoly&lt;/strong&gt;. Instead of accepting a small allowance handed down by Silicon Valley to keep us quiet, we should view the benefits of automation as a shared resource that belongs to everyone.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Beyond C: wrapping Dear ImGui in Swift with zero FFI</title>
      <link>https://carette.xyz/posts/swift_cpp_compatibility_with_raylib_and_imgui/</link>
      <pubDate>Thu, 26 Mar 2026 23:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/swift_cpp_compatibility_with_raylib_and_imgui/</guid>
      <description>&lt;p&gt;A few days ago I wrote and published a blog post about &lt;a href=&#34;https://carette.xyz/posts/swift_c_compatibility_with_raylib&#34;&gt;how Swift interacts with C projects, using Raylib&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Somehow, much to my delight, it has been posted on multiple social networks, like Reddit and Hackernews.&lt;br&gt;
Comments were interesting and constructive.
Many people praised how Swift manages interactivity with Raylib, but a few expressed their disappointment about the lack of demonstration on how to interact with a C++ project.&lt;/p&gt;
&lt;p&gt;Yesterday, again, I was bored.
So I tried.&lt;/p&gt;
&lt;p&gt;Like the previous one this article is for demonstration purpose only.&lt;br&gt;
I will not demonstrate this time how to build a WASM version of the finished project, most particularly because &lt;a href=&#34;https://forums.swift.org/t/pitch-emscripten-target-support-for-swift/85310&#34;&gt;some exciting changes are coming in the Swift WASM ecosystem&lt;/a&gt; and I am waiting for those changes before doing the WASM build.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;swift-3-dear-imgui&#34;&gt;
  Swift &amp;lt;3 Dear ImGui
  &lt;a class=&#34;anchor&#34; href=&#34;#swift-3-dear-imgui&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This time I decided to integrate Dear ImGui into my (very simple) project.&lt;br&gt;
Raylib will be used to initialize the window, initialize the screen, clear it, and draw some text.
ImGui, compared to Raylib, will be used to draw some GUI (used mainly for very useful menus to interact with the core of your program).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://carette.xyz/posts/swift_c_compatibility_with_raylib&#34;&gt;Last time&lt;/a&gt; I discussed how easy integrating Raylib was: dropping the main header file of Raylib and its static library, and let the compiler and package manager do their magic.&lt;/p&gt;
&lt;p&gt;But how is it different compared to Dear ImGui, a C++ project?&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-project-structure&#34;&gt;
  The project structure
  &lt;a class=&#34;anchor&#34; href=&#34;#the-project-structure&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;The project structure does not change that much.&lt;br&gt;
I included a static build of &lt;a href=&#34;https://github.com/ocornut/imgui&#34;&gt;Dear ImGui&lt;/a&gt; (including &lt;a href=&#34;https://github.com/raylib-extras/rlImGui&#34;&gt;rlImGui&lt;/a&gt;, which is a Raylib integration with DearImGui), and the headers of both Dear ImGui and rlImGui.&lt;/p&gt;
&lt;p&gt;That folder (&lt;code&gt;ImGui&lt;/code&gt;) will be dedicated to being a Clang module, as Raylib was previously.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Package.swift
Sources/
    ImGui/
        macOS/
            dearimgui.a
        imconfig.h
        imgui.h
        imgui_internal.h
        ...
        module.modulemap
    CRaylib/
        macOS/
            libraylib.a
        WASM/
            libraylib.a
        raylib.h
    MyGame/
        main.swift
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Again, I declare a &lt;code&gt;module.modulemap&lt;/code&gt; in this folder, to help the compiler make the bridge between the Clang module and Swift:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-clang&#34; data-lang=&#34;clang&#34;&gt;module ImGui [system] {
    header &amp;#34;imgui.h&amp;#34;
    header &amp;#34;rlImGui.h&amp;#34;
    link &amp;#34;imgui&amp;#34;
    export *
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compared to Raylib I exported two headers here: &lt;code&gt;imgui.h&lt;/code&gt; to interact with Dear ImGui, and &lt;code&gt;rlImGui.h&lt;/code&gt; for rlImGui (as a reminder: the bridge between Raylib and Dear ImGui).&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-packageswift-file&#34;&gt;
  The Package.swift file
  &lt;a class=&#34;anchor&#34; href=&#34;#the-packageswift-file&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;As with Raylib, I explicitly define a new target called &lt;code&gt;imgui&lt;/code&gt;, which has a dependency to &lt;code&gt;raylib&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// swift-tools-version: 6.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;PackageDescription&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;package&lt;/span&gt; = Package(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    targets: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Raylib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .target(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;craylib&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            path: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            publicHeadersPath: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            linkerSettings: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .unsafeFlags([&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib/macOS&amp;#34;&lt;/span&gt;], .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Link required macOS graphics frameworks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;OpenGL&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Cocoa&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;IOKit&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;CoreVideo&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// WASM only&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .unsafeFlags([&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib/WASM&amp;#34;&lt;/span&gt;], .when(platforms: [.wasi])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// NEW: ImGui integration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .target(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;imgui&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            dependencies: [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;craylib&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Usage of rlImGui, which needs a dependency to the Raylib Clang module&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            path: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/ImGui&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            publicHeadersPath: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            linkerSettings: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .unsafeFlags([&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/ImGui/macOS&amp;#34;&lt;/span&gt;], .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedLibrary(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;c++&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])), &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// This time I use a C++ library, so I want the C++ standard library linked to that module&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .executableTarget(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            dependencies: [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;craylib&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;imgui&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Now my project has two dependencies: Raylib and Dear ImGui&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=&#34;heading&#34; id=&#34;lets-run-it&#34;&gt;
  Let&amp;rsquo;s run it
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-run-it&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ok, now, I have to change the Swift &lt;code&gt;main.swift&lt;/code&gt; source to use our new dependencies.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;CRaylib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ImGui&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;screenWidth&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;Int32&lt;/span&gt; = 1200
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;screenHeight&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;Int32&lt;/span&gt; = 800
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;InitWindow(screenWidth, screenHeight, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Swift + Raylib + ImGui&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SetTargetFPS(60)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayWhite&lt;/span&gt; = Color(r: 245, g: 245, b: 245, a: 255)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;darkGray&lt;/span&gt; = Color(r: 80, g: 80, b: 80, a: 255)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rlImGuiSetup(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;showDemoWindow&lt;/span&gt; = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; !WindowShouldClose() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    BeginDrawing()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ClearBackground(rayWhite)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    DrawText(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;It&amp;#39;s alive... ALIVE!&amp;#34;&lt;/span&gt;, 300, 300, 20, darkGray)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rlImGuiBegin()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; showDemoWindow {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ImGui.ShowDemoWindow(&amp;amp;showDemoWindow)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rlImGuiEnd()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EndDrawing()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rlImGuiShutdown()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CloseWindow()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code is very simple: I spawn a native window, setup using Raylib, and then draw some text and display the Dear ImGui demo window.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s run that &lt;code&gt;make run-mac&lt;/code&gt; command and&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;unknown&amp;gt;:0: error: too many errors emitted, stopping now
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/Users/me/Devel/craylib/Sources/MyGame/main.swift:4:12: error: could not build Objective-C module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;ImGui&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 2 | 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 3 | &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;#if os(macOS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 4 |     import ImGui
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;- error: could not build Objective-C module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;ImGui&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 5 | &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;#endif&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 6 | 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make: *** [Makefile:17: run-mac] Error 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Oh no.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;upgrading-the-clang-importer&#34;&gt;
  Upgrading the Clang Importer
  &lt;a class=&#34;anchor&#34; href=&#34;#upgrading-the-clang-importer&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;What happened?&lt;/p&gt;
&lt;p&gt;Swift uses a built-in tool called the &lt;a href=&#34;https://www.swift.org/documentation/swift-compiler/&#34;&gt;Clang Importer&lt;/a&gt; to import Clang modules and maps the &lt;strong&gt;C or Objective-C&lt;/strong&gt; APIs for Swift.
This means that the Clang Importer looks at our files, sees C++ keywords like &lt;code&gt;namespace&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;template&lt;/code&gt;, completely &lt;strong&gt;panics&lt;/strong&gt;, and throws an error saying it doesn&amp;rsquo;t recognize the syntax.
This explains why I can easily compile C code, and not C++ code&amp;hellip;&lt;/p&gt;
&lt;p&gt;Thankfully the Swift community managed to make the &amp;ldquo;translation&amp;rdquo; for C++ since Swift 5.9 using the &lt;code&gt;interoperabilityMode&lt;/code&gt; Swift build setting. This setting &lt;a href=&#34;https://www.swift.org/documentation/cxx-interop/project-build-setup/&#34;&gt;enables C++ interoperability for a given target&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;interoperabilityMode&lt;/code&gt; has to be enabled in our executable settings, so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;package&lt;/span&gt; = Package(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    targets: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .executableTarget(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            dependencies: [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;craylib&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;imgui&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            swiftSettings: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .interoperabilityMode(.Cxx) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// tells Swift to parse C++ directly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, does this compile?&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;lets-run-it-2&#34;&gt;
  Let&amp;rsquo;s run it (2)
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-run-it-2&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ok, let build and run it again, and&amp;hellip;&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A native window using Swift, Raylib, and DearImGui&#34; src=&#34;https://carette.xyz/images/swift_cpp_raylib_imgui_native_window.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Mission completed!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Wrapping DearImgui for Swift, a C++ project, was as straightforward as wrapping Raylib.
The subtle difference is simply enabling the C++ interoperability in the package configuration, which is just a matter of a simple Google search (or in your favorite LLM).&lt;/p&gt;
&lt;p&gt;I guess people will argue that this project is not complex or big enough to make assumptions.
And they are right!&lt;/p&gt;
&lt;p&gt;But this is a start, and I don&amp;rsquo;t plan on stopping there&amp;hellip;&lt;/p&gt;
&lt;p&gt;Link to the Github project: &lt;a href=&#34;https://github.com/k0pernicus/swift-c-raylib&#34;&gt;https://github.com/k0pernicus/swift-c-raylib&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Testing the Swift C compatibility with Raylib</title>
      <link>https://carette.xyz/posts/swift_c_compatibility_with_raylib/</link>
      <pubDate>Sun, 22 Mar 2026 14:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/swift_c_compatibility_with_raylib/</guid>
      <description>&lt;p&gt;Since Ladybird team &lt;a href=&#34;https://github.com/LadybirdBrowser/ladybird/commit/e87f889e31afbb5fa32c910603c7f5e781c97afd&#34;&gt;abandoned their Swift&lt;/a&gt; adoption for the browser I heard a lot of criticism about the Swift ecosystem and the interaction between Swift and C/C++ projects.&lt;/p&gt;
&lt;p&gt;My usage of Swift is mainly for command line tools, recreational programming (like &lt;a href=&#34;https://github.com/k0pernicus/aoc2023&#34;&gt;Advent of Code 2023&lt;/a&gt; and previous years) or &lt;a href=&#34;https://github.com/k0pernicus/PhoenixEngine_Swift&#34;&gt;Metal programming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In my previous experiments I really enjoyed &lt;a href=&#34;https://www.swift.org/&#34;&gt;Swift&lt;/a&gt;, and actually preferred it to some other programming languages like &lt;a href=&#34;https://rust-lang.org/&#34;&gt;Rust&lt;/a&gt;. However it seems that programmers have wrong opinions about this programming language, especially about its accessibility (no it is not only for Apple platforms) and &lt;a href=&#34;https://www.swift.org/documentation/articles/wrapping-c-cpp-library-in-swift.html&#34;&gt;its actual power wrapping C/C++ libraries&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Today, I will demonstrate how easy I built a very basic Raylib game using Swift, with no FFI, and for macOS and web (using WASI).&lt;/p&gt;
&lt;p&gt;This article is for demonstration purposes, and is not a tutorial.
To this end I will &lt;strong&gt;not&lt;/strong&gt; explain how to install Swift, the WASM SDK for Swift, etc.&lt;br&gt;
However, if you are interested in reproducing this demonstration at home, you can find the finished project &lt;a href=&#34;https://github.com/k0pernicus/swift-c-raylib&#34;&gt;on my github&lt;/a&gt; and adapt for your own needs.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;swift-3-raylib&#34;&gt;
  Swift &amp;lt;3 Raylib
  &lt;a class=&#34;anchor&#34; href=&#34;#swift-3-raylib&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Unlike other languages, Swift does not require you to write &lt;strong&gt;manual FFI bindings or wrapper layers&lt;/strong&gt; to interact with C code.
FFIs are engineered to be completely invisible and automatic via the Clang importer (more about that later).&lt;/p&gt;
&lt;p&gt;This means you can directly drop your C headers in your project, the static C library, and use the power of the Swift Package Manager to tell the compiler how the project needs to be compiled.&lt;/p&gt;
&lt;p&gt;The code I want to run is very simple: initialize raylib, a window, and drawing a text.&lt;br&gt;
This is the Swift code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;CRaylib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;screenWidth&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;Int32&lt;/span&gt; = 800
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;screenHeight&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;Int32&lt;/span&gt; = 600
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#if&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;os&lt;/span&gt;(&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;WASI&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    InitWindow(screenWidth, screenHeight, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;WASM C Raylib from Swift!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    InitWindow(screenWidth, screenHeight, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Raw C Raylib from Swift!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SetTargetFPS(60)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayWhite&lt;/span&gt; = Color(r: 245, g: 245, b: 245, a: 255)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;darkGray&lt;/span&gt; = Color(r: 80, g: 80, b: 80, a: 255)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; !WindowShouldClose() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    BeginDrawing()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ClearBackground(rayWhite)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    DrawText(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;It&amp;#39;s alive... ALIVE!&amp;#34;&lt;/span&gt;, 300, 300, 20, darkGray)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EndDrawing()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CloseWindow()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=&#34;heading&#34; id=&#34;the-project-structure&#34;&gt;
  The project structure
  &lt;a class=&#34;anchor&#34; href=&#34;#the-project-structure&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Generally a Swift project is constituted like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Package.swift
Sources/
    ProjectName/
        code.swift
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All code in &lt;code&gt;Sources&lt;/code&gt; will be used by the Swift Package Manager to compile my project.&lt;br&gt;
In my case I want to differentiate what comes from the Raylib C project and my own code.
So, my Swift project ends up like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Package.swift
Sources/
    CRaylib/
        macOS/
            libraylib.a
        WASM/
            libraylib.a
        raylib.h
    MyGame/
        main.swift
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Everything in &lt;code&gt;Sources/CRaylib&lt;/code&gt; is related to raylib itself: header files, static libraries (based on platforms, here macOS and WASM), etc.
And everything in &lt;code&gt;Sources/MyGame&lt;/code&gt; is my code, that will use the raylib C code.&lt;/p&gt;
&lt;p&gt;I actually prefer downloading and replacing directly the files in my project, instead of letting a script, the package manager, or even the end-user, download them automatically.
This approach comes directly comes from my experience in game engine development: never trust that the library will be available online in one minute, and never trust that the next version will not end up breaking your project or your dependencies.&lt;br&gt;
This is actually an &amp;ldquo;anti-web&amp;rdquo; way to see things, but it actually saved my (dev-)life more than one time.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-packageswift-file&#34;&gt;
  The Package.swift file
  &lt;a class=&#34;anchor&#34; href=&#34;#the-packageswift-file&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;But how to build that project (let&amp;rsquo;s call it &amp;ldquo;MyGame&amp;rdquo;) now?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s dig into the &lt;code&gt;Package.swift&lt;/code&gt; file at the root of the project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// swift-tools-version: 6.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;PackageDescription&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;package&lt;/span&gt; = Package(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    targets: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .target(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;raylib&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            path: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            publicHeadersPath: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            linkerSettings: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .unsafeFlags([&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib/macOS&amp;#34;&lt;/span&gt;], .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;OpenGL&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Cocoa&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;IOKit&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .linkedFramework(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;CoreVideo&amp;#34;&lt;/span&gt;, .when(platforms: [.macOS])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// WASM only&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .unsafeFlags([&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Sources/CRaylib/WASM&amp;#34;&lt;/span&gt;], .when(platforms: [.wasi])),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .executableTarget(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;MyGame&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            dependencies: [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;raylib&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The interesting part of this demonstration is in how I defined the &lt;code&gt;targets&lt;/code&gt;.
This target is actually a &lt;strong&gt;Clang target&lt;/strong&gt;, which specifies how the target is named, where is the source code, the header, and which libraries the linker needs to interact with for the linking step.&lt;/p&gt;
&lt;p&gt;In this case, I have a target named &lt;code&gt;raylib&lt;/code&gt; with the source code in a relative path (&lt;code&gt;Sources/CRaylib&lt;/code&gt;) and different libraries depending on the OS (&lt;code&gt;macOS&lt;/code&gt; or &lt;code&gt;WASM&lt;/code&gt;).&lt;br&gt;
Very easy!&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;lets-run-it&#34;&gt;
  Let&amp;rsquo;s run it
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-run-it&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;If I try to run my project, I have an issue:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; swift run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;warning: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;craylib&amp;#39;&lt;/span&gt;: ignoring declared target(s) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;craylib, MyGame&amp;#39;&lt;/span&gt; in the system package
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;warning: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;craylib&amp;#39;&lt;/span&gt;: system packages are deprecated; use system library targets instead
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error: no executable product available
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hum, what is going wrong here?&lt;/p&gt;
&lt;p&gt;Swift natively has &lt;strong&gt;no idea&lt;/strong&gt; what a header (or &lt;code&gt;.h&lt;/code&gt;) file is. As in, you cannot write &lt;code&gt;import raylib.h&lt;/code&gt; in a Swift file directly.&lt;/p&gt;
&lt;p&gt;To solve this, Apple built the Clang Importer into the Swift compiler.
When the Swift compiler compiles Swift code, Swift silently boots up Clang, that parses the C headers, translates them into a format Swift can understand, organizes code into &lt;strong&gt;modules&lt;/strong&gt;, and hands them back to Swift through.&lt;/p&gt;
&lt;p&gt;However I actually had to help the compiler making the bridge between this Clang module and Swift, using a &lt;code&gt;module.modulemap&lt;/code&gt; file in my CRaylib project:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-clang&#34; data-lang=&#34;clang&#34;&gt;module CRaylib [system] {
    header &amp;#34;raylib.h&amp;#34;
    link &amp;#34;raylib&amp;#34;
    export *
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the &lt;code&gt;module.modulemap&lt;/code&gt; can be explained like that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;module CRaylib [system]&lt;/code&gt;: &amp;ldquo;Create a brand new Swift module named CRaylib and treat it as a system library&amp;hellip;&amp;rdquo;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;header &amp;quot;raylib.h&amp;quot;&lt;/code&gt;: &amp;ldquo;Here is the exact file you need to parse to find the C functions and structs&amp;hellip;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;link &amp;quot;raylib&amp;quot;&lt;/code&gt;: &amp;ldquo;Whenever a Swift file imports this module, automatically tell the linker to look for a compiled library named libraylib.a&amp;hellip;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;export *&lt;/code&gt;: &amp;ldquo;Take every single C function you find and make it publicly available to my Swift project&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our final project structure is like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Package.swift
Sources/
    CRaylib/
        macOS/
            libraylib.a
        WASM/
            libraylib.a
        raylib.h
        module.modulemap
    MyGame/
        main.swift
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, if I try to run it&amp;hellip; I have a window! Yeah!&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A native window using Swift and C Raylib&#34; src=&#34;https://carette.xyz/images/swift_c_raylib_native_window.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Ok, let&amp;rsquo;s summarize what I did previously:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Downloading and copy-pasting raylib header and static libraries to my project: &lt;strong&gt;EASY&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;Write a &lt;code&gt;Package.swift&lt;/code&gt; file in order to declare my project and its dependencies: &lt;strong&gt;EASY&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;Write a &lt;code&gt;module.modulemap&lt;/code&gt; file to make the transition between raylib C files and my Swift project: &lt;strong&gt;EASY&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;EASY&lt;/strong&gt; + &lt;strong&gt;EASY&lt;/strong&gt; + &lt;strong&gt;EASY&lt;/strong&gt; = &lt;strong&gt;EASY&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;swift-3-wasm&#34;&gt;
  Swift &amp;lt;3 WASM
  &lt;a class=&#34;anchor&#34; href=&#34;#swift-3-wasm&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ok, now that I have a native build&amp;hellip; why not building it for WASM?&lt;/p&gt;
&lt;p&gt;The Swift community made a ton of improvements the last years to build WASM applications using Swift.&lt;br&gt;
If you are interested with it I would advise you to take a look at &lt;a href=&#34;https://www.swift.org/documentation/articles/wasm-getting-started.html&#34;&gt;the official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Building the project for WASM was a bit more complicated, maybe because I miss some documentation to build this kind of project using the WASM SDK for Swift.&lt;/p&gt;
&lt;p&gt;As shown &lt;a href=&#34;#the-packageswift-file&#34;&gt;here&lt;/a&gt; I did link the WASM project with the correct static library, in the correct path.
And I do not have any modification to make in the &lt;code&gt;module.modulemap&lt;/code&gt; file for raylib WASM. Nice.&lt;/p&gt;
&lt;p&gt;All the following is just how to build the final WASM project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; swift build --swift-sdk swift-6.2.4-RELEASE_wasm &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# i am using Swift 6.2.4 and Swift SDK for WASM has been installed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As I build for browser I have a linking error, but my object file has been built using Swift WASM compiler.&lt;/p&gt;
&lt;p&gt;Because Swift&amp;rsquo;s stdlib was built for a headless server (WASI), it expects a terminal.&lt;br&gt;
I needed to write a tiny C stub to intercept those terminal requests (&lt;code&gt;errno&lt;/code&gt;, &lt;code&gt;__wasi_args_sizes_get&lt;/code&gt; and &lt;code&gt;__wasi_args_get&lt;/code&gt;) so the browser&amp;rsquo;s WebGL environment (Emscripten) doesn&amp;rsquo;t panic:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// wasi_stubs.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; errno = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;__wasi_args_sizes_get&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; *argc, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; *argv_buf_size) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *argc = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *argv_buf_size = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;__wasi_args_get&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; *argv, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32_t&lt;/span&gt; *argv_buf) { &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and finally to compile the project using &lt;code&gt;emcc&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;emcc .build/wasm32-unknown-wasip1/debug/MyGame.build/main.swift.o ./wasi_stubs.o &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\ &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Sources/CRaylib/WASM/libraylib.a &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -L&amp;lt;/PATH/TO/YOUR/SWIFT_SDK&amp;gt;/usr/lib/swift_static/wasi &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -lswiftCore &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -s &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;USE_GLFW&lt;/span&gt;=3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -s ASYNCIFY &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -o index.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;&lt;br&gt;
Browsers cannot handle infinite while loops without freezing.&lt;br&gt;
In order to avoid rewriting my infinite loop function in &lt;code&gt;main.swift&lt;/code&gt; I used the magic Emscripten flag &lt;code&gt;ASYNCIFY&lt;/code&gt; to pause the Swift code and let the browser actually draw the frame.&lt;/p&gt;
&lt;p&gt;Once I have my web files generated (&lt;code&gt;index.html&lt;/code&gt;, &lt;code&gt;index.js&lt;/code&gt; and &lt;code&gt;index.wasm&lt;/code&gt;) I can spawn a tiny web server, and go to &lt;code&gt;http://localhost:8080&lt;/code&gt; to see&amp;hellip;&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A WASM window using Swift and C Raylib&#34; src=&#34;https://carette.xyz/images/swift_c_raylib_wasm_window.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The hardest thing was using &lt;code&gt;emcc&lt;/code&gt; to build our final WASM binary.
I did not even need to modify our source code or our project!&lt;/p&gt;
&lt;p&gt;Mission completed!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Wrapping C for Swift was pretty straightforward, and I successfully spawned a window and draw some text using raylib.
The usage of the Swift Package Manager is useful, and I did not need to dig so much into compiler issues, or build wrappers by hand, to actually interact with the C code of raylib.&lt;/p&gt;
&lt;p&gt;So, if you want to build games using raylib, why not learn learning or use Swift for that?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Influentists</title>
      <link>https://carette.xyz/posts/influentists/</link>
      <pubDate>Tue, 06 Jan 2026 16:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/influentists/</guid>
      <description>&lt;p&gt;Last week, the developer community was busy discussing about a single tweet:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I&amp;#39;m not joking and this isn&amp;#39;t funny. We have been trying to build distributed agent orchestrators at Google since last year. There are various options, not everyone is aligned... I gave Claude Code a description of the problem, it generated what we built last year in an hour.&lt;/p&gt;&amp;mdash; Jaana Dogan ヤナ ドガン (@rakyll) &lt;a href=&#34;https://x.com/rakyll/status/2007239758158975130?ref_src=twsrc%5Etfw&#34;&gt;January 2, 2026&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;The author is Jaana Dogan (known as &lt;a href=&#34;https://github.com/rakyll&#34;&gt;Rakyll&lt;/a&gt;), a highly respected figure in the Google ecosystem, in the open-source world, and in my heart (thank you Rakyll for your great &lt;a href=&#34;https://rakyll.org/&#34;&gt;Go blog posts&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;At first glance, the tweet suggests an enormous shift in the software industry: the ability to build &lt;strong&gt;in just one hour&lt;/strong&gt; what previously required weeks or months for a team of sofware engineers, using &lt;strong&gt;just&lt;/strong&gt; the description of the problem. The tweet was too-much dramatic in my own opinion, but actually impressive!&lt;/p&gt;
&lt;p&gt;The post triggered an immediate wave of &amp;ldquo;doom-posting,&amp;rdquo; with many fearing for the future of software engineering (as each week since a year now).
However, as the conversation reached a high number of replies and citations on social networks, Rakyll released a follow-up thread to provide context:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;To cut through the noise on this topic, it’s helpful to provide more more context:&lt;br&gt;&lt;br&gt;- We have built several versions of this system last year. - There are tradeoffs and there hasn&amp;#39;t been a clear winner.&lt;br&gt;- When prompted with the best ideas that survived, coding agents are able to… &lt;a href=&#34;https://t.co/k5FvAah7yc&#34;&gt;https://t.co/k5FvAah7yc&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jaana Dogan ヤナ ドガン (@rakyll) &lt;a href=&#34;https://x.com/rakyll/status/2007659740126761033?ref_src=twsrc%5Etfw&#34;&gt;January 4, 2026&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;This response thread revealed a story &lt;strong&gt;far less miraculous&lt;/strong&gt; than the original tweet suggested.
Let&amp;rsquo;s analyze it.&lt;/p&gt;
&lt;p&gt;Crucially, &lt;strong&gt;the foundational &amp;ldquo;thinking&amp;rdquo; had already been performed by Rakyll herself&lt;/strong&gt;, who guided the AI using architectural concepts (honed over several weeks or months of prior effort) rather than the AI thinking and inventing the &amp;ldquo;product&amp;rdquo; from scratch.&lt;br&gt;
Furthermore, &lt;strong&gt;the resulting project was strictly a proof-of-concept&lt;/strong&gt; that falls far short of a production-ready system capable of managing real-world complexity.&lt;br&gt;
And finally, this success hinged on the Rakyll&amp;rsquo;s &lt;strong&gt;implicit domain knowledge and deep expertise&lt;/strong&gt;. The last point is often (strategically?) omitted from these &amp;ldquo;magic&amp;rdquo; viral demonstrations in order to make the tool appear way more autonomous than it truly is.&lt;/p&gt;
&lt;p&gt;Hmm. Now, this is far less exciting&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;under-influence&#34;&gt;
  Under influence
  &lt;a class=&#34;anchor&#34; href=&#34;#under-influence&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This pattern of &amp;ldquo;&lt;em&gt;hype first and context later&lt;/em&gt;&amp;rdquo; is actually part of a growing trend.&lt;/p&gt;
&lt;p&gt;I call the individuals participating to that trend &amp;ldquo;&lt;strong&gt;The Influentists&lt;/strong&gt;&amp;rdquo;.
Those people are members of a scientific or technical community, and leverage their large audiences to propagate claims that are, at best, unproven and, at worst, &lt;em&gt;intentionally&lt;/em&gt; misleading.&lt;/p&gt;
&lt;p&gt;But how can we spot them?&lt;/p&gt;
&lt;p&gt;I personally identify these &amp;ldquo;Influentists&amp;rdquo; by four personality traits that characterize their public discourse.&lt;br&gt;
The first is a reliance on &lt;strong&gt;&amp;quot;&lt;em&gt;trust-me-bro&lt;/em&gt;&amp;quot; culture&lt;/strong&gt;, where anecdotal experiences are framed as universal, objective truths to generate hype. This is a sentiment perfectly captured by the &lt;em&gt;&amp;ldquo;I’m not joking and this isn’t funny&amp;rdquo;&lt;/em&gt; tone of Rakyll’s original tweet, but also the dramatic &lt;em&gt;&amp;ldquo;I&amp;rsquo;ve never felt that much behind as a programmer&amp;rdquo;&lt;/em&gt; from Andrej Karpathy&amp;rsquo;s tweet.
This is supported by an &lt;strong&gt;absence of reproducible proof&lt;/strong&gt;, as these individuals rarely share the code, data, or methodology behind their viral &amp;ldquo;wins&amp;rdquo;, an omission made easier than ever in the current LLM era.
And finally, they utilize &lt;strong&gt;strategic ambiguity&lt;/strong&gt;, carefully wording their claims with enough vagueness to pivot toward a &amp;ldquo;clarification&amp;rdquo; if the technical community challenges their accuracy.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I&amp;#39;ve never felt this much behind as a programmer. The profession is being dramatically refactored as the bits contributed by the programmer are increasingly sparse and between. I have a sense that I could be 10X more powerful if I just properly string together what has become…&lt;/p&gt;&amp;mdash; Andrej Karpathy (@karpathy) &lt;a href=&#34;https://x.com/karpathy/status/2004607146781278521?ref_src=twsrc%5Etfw&#34;&gt;December 26, 2025&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;h2 class=&#34;heading&#34; id=&#34;a-growing-pattern&#34;&gt;
  A growing pattern
  &lt;a class=&#34;anchor&#34; href=&#34;#a-growing-pattern&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Rakyll is far from alone. We see this &amp;ldquo;hype-first&amp;rdquo; approach across major AI firms like Anthropic, OpenAI, or Microsoft.&lt;/p&gt;
&lt;p&gt;Consider Galen Hunt, a Distinguished Engineer at Microsoft. He recently made waves by claiming a goal to rewrite Microsoft’s massive C/C++ codebases into Rust by 2030 using AI.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Galen Hunt original linkedin post&#34; src=&#34;https://carette.xyz/images/galen_hunt_original_post.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;When the industry pointed out the near-impossible complexity of this task, but also asking clarity for popular and critical products like Microsoft Windows, he was forced to clarify that it was only a &amp;ldquo;research project&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Galen Hunt updated linkedin post&#34; src=&#34;https://carette.xyz/images/galen_hunt_updated_post.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Similarly, engineers from Anthropic and OpenAI oftenly post teasers about &amp;ldquo;AGI being achieved internally&amp;rdquo; to release months later models that disappoint the crowd.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Wait, can we consider seriously the hypothesis that 1) the recent hyped tweets from OA&amp;#39;s staff &lt;br&gt;2) &amp;quot;AGI has been achieved internally&amp;quot; &lt;br&gt;3) sama&amp;#39;s comments on the qualification of slow or fast takeoff hinging on the date you count from &lt;br&gt;4) sama&amp;#39;s comments on 10000x researchers &lt;br&gt;are… &lt;a href=&#34;https://t.co/f57g7dXMhM&#34;&gt;https://t.co/f57g7dXMhM&lt;/a&gt; &lt;a href=&#34;https://t.co/Gap3V7VqkK&#34;&gt;pic.twitter.com/Gap3V7VqkK&lt;/a&gt;&lt;/p&gt;&amp;mdash; Siméon (@Simeon_Cps) &lt;a href=&#34;https://x.com/Simeon_Cps/status/1706078819617063304?ref_src=twsrc%5Etfw&#34;&gt;September 24, 2023&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Liam, I have been a professional programmer for 36 years. I spent 11 years at Google, where I ended up as a Staff Software Engineer, and now work at Anthropic. I&amp;#39;ve worked with some incredible people - you might have heard of Jaegeuk Kim or Ted Ts&amp;#39;o - and some ridiculously… &lt;a href=&#34;https://t.co/Ku8agTrps3&#34;&gt;https://t.co/Ku8agTrps3&lt;/a&gt;&lt;/p&gt;&amp;mdash; Paul Crowley (@ciphergoth) &lt;a href=&#34;https://x.com/ciphergoth/status/2006446942453387675?ref_src=twsrc%5Etfw&#34;&gt;December 31, 2025&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;Similarly, many other companies lie over what they are solving or willing to solve:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/tNmgmwEtoWE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;h2 class=&#34;heading&#34; id=&#34;the-cost-of-unchecked-influence&#34;&gt;
  The cost of unchecked influence
  &lt;a class=&#34;anchor&#34; href=&#34;#the-cost-of-unchecked-influence&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When leaders at major labs propagate these hyped-based results, it can create a &amp;ldquo;technical debt of expectations&amp;rdquo; for the rest of us.
Junior developers see these viral threads and feel they are failing because they can&amp;rsquo;t reproduce a year of work in an hour, not realizing the &amp;ldquo;magic&amp;rdquo; was actually a highly-curated prototype guided by a decade of hidden expertise.&lt;/p&gt;
&lt;p&gt;We must stop granting automatic authority to those who rely on hype, or vibes, rather than evidence.&lt;br&gt;
If a tool or methodology were truly as revolutionary as claimed, then it wouldn&amp;rsquo;t need a viral thread to prove its worth
because &lt;strong&gt;the results would speak for themselves&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The tech community must shift its admiration back toward &lt;strong&gt;reproducible results&lt;/strong&gt; and away from this &amp;ldquo;&lt;em&gt;trust-me-bro&lt;/em&gt;&amp;rdquo; culture.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The CEO cost function</title>
      <link>https://carette.xyz/posts/automated_ceo/</link>
      <pubDate>Fri, 02 Jan 2026 13:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/automated_ceo/</guid>
      <description>&lt;p&gt;We are living through a strange era in tech.&lt;/p&gt;
&lt;p&gt;Every month, a new headline appears. Another CEO announces a massive round of layoffs of managers, developers, and engineers.&lt;br&gt;
They talk about &amp;ldquo;efficiency&amp;rdquo; and &amp;ldquo;streamlining&amp;rdquo;, which should maintain the same quality while spending less on staff.
However the engineers, and the users, on the ground see something else: &lt;a href=&#34;https://www.windowscentral.com/microsoft/windows-11/2025-has-been-an-awful-year-for-windows-11-with-infuriating-bugs-and-constant-unwanted-features&#34;&gt;a decrease in software quality&lt;/a&gt;, &lt;a href=&#34;https://www.windowscentral.com/microsoft/windows-11/microsoft-ai-ceo-pushes-back-against-critics-after-recent-windows-ai-backlash-the-fact-that-people-are-unimpressed-is-mindblowing-to-me&#34;&gt;a loss of institutional knowledge&lt;/a&gt;, and &lt;a href=&#34;https://www.reddit.com/r/softwaredevelopment/comments/1oy40of/ai_coding_tools_ruining_code_quality/&#34;&gt;a product that starts to feel like it’s held together by duct tape&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Meanwhile, &lt;a href=&#34;https://fortune.com/2025/10/22/microsoft-ceo-satya-nadella-pay-hits-a-record-96-5-million-dollars-usd-he-got-a-22-percent-pay-rise-mirroring-the-4-trillion-tech-giants-skyrocketing-shares/&#34;&gt;these same CEOs see their incomes rise&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It makes me wonder. If a CEO&amp;rsquo;s job is essentially a series of inputs (decisions) and outputs (stock price and revenues), can we finally treat that role as a cost function?&lt;br&gt;
If we can model a complex distributed system, why can&amp;rsquo;t we model the person at the top?&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-formula-of-a-leader&#34;&gt;
  The formula of a leader
  &lt;a class=&#34;anchor&#34; href=&#34;#the-formula-of-a-leader&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;History is surprisingly clear on this. We have decades of data on stock movements, economic strategies, and the specific decisions that led to them. We have thousands of articles explaining exactly why a pivot worked or why a merger failed.&lt;/p&gt;
&lt;p&gt;When you strip away the charisma and the expensive suits, &lt;strong&gt;a CEO is just an optimization problem&lt;/strong&gt; over an original idea.&lt;br&gt;
They are trying to maximize a reward function ($J$), which can be simplified as:&lt;/p&gt;
&lt;p&gt;$$J = \sum_{t=0}^{T} \gamma^t (w_1 \cdot R_t + w_2 \cdot S_t + w_3 \cdot U_t - w_4 \cdot Q_t)$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$R_t$: quarterly revenue,&lt;/li&gt;
&lt;li&gt;$S_t$: stock price / market cap,&lt;/li&gt;
&lt;li&gt;$Q_t$: system quality (technical debt, employee retention, bug count, &amp;hellip;),&lt;/li&gt;
&lt;li&gt;$U_t$: user satisfaction (measured via churn rate, NPS, sentiment analysis, &amp;hellip;),&lt;/li&gt;
&lt;li&gt;$w_n$: weights assigned by the board of directors (likely for priorities).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem with human CEOs is that they often set $w_3$ (user satisfaction) or $w_4$ (system quality) to zero if the sum of $w_1$ and $w_2$ (revenues and stocks) are higher.
Their incentives (mostly vesting schedules and annual bonuses) encourage them to maximize $R_t$ and $S_t$ at all costs.&lt;br&gt;
A good AI, however, could be hard-coded with a high $w_3$ value.&lt;br&gt;
Then, it would be mathematically incapable of &amp;ldquo;winning&amp;rdquo; if software quality drops below a certain threshold.&lt;/p&gt;
&lt;p&gt;Human CEOs are expensive, they are prone to ego-driven mistakes, and &lt;a href=&#34;https://abc7news.com/post/artificial-intelligence-ceo-san-francisco-tech-company-replit-apologizes-ai-chatbot-goes-rogue/17295335/&#34;&gt;they often &amp;ldquo;bullshit&amp;rdquo; to cover their tracks&lt;/a&gt;.
An AI wouldn&amp;rsquo;t buy a social media platform on a whim just to prove a point. It would be transparent. It would explain exactly why it chose to cut a budget or invest in a new feature.&lt;/p&gt;
&lt;p&gt;Most importantly, an AI would cost a fraction of the &lt;a href=&#34;https://www.epi.org/publication/ceo-pay-in-2022/&#34;&gt;1,200% increase in CEO pay we&amp;rsquo;ve seen since 1978&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;surgical-cut&#34;&gt;
  Surgical cut
  &lt;a class=&#34;anchor&#34; href=&#34;#surgical-cut&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In the current corporate playbook, layoffs are a blunt instrument. When a CEO needs to save money, they often fire the most expensive people: the Senior Engineers.
This has been explained, once again, by &lt;a href=&#34;https://www.finalroundai.com/blog/aws-ceo-ai-cannot-replace-junior-developers&#34;&gt;AWS CEO a few months ago&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Number two, they [&lt;strong&gt;the junior developers&lt;/strong&gt;] are usually the least expensive because they&amp;rsquo;re right out of college, and they generally make less. So if you&amp;rsquo;re thinking about cost optimization, they&amp;rsquo;re not the only people you would want to optimize around.” AWS CEO Matt Garman&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But the senior people are the same people who know where the &amp;ldquo;bodies are buried&amp;rdquo; in the codebase.
Removing them to save the budget is like a pilot throwing the engines overboard to make the plane lighter.&lt;/p&gt;
&lt;p&gt;An AI CEO would see the company not as a list of salaries, but as a &lt;strong&gt;dependency graph&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If the platform’s stability is failing, the data is usually screaming the reason why.
It might show that the &amp;ldquo;code-to-bug&amp;rdquo; ratio is spiking in a specific department, or that &amp;ldquo;time-to-resolve&amp;rdquo; is dragging because of a bottleneck in management.&lt;/p&gt;
&lt;p&gt;In this scenario, the AI wouldn&amp;rsquo;t fire the engineers.
It would look at the data and realize that the engineers are actually performing well, but are being slowed down by three layers of middle management that produce nothing but meetings.
The AI would perform a surgical cut: &lt;strong&gt;it would remove the bureaucracy to save the builders&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;objectivity-and-truth&#34;&gt;
  Objectivity and Truth
  &lt;a class=&#34;anchor&#34; href=&#34;#objectivity-and-truth&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;By using an AI to manage the &amp;ldquo;human resources&amp;rdquo; of a company, we remove the politics of survival.
In a human-led company, the person who survives a layoff is often the one who is best at &amp;ldquo;managing up&amp;rdquo; - the one the CEO likes personally.&lt;/p&gt;
&lt;p&gt;An AI doesn&amp;rsquo;t have &amp;ldquo;favorites&amp;rdquo;. It only has metrics.&lt;/p&gt;
&lt;p&gt;This brings us to a new kind of &lt;strong&gt;corporate transparency&lt;/strong&gt;. If you are fired by an AI, you get a receipt. You see the data. You see the logic. If your contribution to the system&amp;rsquo;s health is high, the math protects you. If your role is purely administrative and the data shows you are a net-negative on velocity, the math removes you. It’s cold, yes, but it’s honest.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-alignment-problem&#34;&gt;
  The alignment problem
  &lt;a class=&#34;anchor&#34; href=&#34;#the-alignment-problem&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;There is a danger here, of course. If we train an AI on historical data, it might learn the wrong lessons.&lt;/p&gt;
&lt;p&gt;As an example, if the history shows that every time a company fires 10% of its staff stock price jumps for two months, then the AI will keep firing everyone until there is no company left.
This is totally normal for the AI because it tries to maximize the reward at the expense of survival.&lt;/p&gt;
&lt;p&gt;This is the classic &amp;ldquo;&lt;strong&gt;alignment problem&lt;/strong&gt;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;There is also the risk of &amp;ldquo;&lt;strong&gt;corporate monoculture&lt;/strong&gt;&amp;rdquo;.&lt;br&gt;
If every company uses the same CEO model trained on the same data, every company will act exactly the same.
They will all chase the same trends and be exploited by anyone who figures out the algorithm.&lt;/p&gt;
&lt;p&gt;And then there is the &lt;strong&gt;morality&lt;/strong&gt;.
An algorithm doesn&amp;rsquo;t care about the families affected by a decision.
It only cares about the math.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;self-correctness&#34;&gt;
  Self-correctness
  &lt;a class=&#34;anchor&#34; href=&#34;#self-correctness&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The solution of alignment problem and corporate monoculture isn&amp;rsquo;t just a better model, but &lt;strong&gt;better engineering&lt;/strong&gt;.
We need &lt;strong&gt;exploration&lt;/strong&gt;, not just exploitation of past data.&lt;/p&gt;
&lt;p&gt;We can imagine a system where the AI is not just a decision-maker, but also its own judge.
As an example, we could have a &amp;ldquo;self-introspection layer&amp;rdquo;, a secondary model that audits the decisions made in the previous quarter and refines the decisions for the next round.&lt;/p&gt;
&lt;p&gt;If the &amp;ldquo;CEO Model&amp;rdquo; predicted that firing the entire QA team would save $22M without affecting quality, but the &amp;ldquo;auditor model&amp;rdquo; sees that bug reports increased by 40% and user retention dropped, the system corrects itself. It adjusts its own &amp;ldquo;cost function&amp;rdquo;. It learns that short-term savings are actually long-term liabilities, &lt;strong&gt;for the company it tries to manage&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is something human CEOs rarely do as admitting a mistake is politically expensive for a human CEO. However, for an AI it is just a weight adjustment of its function.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;augmented-ceo&#34;&gt;
  &amp;ldquo;Augmented CEO&amp;rdquo;
  &lt;a class=&#34;anchor&#34; href=&#34;#augmented-ceo&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We aren&amp;rsquo;t ready to hand the keys of the boardroom to a server rack just yet. However the &amp;ldquo;augmented CEO&amp;rdquo; is already becoming a necessity.&lt;/p&gt;
&lt;p&gt;Imagine a board meeting where every proposal is stress-tested against 10,000 simulations. The CEO says, &amp;ldquo;We need to layoff 500 engineers to hit our quarterly targets&amp;rdquo;.
The AI responds, &amp;ldquo;That decision has an 85% probability of causing a system-wide outage within 12 months due to lost expertise&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;In this world, &lt;strong&gt;decisions become data-driven instead of gut-driven&lt;/strong&gt;.
It forces a level of honesty that the current corporate structure lacks, or do not want to listen on purpose.&lt;/p&gt;
&lt;p&gt;Also, to have a companion for that would reduce the bonus and salary as the CEO is not anymore the executive,
but just an &amp;ldquo;interface&amp;rdquo; between the AI and the board of directors.&lt;/p&gt;
&lt;p&gt;The conclusion is simple, even if it&amp;rsquo;s uncomfortable for those at the top. The idea that certain roles are &amp;ldquo;too human&amp;rdquo; or &amp;ldquo;too complex&amp;rdquo; to be automated is a myth.&lt;br&gt;
History shows that no one is truly irreplaceable.
Once the cost function is solved, not even the CEO is safe.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Going immutable on macOS</title>
      <link>https://carette.xyz/posts/going_immutable_macos/</link>
      <pubDate>Wed, 31 Dec 2025 14:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/going_immutable_macos/</guid>
      <description>&lt;p&gt;With no surprise the end of one year marks the start of the next.&lt;br&gt;
And the beginning of a year is always synonymous with&amp;hellip; a fresh macOS system!&lt;/p&gt;
&lt;p&gt;But managing a good working environment on macOS has long been a game of &amp;ldquo;hope for the best.&amp;rdquo; We’ve all been there: a &lt;code&gt;curl | sh&lt;/code&gt; here, a manual &lt;code&gt;brew install&lt;/code&gt; there, and six months later, you’re staring at a broken &lt;code&gt;PATH&lt;/code&gt; and a Python environment that seems to have developed its own consciousness.&lt;/p&gt;
&lt;p&gt;I’ve spent a lot of time recently moving my entire workflow into a declarative system using nix. From my zsh setup to my odin toolchain, here is why the transition from the imperative world of &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt; to the immutable world of &lt;a href=&#34;https://nix-darwin.org/&#34;&gt;nix-darwin&lt;/a&gt; has been both a revelation and a fight.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-problem-to-solve-imperative-rot&#34;&gt;
  The problem to solve: imperative rot
  &lt;a class=&#34;anchor&#34; href=&#34;#the-problem-to-solve-imperative-rot&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Homebrew is great.&lt;br&gt;
From the Linux world, it was the perfect missing package manager for macOS at first, promoted by a lot of developers, and it (mostly) works.
But Homebrew has a problem: it is imperative.&lt;/p&gt;
&lt;p&gt;When you run &lt;code&gt;brew install&lt;/code&gt; &lt;strong&gt;you are changing the state of your machine&lt;/strong&gt; in a way that is difficult to reverse or replicate exactly.&lt;br&gt;
As an example, if I set up a new Mac today, &lt;code&gt;brew install neovim&lt;/code&gt; might give me version 0.10. However, if I do it six months from now, the version might changed and I had to reconfigure some components because of that change. The consequence is me, spending a few hours debugging my environment instead of writing code.&lt;/p&gt;
&lt;p&gt;A solution to that is postfix every brew package by its version, but this is not possible for every package.&lt;/p&gt;
&lt;p&gt;Another solution is system immutability and the Nix store.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;system-immutablility-and-the-nix-store&#34;&gt;
  System immutablility, and the Nix store
  &lt;a class=&#34;anchor&#34; href=&#34;#system-immutablility-and-the-nix-store&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://nixos.org/&#34;&gt;Nix&lt;/a&gt; approaches the problem from a functional programming perspective.&lt;br&gt;
Your system is not a collection of side effects, but a &lt;strong&gt;pure function&lt;/strong&gt; of your configuration.&lt;/p&gt;
&lt;p&gt;This allows different strong points like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;reproducibility&lt;/strong&gt;: Every package lives in &lt;code&gt;/nix/store&lt;/code&gt; with a unique hash. This means I can have three different versions of the Odin compiler side-by-side, and they will never see each other, or even mess up with the different versions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rollbacks&lt;/strong&gt;: If a system update breaks my shell, I don&amp;rsquo;t panic. I just boot into a previous generation. The previous state of my system is still sitting in the store, untouched.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;flakes&lt;/strong&gt;: Using &lt;code&gt;flake.lock&lt;/code&gt;, I pin my setup to specific git commits. If it works on my laptop then &lt;strong&gt;it will work&lt;/strong&gt; on yours. Period.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rollbacks on macOS exist, and are great to go back to a previous version &amp;ldquo;that works&amp;rdquo;.&lt;br&gt;
As an example, to list all my previous generations, I can do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; sudo nix-env --list-generations -p /nix/var/nix/profiles/system
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   1   2025-12-28 01:21:38
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   2   2025-12-28 01:33:47
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   3   2025-12-28 09:34:27
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   4   2025-12-28 09:43:15
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   5   2025-12-28 11:00:49
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   6   2025-12-28 11:10:12
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   7   2025-12-28 11:19:03
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each generation is also stored in a read-only specific volume on your system, which prevents accidental mutability of your packages.&lt;/p&gt;
&lt;p&gt;On macOS &lt;code&gt;nix-darwin&lt;/code&gt; allows me to modify everything, from Finder settings to the Dock, or the Trackpad.&lt;/p&gt;
&lt;p&gt;As an example, this is a part of my setup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;configuration = { pkgs, ... }: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Firewall settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    networking.applicationFirewall = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        enable = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        enableStealthMode = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allowSigned = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allowSignedApp = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    system.defaults = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        CustomUserPreferences = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Disable siri&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;com.apple.Siri&amp;#34;&lt;/span&gt; = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;UAProfileCheckingStatus&amp;#34;&lt;/span&gt; = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;siriEnabled&amp;#34;&lt;/span&gt; = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Disable personalized ads &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;com.apple.AdLib&amp;#34;&lt;/span&gt; = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            allowApplePersonalizedAdvertising = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Show battery percentage in the menu bar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        controlcenter.BatteryShowPercentage = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Allow touch to click&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        trackpad.Clicking = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Hide the dock after a small delay of inactivity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        dock.autohide = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        dock.autohide-delay = 0.25;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And all those settings are documented in the official nix-darwin manual &lt;a href=&#34;https://nix-darwin.github.io/nix-darwin/manual/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-nix-flake&#34;&gt;
  The Nix flake
  &lt;a class=&#34;anchor&#34; href=&#34;#the-nix-flake&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Before diving into the pros and cons of Nix, we need to address the engine under the hood: &lt;strong&gt;The Nix Flake&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In the traditional Nix world, things were a bit loose.&lt;br&gt;
You had &amp;ldquo;channels&amp;rdquo;, but &amp;ldquo;channels&amp;rdquo; that could change behind your back&amp;hellip; and we don&amp;rsquo;t want to get back to mutable systems.&lt;br&gt;
Nix flakes fixed this by introducing a strictly defined structure.&lt;/p&gt;
&lt;p&gt;Every Flake has a &lt;code&gt;flake.nix&lt;/code&gt; (the blueprint) and a &lt;code&gt;flake.lock&lt;/code&gt; (the time capsule).&lt;/p&gt;
&lt;p&gt;The lockfile is actually the secret sauce.&lt;br&gt;
It records the exact git commit of every dependency. When I build my system, I’m not just asking for &amp;ldquo;the latest version of the Odin programming language&amp;rdquo;, but for the exact version of Odin that existed at a specific moment in history.&lt;/p&gt;
&lt;p&gt;So, when you run &lt;code&gt;darwin-rebuild switch --flake .&lt;/code&gt; to update your system (depending on configuration changes), Nix will look first at the lockfile.
If the lockfile says you are using &lt;code&gt;nixpkgs&lt;/code&gt; from October 12th at 10:45 PM, that is exactly what it fetches.
Nix doesn&amp;rsquo;t matter if you are on a new MacBook or an old iMac. If the lockfile is the same, then the resulting environment will be identical to your previous setup.&lt;/p&gt;
&lt;p&gt;This turns system administration into a pure function: &lt;strong&gt;the same inputs always produce the same result&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-get-and-forget-workflow&#34;&gt;
  The &amp;ldquo;get and forget&amp;rdquo; workflow
  &lt;a class=&#34;anchor&#34; href=&#34;#the-get-and-forget-workflow&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One of the most liberating features is the &amp;ldquo;ephemeral shell&amp;rdquo; provided by Nix.&lt;br&gt;
Imagine you need to test a script against &lt;code&gt;Python 3.15&lt;/code&gt;, but you don&amp;rsquo;t want to install a pre-release version globally and risk breaking your system tools&amp;hellip;&lt;/p&gt;
&lt;p&gt;With Nix, you run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nix shell nixpkgs#python314
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Suddenly, &lt;code&gt;python --version&lt;/code&gt; returns 3.14.
You run your tests, you exit the shell, &lt;strong&gt;and it’s gone&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;No leftovers, no site-packages conflicts, no trace.
It is the ultimate &amp;ldquo;get and forget&amp;rdquo; utility, without messing up your system.&lt;/p&gt;
&lt;p&gt;However be careful as &lt;strong&gt;&amp;ldquo;ephemeral&amp;rdquo; does not mean &amp;ldquo;sandboxed&amp;rdquo; or &amp;ldquo;isolated&amp;rdquo;&lt;/strong&gt; in this context!
A common misconception is that &lt;code&gt;nix shell&lt;/code&gt; is like a Docker container or a VM, but it is not as &lt;code&gt;nix shell&lt;/code&gt; only isolated the environment variables, and is still running directly on the darwin kernel.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-learning-curve-cliff&#34;&gt;
  The learning &lt;del&gt;curve&lt;/del&gt; cliff
  &lt;a class=&#34;anchor&#34; href=&#34;#the-learning-curve-cliff&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Is this configuration exempt from defaults? Absolutely not.&lt;br&gt;
In fact, its biggest &amp;ldquo;default&amp;rdquo; is one of the most significant pain points in modern software: it arrives wrapped in complicated concepts and dense foundations.&lt;/p&gt;
&lt;p&gt;The learning curve for Nix is actually not a curve, but a vertical cliff face.&lt;/p&gt;
&lt;p&gt;Unlike Homebrew, where you just type a command and forget it, Nix requires you to learn a &lt;a href=&#34;https://nix.dev/tutorials/nix-language.html&#34;&gt;domain-specific language called&amp;hellip; &lt;code&gt;Nix&lt;/code&gt; (I know, it is confusing)&lt;/a&gt;. You have to understand how symbolic links work on macOS, how the Nix daemon interacts with Apple&amp;rsquo;s read-only system volume, and why your applications don&amp;rsquo;t magically appear in Spotlight.&lt;/p&gt;
&lt;p&gt;For instance, getting GUI apps to show up in the Applications folder requires &amp;ldquo;trampoline&amp;rdquo; binaries or custom activation scripts using &lt;code&gt;mkalias&lt;/code&gt;.&lt;br&gt;
After a few minutes debugging and scrolling forums it works great, but many users will simply stop there and walking away with the mistaken impression that &lt;code&gt;nix-darwin&lt;/code&gt; is an immature project, rather than a deeply powerful one.&lt;/p&gt;
&lt;p&gt;The documentation is great, but maybe not well arranged.&lt;br&gt;
As an example, this is the manual to write your own &lt;code&gt;flake.nix&lt;/code&gt;: &lt;a href=&#34;https://nix-darwin.github.io/nix-darwin/manual/&#34;&gt;https://nix-darwin.github.io/nix-darwin/manual/&lt;/a&gt;.
You can be lost very easily in the manual if you do not know what you are looking for&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-hybrid-reality&#34;&gt;
  The hybrid reality
  &lt;a class=&#34;anchor&#34; href=&#34;#the-hybrid-reality&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Despite my love for Nix, it isn&amp;rsquo;t perfect for everything.
macOS GUI applications like Thunderbird, Firefox, or CrossOver, often fight against the read-only nature of the Nix store.&lt;br&gt;
Those software &lt;strong&gt;expect&lt;/strong&gt; to self-update and live in &lt;code&gt;/Applications&lt;/code&gt; on your system.&lt;/p&gt;
&lt;p&gt;I found the sane path to be an hybrid approach: I use &lt;code&gt;nix-darwin&lt;/code&gt; to manage my critical state (compilers, LSPs, shell aliases), and use the homebrew module inside my Nix config to handle the big GUI pieces. It looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-Nix&#34; data-lang=&#34;Nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;// file: brew.nix
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;homebrew = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  enable = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  casks = [ 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;firefox&amp;#34;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;thunderbird&amp;#34;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;crossover&amp;#34;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s it!
And using this, I am sure Nix will use &lt;code&gt;brew&lt;/code&gt; to install those software on my system, as I did manually with my &lt;code&gt;brew install&lt;/code&gt; scripts.&lt;/p&gt;
&lt;p&gt;This gives me the best of both worlds: Homebrew handles the macOS-specific integration, but Nix still &amp;ldquo;records&amp;rdquo; that they should exist in my declarative blueprint.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;how-to-start&#34;&gt;
  How to start
  &lt;a class=&#34;anchor&#34; href=&#34;#how-to-start&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you want to move away from &amp;ldquo;hope-based&amp;rdquo; configuration:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;install the &lt;a href=&#34;https://docs.determinate.systems/&#34;&gt;Determinate Nix Installer&lt;/a&gt;: it handles the messy macOS multi-user setup for you.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;initialize a Flake and &lt;a href=&#34;https://nix-community.github.io/home-manager/&#34;&gt;&lt;code&gt;home-manager&lt;/code&gt;&lt;/a&gt;: Create a &lt;code&gt;flake.nix&lt;/code&gt; and a &lt;code&gt;home.nix&lt;/code&gt; for your home-manager instance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;think &lt;strong&gt;&amp;ldquo;modularity&amp;rdquo;&lt;/strong&gt;, like keeping your system settings in &lt;code&gt;system.nix&lt;/code&gt;, your dev tools in &lt;code&gt;dev.nix&lt;/code&gt;, and your GUI apps in &lt;code&gt;brew.nix&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;version &lt;strong&gt;everything&lt;/strong&gt; and commit your &lt;code&gt;flake.lock&lt;/code&gt;! It is the source of truth for your system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are curious I’ve documented my current setup, including my security hardening (firewall, stealth mode, etc.) here: &lt;a href=&#34;https://github.com/k0pernicus/dotfiles/tree/master/system/nix-darwin-config&#34;&gt;k0pernicus/dotfiles/nix-darwin-config&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Keep in mind this configuration is personal, and might not be interesting (and certainly not useful) for everyone.&lt;/p&gt;
&lt;p&gt;A few links that helped me to make a first setup version for my mac:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://nixcademy.com/posts/nix-on-macos/&#34;&gt;https://nixcademy.com/posts/nix-on-macos/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dreamsofcode.io/blog/nix-darwin-my-favorite-package-manager-for-macos&#34;&gt;https://dreamsofcode.io/blog/nix-darwin-my-favorite-package-manager-for-macos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/torgeir/nix-darwin&#34;&gt;https://github.com/torgeir/nix-darwin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s more work upfront, certainly.
But there is a profound peace of mind in knowing that your system is defined by code, not by a history of forgotten terminal commands.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Deep dive into crossover</title>
      <link>https://carette.xyz/posts/deep_dive_into_crossover/</link>
      <pubDate>Sat, 20 Dec 2025 15:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/deep_dive_into_crossover/</guid>
      <description>&lt;p&gt;If you read my previous post about &lt;a href=&#34;https://carette.xyz/posts/crossover_mac_retro_games&#34;&gt;gaming on mac&lt;/a&gt;, you know I have a soft spot for running Windows games on Apple Silicon.&lt;/p&gt;
&lt;p&gt;Early this year I upgraded from a M1 MacBook Air to an M3 Max MacBook Pro.
Naturally, I had to test three completely different generations of games at it: &lt;a href=&#34;https://en.wikipedia.org/wiki/ARC_Raiders&#34;&gt;&lt;em&gt;ARC Raiders&lt;/em&gt;&lt;/a&gt; (2025), &lt;a href=&#34;https://en.wikipedia.org/wiki/Routine_(video_game)&#34;&gt;&lt;em&gt;Routine&lt;/em&gt;&lt;/a&gt; (2025), &lt;a href=&#34;https://en.wikipedia.org/wiki/Watch_Dogs_2&#34;&gt;&lt;em&gt;Watch Dogs 2&lt;/em&gt;&lt;/a&gt; (2016) and &lt;a href=&#34;https://en.wikipedia.org/wiki/Tron_2.0&#34;&gt;&lt;em&gt;Tron 2.0&lt;/em&gt;&lt;/a&gt; (2003).&lt;/p&gt;
&lt;p&gt;I expected the modern game to struggle and the old game to fly.
The reality was exactly the opposite, and it forced me to dig deep into how &lt;a href=&#34;https://www.codeweavers.com/crossover&#34;&gt;CrossOver&lt;/a&gt; handles translation layers under the hood.&lt;/p&gt;
&lt;p&gt;This article summarizes my investigations and challenges to play DirectX 12, Direct 11, and DirectX 9 games, using Crossover.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-modern-stack-d3dmetal-and-msync&#34;&gt;
  The modern stack: D3DMetal and MSync
  &lt;a class=&#34;anchor&#34; href=&#34;#the-modern-stack-d3dmetal-and-msync&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;there-is-no-place-for-anti-cheats&#34;&gt;
  There is no place for anti-cheats
  &lt;a class=&#34;anchor&#34; href=&#34;#there-is-no-place-for-anti-cheats&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with the bad news: no, you still can&amp;rsquo;t play everything.
Despite the M3 Max being a hardware beast, there is a hard software wall called Kernel-level Anti-Cheat.&lt;br&gt;
I am not going to get into the debate of if it is useful or not, but if you are interested in that debate you can feed &lt;a href=&#34;https://steamcommunity.com/app/2807960/discussions/0/664963107066558385/&#34;&gt;this Steam forum discussion&lt;/a&gt;.&lt;br&gt;
Games like &lt;em&gt;ARC Raiders&lt;/em&gt; are strictly unplayable because Wine cannot emulate the deep Windows kernel access that Easy Anti-Cheat (EAC) or BattlEye require. If your target game relies on invasive anti-cheat then the Crossover solution is not the good one, as there is no &amp;ldquo;userspace bridge&amp;rdquo; built by Apple and / or Crossover to support those software.&lt;br&gt;
For that kind of games you might be interested in installing a Windows VM and then install Steam and your game(s) on that system, but this is not the purpose of this blog post.&lt;/p&gt;
&lt;p&gt;However, for the vast majority of single-player titles that don&amp;rsquo;t treat the OS like a crime scene, the landscape has changed dramatically.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;ARC Raiders&lt;/em&gt; : &lt;strong&gt;Fail&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-routine&#34;&gt;
  The routine
  &lt;a class=&#34;anchor&#34; href=&#34;#the-routine&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;First, I tried the most recent game, &lt;em&gt;Routine&lt;/em&gt;. &lt;em&gt;Routine&lt;/em&gt; is made using Unreal Engine and uses the DirectX 12 graphics API under the hood.&lt;br&gt;
I tried this game on a default &amp;ldquo;Steam&amp;rdquo; bottle on Crossover, with &amp;ldquo;Auto&amp;rdquo; settings, and&amp;hellip; it launched successfully! No graphics or performance issue, no issue recovering my saves through Steam cloud, and I successfully continued the game I began on my other machine.&lt;/p&gt;
&lt;p&gt;Great!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Routine&lt;/em&gt; : &lt;strong&gt;Great success&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-hackerspace&#34;&gt;
  The hackerspace
  &lt;a class=&#34;anchor&#34; href=&#34;#the-hackerspace&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Next, I tried &lt;em&gt;Watch Dogs 2&lt;/em&gt;. This game is almost 10 years old, and runs on DirectX 11.&lt;br&gt;
As &lt;em&gt;Routine&lt;/em&gt; I tried with the auto settings, but the game did run poorly, and glitchees appeared too regularly.&lt;br&gt;
It was time to tweak the machine!&lt;/p&gt;
&lt;p&gt;On modern versions of CrossOver (23+), we have a new toy: &lt;strong&gt;D3DMetal&lt;/strong&gt;.
This is essentially &lt;a href=&#34;https://developer.apple.com/games/game-porting-toolkit/&#34;&gt;Apple&amp;rsquo;s Game Porting Toolkit (GPTK)&lt;/a&gt; integrated directly into CrossOver.&lt;br&gt;
Using GPTK, instead of the traditional translation path: &lt;code&gt;DirectX&lt;/code&gt; -&amp;gt; &lt;code&gt;Vulkan&lt;/code&gt; (via DXVK) -&amp;gt; &lt;code&gt;Metal&lt;/code&gt; (via MoltenVK), D3DMetal translates DirectX headers &lt;em&gt;&lt;strong&gt;directly&lt;/strong&gt;&lt;/em&gt; to Metal.&lt;br&gt;
GPTK is a great tech, and enable some modern games to run on macOS. If you want to know more for a list of compatible games I invite you to look for &lt;a href=&#34;https://macgametoolkit.com/&#34;&gt;this website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Going back to Crossover, I enabled the D3DMetal flag it in the bottle settings, along with MSync and the performances were &lt;strong&gt;much&lt;/strong&gt; better, despite regular stutters I investigated and actually solved (more in the next section).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
For those who missed the memo, MSync replaces the old ESync/FSync methods.
Instead of using &lt;code&gt;eventfd&lt;/code&gt; (which is a Linux kernel feature that macOS lacks and must emulate), MSync maps Wine synchronization primitives directly to macOS native &lt;code&gt;kqueue&lt;/code&gt; or Mach semaphores. The result is a &lt;strong&gt;much&lt;/strong&gt; lower CPU overhead.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-retina-problem&#34;&gt;
  The retina problem
  &lt;a class=&#34;anchor&#34; href=&#34;#the-retina-problem&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;However, performance was initially terrible. Why? Because macOS tells the game: &amp;ldquo;Hey, I have a 3024x1964 screen!&amp;rdquo; and the game engine says &amp;ldquo;OK!&amp;rdquo; and tries to render a poorly optimized open-world at 4K.&lt;/p&gt;
&lt;p&gt;The fix was simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;turn &lt;strong&gt;OFF&lt;/strong&gt; &amp;ldquo;High Resolution Mode&amp;rdquo; in the bottle settings.&lt;/li&gt;
&lt;li&gt;force the game to 1920x1080.&lt;/li&gt;
&lt;li&gt;enable &lt;strong&gt;Temporal Filtering&lt;/strong&gt; in the game engine (which essentially renders at lower res and upscales).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Suddenly, the M3 Max was pushing stable frames. Unfortunately this &amp;ldquo;modern&amp;rdquo; approach completely breaks when you look backward.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Watch Dogs 2&lt;/em&gt; : &lt;strong&gt;Success&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-legacy-stack-when-d3dmetal-fails&#34;&gt;
  The legacy stack: when D3DMetal fails
  &lt;a class=&#34;anchor&#34; href=&#34;#the-legacy-stack-when-d3dmetal-fails&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I then tried to run &lt;em&gt;Tron 2.0&lt;/em&gt;, a monolith classic from 2003 running on the LithTech engine (DirectX 9).&lt;/p&gt;
&lt;p&gt;I naively kept D3DMetal on. The result? An instant crash.&lt;/p&gt;
&lt;p&gt;Here is the technical reason: &lt;strong&gt;D3DMetal does not support DirectX 9&lt;/strong&gt;. It currently only handles DX11 and DX12 instructions. For older games, you &lt;em&gt;must&lt;/em&gt; fallback to the translation chain: &lt;code&gt;DirectX 9&lt;/code&gt; -&amp;gt; &lt;code&gt;DXVK&lt;/code&gt; -&amp;gt; &lt;code&gt;MoltenVK&lt;/code&gt; -&amp;gt; &lt;code&gt;Metal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, I created a separate bottle (and this is crucial: &lt;strong&gt;never mix eras&lt;/strong&gt;).&lt;br&gt;
I set this bottle to Windows XP mode to avoid modern OS overhead, and enabled DXVK.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-case-of-the-missing-dll&#34;&gt;
  The case of the missing DLL
  &lt;a class=&#34;anchor&#34; href=&#34;#the-case-of-the-missing-dll&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Even with the correct graphics layer, the game wouldn&amp;rsquo;t start. This is where it gets interesting for C++ developers.&lt;/p&gt;
&lt;p&gt;The crash wasn&amp;rsquo;t graphical. It was a missing dependency: &lt;code&gt;msvcirt.dll&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This library is the &lt;em&gt;old&lt;/em&gt; C++ runtime (MSVC 6.0 era). Modern Windows (and by extension, modern Wine bottles) have largely deprecated or removed it. The game was calling functions in a dynamic library that simply didn&amp;rsquo;t exist in the virtual &lt;code&gt;system32&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;To fix this, I had to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;manually create a &lt;code&gt;Windows XP&lt;/code&gt; bottle (which is more likely to handle legacy calls).&lt;/li&gt;
&lt;li&gt;use the &amp;ldquo;Install Software&amp;rdquo; tool to inject &lt;code&gt;DirectX for Modern Games&lt;/code&gt; (which oddly enough, contains legacy DX9 redistributables).&lt;/li&gt;
&lt;li&gt;manually patch the executable with the community-made &amp;ldquo;Killer App Mod&amp;rdquo; to strip the DRM that Wine couldn&amp;rsquo;t parse.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Tron 2.0&lt;/em&gt; : &lt;strong&gt;Partial success&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-proton-reality-check&#34;&gt;
  The proton reality check
  &lt;a class=&#34;anchor&#34; href=&#34;#the-proton-reality-check&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;On the four games I wanted to test only &lt;strong&gt;one&lt;/strong&gt; launched with great perfor,ances &amp;ldquo;out of the box“.
Two have been tweaked to run great, and only one did not run at all (due to anti-cheats software compatibility).&lt;/p&gt;
&lt;p&gt;We often think of &amp;ldquo;emulation&amp;rdquo; (or translation, in Wine&amp;rsquo;s case) as a linear performance cost. But on Apple Silicon, it&amp;rsquo;s really about choosing the right translation path:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;retro&amp;rdquo; Games&lt;/strong&gt; (&amp;lt;= 2012): use &lt;code&gt;DXVK&lt;/code&gt; as it handles the fixed-function pipeline of older DirectX versions way better than Apple&amp;rsquo;s toolkit does,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;modern&amp;rdquo; Games&lt;/strong&gt; (&amp;gt; 2012): use &lt;code&gt;D3DMetal&lt;/code&gt; and &lt;code&gt;MSync&lt;/code&gt; provides the best combo here as it skips the Vulkan translation overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, we have to address the elephant in the room: &lt;strong&gt;Proton on Linux&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you own a Steam Deck or run Linux on your desktop, you know that the experience is lightyears ahead of what we have on macOS. Why? Because Proton (Valve&amp;rsquo;s fork of Wine) is solving a much simpler equation.&lt;/p&gt;
&lt;p&gt;On Linux (x86_64), the CPU instructions are native. Proton only needs to translate Windows API calls to Linux Kernel calls, and DirectX to Vulkan. It&amp;rsquo;s a 1:1 translation.&lt;/p&gt;
&lt;p&gt;On macOS (Apple Silicon), the translations are more expensive:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rosetta 2 translates x86_64 instructions to ARM64 (CPU overhead),&lt;/li&gt;
&lt;li&gt;CrossOver translates Windows API to macOS API (OS overhead),&lt;/li&gt;
&lt;li&gt;D3DMetal translates DirectX to Metal (GPU overhead).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This triple-layer cake is technical wizardry, but it explains why my $400 Steam Deck can sometimes launch a game with fewer glitches (and slightly better performance) than an Apple Silicon MacBook Pro. Proton simply has less distance to cover, and Vulkan is a first-class citizen on Linux.&lt;/p&gt;
&lt;p&gt;I actually tried to run the same four games on another machine using CachyOS with Proton and&amp;hellip; &lt;strong&gt;all four games launched without any tweak&lt;/strong&gt;.
That is a &lt;strong&gt;major success&lt;/strong&gt; for the Linux community.&lt;/p&gt;
&lt;p&gt;Maybe MacBooks will come to launch and run natively Windows games (&lt;strong&gt;if&lt;/strong&gt; Apple wants to).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Chaos or comfort: a reflection on the engineer&#39;s quest</title>
      <link>https://carette.xyz/posts/chaos_or_comfort/</link>
      <pubDate>Mon, 25 Aug 2025 16:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/chaos_or_comfort/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;br&gt;
Article fully writtened by the author, but grammar correction by Gemini.&lt;br&gt;
Images generated using Gemini.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Every software engineer I know is searching for it.&lt;br&gt;
Me included.&lt;br&gt;
They don&amp;rsquo;t always call it the same thing, but the desire is universal.&lt;/p&gt;
&lt;p&gt;I call it the &amp;ldquo;holy grail&amp;rdquo;.
That one project, that perfect role, where we get to solve problems that matter.
The kind of deep, complex, elegant challenges in architecture, scaling, or algorithmic design that can justify long hours of coding and debugging. It&amp;rsquo;s the work that finally makes us feel like true engineers: the builders and architects of what could like the future.&lt;/p&gt;
&lt;p&gt;We often associate this grail with a specific company or a famous team. But this search is a mirage. The grail isn&amp;rsquo;t waiting for you in a specific building or behind a particular logo. It&amp;rsquo;s a phantom we chase, and the landscape of our industry has cleaved the path to it in two.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-forge-of-chaos&#34;&gt;
  The forge of Chaos
  &lt;a class=&#34;anchor&#34; href=&#34;#the-forge-of-chaos&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;On one side, you have the startup. This is the path of &lt;strong&gt;trial by fire&lt;/strong&gt;.&lt;br&gt;
The prevailing wisdom here is that to build something new, or innovative, you must move at a speed that is fundamentally at odds with stability.&lt;/p&gt;
&lt;p&gt;The main goal of a startup is not to be right, but &lt;strong&gt;to be first&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this world, and based on my experience on several startups before, an engineer is rarely just an engineer. A Software engineer can also be an architect, part of the DevOps team, a database administrator, and, if you are not lucky, part of the on-call support.
And all of this can happen in the same afternoon.&lt;/p&gt;
&lt;p&gt;You are handed a blank canvas and told to build a cathedral by next Tuesday.
The result is an environment of incredible learning velocity. You&amp;rsquo;re forced to understand the entire stack because &lt;strong&gt;you&lt;/strong&gt; are the entire stack. You learn about resilience because you are the one who has to fix the server when it inevitably crashes at 3 AM. And, most importantly, you don&amp;rsquo;t have time to spend on endless meetings or delivering documentation that nobody will ever read.&lt;/p&gt;
&lt;p&gt;You do not have time to get border and the skills you gain are real, forged in the heat of necessity.&lt;br&gt;
But the engineering can be illusion. You aren&amp;rsquo;t solving complex problems of scale; you are solving the immediate problem of survival. The solutions are often messy, and riddled with technical debt as you care mostly about fast deliveries. It&amp;rsquo;s less about elegant architecture and more about patching the hull of a sinking ship fast enough to reach the next shore. You learn a great deal and at fast-paced, but you risk becoming a master of the temporary fix.&lt;/p&gt;
&lt;p&gt;Autonomy is essential here. You have a freedom you won&amp;rsquo;t find on the other path. Feedback is instant. Your ideas are heard, and if they create a positive impact, then they become the product.
About failure, a bad decision can kill the company, but and the feedback is instant as well. The lesson is learned by all, some products could be shutdowned almost instantaneously, but more importantly the startup itself will grow up by its mistakes.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-gilded-cage&#34;&gt;
  The gilded cage
  &lt;a class=&#34;anchor&#34; href=&#34;#the-gilded-cage&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;On the other side stands the big company, the tech empire. Here, the problems of survival were solved years or decades ago. The machine is already built, maybe not much innovative, and its engine is running at a good speed.
The goal here is to keep the engine running at the same speed and, if possible, make it 0.05% more efficient (mostly in terms of costs) this quarter.&lt;/p&gt;
&lt;p&gt;The scale is immense, almost abstract. A single change can impact a billion users, so it is treated with the gravity of a moon launch (mostly by people who have great responsabilities in the company but not interested to understand how the engine is actually working).&lt;br&gt;
This creates its own kind of complexity.&lt;br&gt;
The engineering challenge is not anymore &amp;ldquo;Can we build it?&amp;rdquo; but &amp;ldquo;Can we deploy it without breaking anything for anyone?&amp;rdquo;&lt;br&gt;
We can clearly assume that big companies rest on one&amp;rsquo;s laurels.&lt;/p&gt;
&lt;p&gt;This can a comfortable place for an engineer who is not interested to solve new challenges.&lt;br&gt;
The pay is good (most of the time way better than a startup), the process is mostly defined, and you can slowly draft your individual carrier.&lt;/p&gt;
&lt;p&gt;But, in my own opinion, &lt;strong&gt;comfort is the enemy of skill&lt;/strong&gt;.&lt;br&gt;
My philosophy is that a senior engineer is an athlete of the mind. To stay competitive, you must train relentlessly, and practice on solving different problems.
The gilded cage, however, often encourages the senior engineer to become a coach who directs from the sidelines, and without even participate to competitions before.
The problem is, you can&amp;rsquo;t maintain your edge by telling others how to compete if you did not compete before and won medals.&lt;/p&gt;
&lt;p&gt;As I said, an engineer&amp;rsquo;s mind, like a muscle, atrophies without resistance. In the gilded cage, you become a specialist in a &lt;strong&gt;microscopic&lt;/strong&gt; part of a colossal machine. You might spend a several weeks optimizing a single API endpoint or shaving milliseconds off a recommendation algorithm, and several months to produce an accurate documentation for your managers who, actually, do not have the time to read this.&lt;/p&gt;
&lt;p&gt;Autonomy is viewed differently here and, often, it isn&amp;rsquo;t valued. The feature you&amp;rsquo;re building was likely decided by someone else. Someone who understood its financial impact, but not the technical one.
In big companies failure is slow, quiet, and &lt;strong&gt;political&lt;/strong&gt;. A bad project is never killed, but can become a zombie, draining morale for years. In big companies failure is not a lesson for anyone (especially not for your manager), but more a big stain on your performance review.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-workplace-that-matters&#34;&gt;
  The workplace that matters
  &lt;a class=&#34;anchor&#34; href=&#34;#the-workplace-that-matters&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We are taught to see these two paths as a choice: the chaotic and skill-building startup, or the stable and specialized corporation.&lt;br&gt;
We ask ourselves which one is better, which one will finally lead us to the grail.&lt;/p&gt;
&lt;p&gt;But this is the wrong question.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;holy grail&amp;rdquo; of engineering isn&amp;rsquo;t a job description. It is not found in the startup&amp;rsquo;s frantic sprint or the big company&amp;rsquo;s careful optimization. It is not a place you arrive at. It is not when your start the morning or when you leave the office.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It is actually the thing(s) you do, and the thing(s) that make you happy.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is the act of consciously seeking out and imposing structure on chaos, of finding the frontier even within a gilded cage.&lt;/p&gt;
&lt;p&gt;In a startup, it means resisting the urge for the quick fix and asking &amp;ldquo;How can we build this to last, even when we only have a week?&amp;rdquo;.&lt;br&gt;
It means being the one who carves out time to pay down technical debt, who introduces a design pattern that will save everyone from themselves six months from now.&lt;/p&gt;
&lt;p&gt;In a big company, it means fighting the gravitational pull of comfort and most of the time hierarchy.&lt;br&gt;
It means actively seeking out the messy, undefined problems that exist between the well-oiled cogs of the machine.
It means providing engineering value instead of boring documentation and meetings with people who do not even understand what you are speaking of.&lt;br&gt;
It means becoming an archeologist of the company&amp;rsquo;s own complex systems, understanding not just your piece, but how it connects to the whole.&lt;/p&gt;
&lt;p&gt;The mirage is the belief that someone will hand you the interesting problems.&lt;br&gt;
The reality is that interesting problems are almost always the ones no one else wants to solve. They are messy, political, and poorly defined.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The grail is not found, it is made&lt;/strong&gt;.&lt;br&gt;
And it is made by engineers who decide to stop searching for the perfect problem and starts solving the imperfect one right in front of them.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The skill of the future is not &#39;AI&#39;, but &#39;Focus&#39;</title>
      <link>https://carette.xyz/posts/focus_will_be_the_skill_of_the_future/</link>
      <pubDate>Tue, 11 Feb 2025 16:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/focus_will_be_the_skill_of_the_future/</guid>
      <description>&lt;p&gt;If you frequent Hacker News regurlarly, you have likely noticed the buzz around engineers using AI
(specifically Large Language Models, or LLMs) to tackle Computer Science problems.&lt;/p&gt;
&lt;p&gt;I want to be clear: &lt;strong&gt;I&amp;rsquo;m not against LLMs&lt;/strong&gt;.&lt;br&gt;
LLMs are incredibly powerful tools, and &lt;strong&gt;can&lt;/strong&gt; be a huge boon to engineers.
They can automate repetitive tasks, generate code snippets, help with brainstorming, assist in debugging, &amp;hellip;
and this can frees up engineers&amp;rsquo; time and mental energy, which could be channeled into more complex, creative problem-solving.&lt;br&gt;
But, like any tool, LLMs should be used &lt;strong&gt;wisely&lt;/strong&gt;.&lt;br&gt;
LLMs can hallucinate, exhibit inconsistencies (especially with self-reflection models), and harbor biases. These limitations mean that LLM outputs require careful review before they can be trusted.&lt;/p&gt;
&lt;p&gt;A key concern with LLMs lies in their training data.&lt;br&gt;
The data can be biased, contradictory sometimes, but those data contain solutions to known problems.&lt;br&gt;
If an engineer wants to &amp;ldquo;reinvent the wheel,&amp;rdquo; an LLM might offer a solution (good or bad, depending on the prompt). But when faced with truly &lt;em&gt;novel&lt;/em&gt; problems, LLMs often provide unreliable responses, placing the burden of error detection squarely on the engineer.&lt;/p&gt;
&lt;p&gt;This reliance on readily available solutions, particularly for familiar problems, creates a real risk: engineers may inadvertently atrophy their own problem-solving skills, hindering their ability to tackle truly novel challenges.&lt;br&gt;
The solution lies is &lt;strong&gt;balance&lt;/strong&gt;, and a focus on the &amp;ldquo;why&amp;rdquo;, not just the &amp;ldquo;what&amp;rdquo;.&lt;br&gt;
Engineers should strive to understand the &lt;em&gt;reasoning&lt;/em&gt; behind LLM-generated solutions, not simply accept them blindly.  Blind acceptance shifts the focus from &lt;em&gt;solving&lt;/em&gt; problems to merely &lt;em&gt;obtaining&lt;/em&gt; a solution.  Crucially, solving complex problems often depends on mastering simpler and foundational skills, which the engineer might lose quickly.&lt;/p&gt;
&lt;p&gt;This idea summarizes why I disagree with those who equate the LLM revolution to the rise of search engines, like Google in the 90s.
Search enginers offer a good choice between &lt;em&gt;Exploration&lt;/em&gt; (crawl through the list and pages of results) and
&lt;em&gt;Exploitation&lt;/em&gt; (click on the top result).&lt;br&gt;
LLMs, however, do not give this choice, and tend to encourage immediate exploitation instead.
Users may explore if the first solution &lt;strong&gt;does not work&lt;/strong&gt;, but the first
choice is &lt;strong&gt;always&lt;/strong&gt; to exploit.&lt;br&gt;
&lt;em&gt;Exploitation&lt;/em&gt; and &lt;em&gt;exploration&lt;/em&gt; are complementary. Remove the exploration and you will introduce more and more instability into the exploitation process.&lt;/p&gt;
&lt;p&gt;Computer Science emerged because Humans needed &lt;strong&gt;tools&lt;/strong&gt; to solve problems faster and wanted to &lt;strong&gt;focus&lt;/strong&gt; on the real problems, not repetitive tasks.
Humans built machines to accelerate problem-solving, but engineers remained the masters of the algorithms.&lt;br&gt;
I fear we&amp;rsquo;re losing our grip on this mastery.
Not because engineers are becoming less and less intelligent, but because the pressure to deliver solutions quickly is paramount.&lt;br&gt;
In embracing these &amp;ldquo;fast-paced solutions&amp;rdquo;, we risk losing a fundamental skill: &lt;em&gt;focus&lt;/em&gt;. Because focus, like any skill, requires practice.&lt;/p&gt;
&lt;p&gt;This is a worrying trend. If engineers become less adept at solving complex problems, what does the future hold?
Will our ability to tackle complex challenges rest solely on self-reflecting AIs, rather than human ingenuity?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The paradoxical disconnection of Silicon Valley</title>
      <link>https://carette.xyz/posts/the_paradoxical_disconnection_of_silicon_valley/</link>
      <pubDate>Sun, 02 Feb 2025 16:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_paradoxical_disconnection_of_silicon_valley/</guid>
      <description>&lt;p&gt;A few months ago, a video of a private tech conference leaked online. The speaker was Eric Schmidt, discussing tech entrepreneurship, his past experiences, and how to make money today.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/mKVFNg3DEng?si=v_CLbcdgP7Sqjwmq?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;The transcript of the video can be found &lt;a href=&#34;https://github.com/ociubotaru/transcripts/blob/main/Stanford_ECON295%E2%A7%B8CS323_I_2024_I_The_Age_of_AI,_Eric_Schmidt.txt&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Frankly, the conference was painful to watch, not because of technical issues, but because of the terrible advice and ideas Schmidt shared.  This isn&amp;rsquo;t the first time I&amp;rsquo;ve heard such pronouncements from (ex-)CEOs and managers, especially those from Silicon Valley. However, this time, I sensed something amiss, a disconnect from reality among those who manage significant companies and products.&lt;/p&gt;
&lt;p&gt;This feeling has been amplified by the &amp;ldquo;war&amp;rdquo; between US and Chinese tech companies, particularly evident in the OpenAI vs. DeepSeek situation.  This disconnect can be illustrated by five key quotes from Schmidt&amp;rsquo;s conference.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-tiktok-case&#34;&gt;
  The TikTok case
  &lt;a class=&#34;anchor&#34; href=&#34;#the-tiktok-case&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;If TikTok is banned, here&amp;rsquo;s what I propose each and every one of you do.&lt;br&gt;
Say to your LLM the following:
&amp;lsquo;make me a copy of TikTok, steal all the users, steal all the music, put my preferences in it, produce this program in the next 30 seconds, release it and in one hour, if it&amp;rsquo;s not viral, do something different along the same lines.&amp;rsquo;&lt;br&gt;
That&amp;rsquo;s the command.&lt;br&gt;
&lt;strong&gt;Boom, boom, boom, boom.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This boils down to: &amp;ldquo;Rob &lt;strong&gt;fast&lt;/strong&gt;, Sell &lt;strong&gt;faster&lt;/strong&gt;, and Iterate &lt;strong&gt;quickly&lt;/strong&gt;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve heard this kind of rhetoric more frequently in recent years, especially from companies that profess to love open source, yet readily clone and rip off entire GPL or MIT projects without attribution, effectively taking credit for work they haven&amp;rsquo;t done. While this has always been a problem, there&amp;rsquo;s now an open embrace of leveraging open-source information and solutions for profit, especially as developers become less concerned about the licensing rights they grant.&lt;/p&gt;
&lt;p&gt;This quote also exemplifies the &amp;ldquo;move fast and break things&amp;rdquo; mentality, which, in my view, has eroded trust in software. This approach suggests that software is no longer designed for long-term user benefit, but rather for short-term investor gains—a demonstration of what a company could do, until they inevitably break (or abandon) their latest &amp;ldquo;innovation.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This quote encapsulates much of what&amp;rsquo;s wrong with the modern software industry over the past decade.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;steal-stole-stolen&#34;&gt;
  Steal, Stole, Stolen
  &lt;a class=&#34;anchor&#34; href=&#34;#steal-stole-stolen&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Schmidt&amp;rsquo;s next statement sent chills down my spine:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the example that I gave of the TikTok competitor&amp;hellip;&lt;br&gt;
and, by the way, &lt;strong&gt;I was not arguing that you should illegally steal everybody&amp;rsquo;s music&lt;/strong&gt;&amp;hellip;&lt;br&gt;
what you would do if you&amp;rsquo;re a Silicon Valley entrepreneur [&amp;hellip;] is, if [your business] took off, then you&amp;rsquo;d hire a whole bunch of lawyers to go clean the mess up.&lt;br&gt;
But, if nobody uses your product, then it doesn&amp;rsquo;t matter that &lt;strong&gt;you stole&lt;/strong&gt; all the content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To me, this translates to: &lt;strong&gt;hypocrisy&lt;/strong&gt; and &lt;strong&gt;theft&lt;/strong&gt; are core competencies for a Silicon Valley entrepreneur. The bolded phrases highlight this hypocrisy.&lt;/p&gt;
&lt;p&gt;Further evidence of this hypocrisy can be seen in his comments about European regulation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Europe is screwed up because of Brussels.
It&amp;rsquo;s not a new fact.&lt;br&gt;
I spent 10 years fighting them.&lt;br&gt;
And I worked really hard to get them to fix the EU act and they still have all the restrictions that make it very difficult to do our kind of research in Europe.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;yet, later he states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So in my career, &lt;strong&gt;I helped Microsoft get broken up&lt;/strong&gt; and it wasn&amp;rsquo;t broken up.&lt;br&gt;
&lt;strong&gt;And I fought for Google to not be broken up&lt;/strong&gt; and it&amp;rsquo;s not been broken up.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hypocrisy, indeed.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;employaves&#34;&gt;
  &amp;ldquo;Employaves&amp;rdquo;
  &lt;a class=&#34;anchor&#34; href=&#34;#employaves&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Google decided that work life balance and going home early and working from home was more important than winning.
I was in Taiwan, different country, different culture.
And they have a rule that the starting PhDs coming out of the good physicists work in the factory on the basement floor.
Now, can you imagine getting American physicists to do that?
The PhDs, highly unlikely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s true that people generally prefer a life outside of work, a fact that seems to irritate many CEOs these days. This is ironic, considering &lt;a href=&#34;https://fortune.com/2024/08/18/ceo-remote-work-headquarters-starbucks-victorias-secret/&#34;&gt;the increasing number of CEOs demanding a full-time return to the office, even as they themselves work remotely&lt;/a&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t belabor this point, but perhaps Schmidt has forgotten that &lt;a href=&#34;https://fortune.com/2023/10/14/nvidia-skips-return-to-office-sticks-to-remote-work-among-hottest-tech-companies/&#34;&gt;Nvidia, with over 80% of its staff working remotely&lt;/a&gt;, continues to dominate the competition in AI and gaming chips.&lt;/p&gt;
&lt;p&gt;It seems Silicon Valley is less concerned about employees and more interested in &amp;ldquo;employaves&amp;rdquo;—perhaps a fitting term for the current climate.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-hard-truth-about-silicon-valley&#34;&gt;
  The hard truth about Silicon Valley
  &lt;a class=&#34;anchor&#34; href=&#34;#the-hard-truth-about-silicon-valley&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Based on these quotes, the Silicon Valley entrepreneur emerges as a hypocrite, a liar, and a thief.  Someone willing to climb over others to appear a giant.&lt;/p&gt;
&lt;p&gt;The hard truth: these individuals are not giants, and never will be.  They suffer from a false sense of self-importance, much like, perhaps, the US itself?&lt;br&gt;
Let&amp;rsquo;s hear from Schmidt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Countries with a lot of money and a lot of talent, strong educational systems, and a willingness to win.&lt;br&gt;
The US is one of them, and China is another one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bbc.com/worklife/article/20240207-big-tech-layoffs-perks-cuts&#34;&gt;It&amp;rsquo;s no secret that California, particularly Silicon Valley, is losing its grip on tech dominance&lt;/a&gt;.
Silicon Valley&amp;rsquo;s golden age as an innovative hub for hackers is fading.&lt;/p&gt;
&lt;p&gt;The US-China tech war, especially the OpenAI vs. DeepSeek debacle, is farcical.  Humanity won&amp;rsquo;t achieve AGI without collaborative effort, particularly in scientific resources and energy consumption.  Furthermore, I believe we deserve to see evidence of cutting-edge technologies through scientific papers, source code, and open weights, rather than having them locked behind a $200 paywall.&lt;/p&gt;
&lt;p&gt;This secrecy reveals a key point: the US, and Silicon Valley in particular, fear losing their perceived top spot. Especially on the Tech field, and AI as the New Battleground.&lt;/p&gt;
&lt;p&gt;We need more insightful discussions from individuals like Denis Assabis of DeepMind, where interviews resemble science courses rather than the kind of vapid advice I just witnessed.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;ceo-bots&#34;&gt;
  CEO-Bots
  &lt;a class=&#34;anchor&#34; href=&#34;#ceo-bots&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The drive for &amp;lsquo;winning&amp;rsquo; at all costs, as exemplified by Schmidt&amp;rsquo;s remarks, naturally leads to a focus on maximizing efficiency and minimizing costs. In this context, the idea of a &amp;lsquo;CEO-bot&amp;rsquo; becomes less far-fetched&amp;hellip;&lt;/p&gt;
&lt;p&gt;In ML terms, &lt;strong&gt;what could be the cost function of a good CEO-bot?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The cost function for a CEO might be simpler than that of an engineer: maximize profits, monitor engineering performance monthly and adjust accordingly, keep abreast of news and future trends.&lt;/p&gt;
&lt;p&gt;It would be interesting to explore how an AI CEO would perform. Especially as it can fits the dreams of Silicon Valley investors and entrepreneurs: no exhuberant salaray, an intelligence that do not sleep or eat, that do not take the plane each time he needs to sign contracts or go to an expensive garden party&amp;hellip;&lt;br&gt;
Just imagine the significant savings that could be realized with just &lt;strong&gt;one&lt;/strong&gt; salary.&lt;/p&gt;
&lt;p&gt;And, the icing on the cake, no more personality cult and no more bullshit on over-the-top conferences!&lt;/p&gt;
&lt;p&gt;Could be great.&lt;br&gt;
Just saying! ;-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The state of Vulkan apps in 2024</title>
      <link>https://carette.xyz/posts/state_of_vulkan_2024/</link>
      <pubDate>Tue, 28 May 2024 20:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/state_of_vulkan_2024/</guid>
      <description>&lt;p&gt;&lt;strong&gt;UPDATE 2TH OF JUNE 2024&lt;/strong&gt;&lt;br&gt;
Removed typos (thanks Geoffrey! :) )&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;As a game engine developer, I always ask myself the same question working on new features or bug fixes: &amp;ldquo;&lt;strong&gt;What are the targets of my game engine?&lt;/strong&gt;&amp;rdquo;.&lt;br&gt;
Excluding the consoles, this question mostly implies which &lt;strong&gt;operating system&lt;/strong&gt; - or platform - is targeted: Windows,
Linux (or GNU/Linux, but I will keep &amp;ldquo;Linux&amp;rdquo; for the rest of the article), or macOS.&lt;/p&gt;
&lt;p&gt;Developing the same game on multiple platforms could increase the developer&amp;rsquo;s interest to use the &lt;strong&gt;same&lt;/strong&gt;
technology for the different platforms.
This may reduce the development time and be more productive.&lt;/p&gt;
&lt;p&gt;Targeting multiple platforms among Windows, Linux, or macOS, only two mainstream graphics APIs might be useful:
&lt;strong&gt;OpenGL&lt;/strong&gt; and &lt;strong&gt;Vulkan&lt;/strong&gt;.
I exclude WebGPU on purpose here as the API is not stable yet.&lt;br&gt;
OpenGL and Vulkan have their specifications developed by the same company, Khronos.
However Khronos declared in 2017 that &lt;a href=&#34;https://www.khronos.org/news/archives&#34;&gt;OpenGL was no longer in active development, in favor of
the Vulkan API&lt;/a&gt;, whose first stable version was released in 2015.&lt;/p&gt;
&lt;p&gt;So, eight years after its introduction, what is the state of Vulkan today among graphics apps?&lt;br&gt;
Is Vulkan finally a &amp;ldquo;DirectX 12 killer&amp;rdquo;, or is it (unfortunately) a splash in the water?&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-retrospective&#34;&gt;
  A retrospective
  &lt;a class=&#34;anchor&#34; href=&#34;#a-retrospective&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Vulkan has a &lt;a href=&#34;https://www.vulkan.org/made-with-vulkan&#34;&gt;nice community-based list of released apps using its own API&lt;/a&gt;.
The main issue of this list is it is non-exhaustive, as some Vulkan apps may not belong to this list if the game developer(s),
or the community, did not suggested it.&lt;br&gt;
I would like to thanks Khronos to publish this list and allow the community to contribute.
This list made my research easier.&lt;br&gt;
Also, I invite you to suggest &lt;strong&gt;any app&lt;/strong&gt; that uses Vulkan but not listed!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: a Vulkan app is not necessarily a game, but any software that uses the Vulkan API
in its backend (for example: &lt;code&gt;geekbench&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;201 Vulkan apps have been released since 2015 (202 listed apps, but one duplicate one called &amp;ldquo;&lt;code&gt;Golf It&lt;/code&gt;&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Using those data I will draw three different graphs, and three different conclusions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the number of released Vulkan apps since 2015, year by year, compared to DirectX 12,&lt;/li&gt;
&lt;li&gt;the number of released Vulkan apps per platform, and the number of platforms targeted,&lt;/li&gt;
&lt;li&gt;and the number of released Vulkan apps per SDK version.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;released-vulkan-apps-per-release-date&#34;&gt;
  Released Vulkan apps per release date
  &lt;a class=&#34;anchor&#34; href=&#34;#released-vulkan-apps-per-release-date&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;As we can see below, the number of apps using Vulkan is decreasing since 2019, from 35 released apps in 2022 to
9 released apps in 2023.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Number of released Vulkan games per year&#34; src=&#34;https://carette.xyz/images/vk_released_games_per_year.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Based on the Wikipedia page &lt;a href=&#34;https://en.wikipedia.org/wiki/Category:Game_engines_that_support_Vulkan_(API)&#34;&gt;&amp;ldquo;Game Engines that support Vulkan(API)&amp;rdquo;&lt;/a&gt; 11 game engines support Vulkan as a graphics API, most of them from very famous video game companies like &lt;a href=&#34;https://en.wikipedia.org/wiki/Id_Software&#34;&gt;id Software&lt;/a&gt;,
&lt;a href=&#34;https://en.wikipedia.org/wiki/Valve_Corporation&#34;&gt;Valve&lt;/a&gt;, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Epic_Games&#34;&gt;Epic Games&lt;/a&gt;.&lt;br&gt;
In my knowledge only &lt;a href=&#34;https://en.wikipedia.org/wiki/Id_Tech_7&#34;&gt;Id Tech 7 supports Vulkan rendering &lt;strong&gt;only&lt;/strong&gt; for PCs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As a comparison:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.pcgamingwiki.com/wiki/List_of_OpenGL_games&#34;&gt;PCGamingWiki shows more than 1600 games released since 1997 using OpenGL&lt;/a&gt;, &lt;strong&gt;16 in 2023&lt;/strong&gt; despite the fact that no new OpenGL version has been released since 2016, &lt;strong&gt;which is more than with Vulkan for the same year&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.pcgamingwiki.com/wiki/List_of_Direct3D_12_games&#34;&gt;PCGamingWiki shows more than 430 games released on the latest version of DirectX&lt;/a&gt; (DirectX 12 and DirectX 12 Ultimate) since 2015, &lt;strong&gt;88 in 2023&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, &lt;strong&gt;twice&lt;/strong&gt; more &lt;strong&gt;games&lt;/strong&gt; have been released with DirectX 12 than Vulkan in total, despite the fact that DirectX 12 is
exclusive to Windows.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Number of released Vulkan games compared to DX12&#34; src=&#34;https://carette.xyz/images/vk_released_games_per_year_vs_dx12.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;As we can see here, the number of released Vulkan apps, compared to the number of released DirectX 12 apps, was really close
until 2021.
Once DirectX 12 Ultimate as been released in 2020 we can clearly see a winner with DirectX 12.&lt;br&gt;
Multiple factors can be explained here: the introduction of the Xbox Series S|X in 2020 and the fact that DirectX 12 targets
also Xbox One &amp;amp; Xbox Series consoles (Microsoft &lt;strong&gt;does not&lt;/strong&gt; allow any graphics API other than DirectX 12 on Xbox Series, not even
DirectX 11), the fact that most AA and AAA games are released after 3-4 years of development
(and the introduction of DirectX 12 in new engines), or maybe the fact that DirectX 12 is good enough to target
the platform with most users on it: Windows.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;released-vulkan-apps-per-platform&#34;&gt;
  Released Vulkan apps per platform
  &lt;a class=&#34;anchor&#34; href=&#34;#released-vulkan-apps-per-platform&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Based on the previous observation, we can ask ourselves whether the demand for cross-platform applications is high or negligeable,
and what are the main platforms that Vulkan apps developers are targeting.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Number of released Vulkan games per platform&#34; src=&#34;https://carette.xyz/images/vk_released_games_per_platform.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Windows and Linux are clear winners for Vulkan since 2015, with 41.7% of Vulkan apps for Windows, and 30.2% for Linux.
The Android mobile platform is kind of a success compared to iOS, with 16.2% of Vulkan apps.&lt;br&gt;
Unlike Sony and Microsoft consoles, the Nintendo Switch officialy accepts Vulkan as a graphics API for first and third-parties games.&lt;/p&gt;
&lt;p&gt;To finish, the major Vulkan apps targets &lt;strong&gt;only one platform&lt;/strong&gt;, which may be a big disappointment
given Vulkan&amp;rsquo;s promise to be multi-platforms.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Number of released Vulkan games with platform support&#34; src=&#34;https://carette.xyz/images/vk_released_games_with_platforms_support.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;released-vulkan-apps-per-api-version&#34;&gt;
  Released Vulkan apps per API version
  &lt;a class=&#34;anchor&#34; href=&#34;#released-vulkan-apps-per-api-version&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s take a look at which API version developers are using: do they prefer the later APIs or do they stick with
the first versions of Vulkan instead?&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Number of released Vulkan games per Vulkan version&#34; src=&#34;https://carette.xyz/images/vk_released_games_per_vk_version.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;This graph is not easy to interpret as there is a &lt;strong&gt;large&lt;/strong&gt; number of Vulkan apps that does not expose publicly their
API version.&lt;br&gt;
However, &lt;strong&gt;if we exclude the 36.8% of unknown versions&lt;/strong&gt;, we can notice that developers did not
move to a SDK version superior at 1.1 to release their Vulkan apps, &lt;strong&gt;which has been released in 2018&lt;/strong&gt;.&lt;br&gt;
Vulkan 1.2 has been introduced in January 2020, more than four years from now, approximately at the same time as
DirectX 12 Ultimate.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-2023-survey&#34;&gt;
  The 2023 survey
  &lt;a class=&#34;anchor&#34; href=&#34;#the-2023-survey&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;LunarG organizes a Vulkan survey for Vulkan developers, since a few years now.
The survey is free, open for everyone, and LunarG published the 2024 results &lt;a href=&#34;https://www.lunarg.com/wp-content/uploads/2023/04/2023-Ecosystem-Survey-Public-Report-06APR2023.pdf&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Despite the fact that the survey has been largely shared to Vulkan developers (more than 13.000+ recipients
of the LunarG Vulkan SDK mailing list, social networks, Vulkan Slack channel, etc.) only 275 developers answered
the LunarG&amp;rsquo;s 2024 Vulkan survey.
In comparison there were 288 respondents in 2022, and 364 in 2021.&lt;/p&gt;
&lt;p&gt;As stated in the survey the main targets of the recipients are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Windows (11, 10),&lt;/li&gt;
&lt;li&gt;Linux,&lt;/li&gt;
&lt;li&gt;Android.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This reflects our observation that the great majority of released apps is actually for Windows and / or Linux
platforms only.&lt;/p&gt;
&lt;p&gt;Vulkan apps developers do not seem to target macOS (yet?), and state that targeting Android can be an issue as the
driver support is still &amp;ldquo;poor&amp;rdquo;.&lt;br&gt;
However there seems to have more interest in supporting Vulkan on Android than iOS, despite the efforts of a dedicated
Khronos team to port Vulkan on Apple platforms with &lt;a href=&#34;https://moltengl.com/moltenvk/&#34;&gt;MoltenVK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To finish, developers show once again that the complexity of the Vulkan API is still a barrier to adoption,
despite the fact that it is now 8 years old.&lt;br&gt;
This statement can be a surprise as DirectX 12 is criticized too for its complexity compared to DirectX 11, &lt;strong&gt;but&lt;/strong&gt; still
gains traction from the Gaming industry compared to Vulkan.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The terrible situation of Windows (professional) laptops</title>
      <link>https://carette.xyz/posts/the_terrible_situation_of_windows_laptops/</link>
      <pubDate>Sun, 19 May 2024 17:25:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_terrible_situation_of_windows_laptops/</guid>
      <description>&lt;p&gt;Last Saturday, after logging on &lt;del&gt;Twitter&lt;/del&gt; X, I came across two tweets from two great programmers I follow.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;*** Deeply Negative Tweet Alert!!!!!! ***&lt;br&gt;&lt;br&gt;My ASUS Rog Strix G16 super hyper gaming laptop has lasted approximately 1 year before destroying itself.&lt;br&gt;&lt;br&gt;For about a month it has been in a mode where it&amp;#39;s impossible to sleep it (and there is no Hibernate option in Windows any more,…&lt;/p&gt;&amp;mdash; Jonathan Blow (@Jonathan_Blow) &lt;a href=&#34;https://x.com/Jonathan_Blow/status/1791925515281899810?ref_src=twsrc%5Etfw&#34;&gt;May 18, 2024&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I bought a Macbook a third of the price of my expensive Windows 11 Dell, and everything feels smoother and nicer (aside from the fact I&amp;#39;m not really used to the OS, and learning vscode is going to be a thing).&lt;/p&gt;&amp;mdash; Omar 🍋 (@ocornut) &lt;a href=&#34;https://x.com/ocornut/status/1791437076455411888?ref_src=twsrc%5Etfw&#34;&gt;May 17, 2024&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt;: Jonathan Blow and Omar Cornut are two programmers focusing on games and game engines
development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I will use the word &amp;ldquo;professional&amp;rdquo; for laptops with high-end specs and components like CPUs,
GPUs (which includes &amp;ldquo;Gaming&amp;rdquo; laptops), and RAM, and big battery capacity.&lt;/p&gt;
&lt;p&gt;In the first tweet, Jonathan Blow exposes its troubles on its latest professional laptop:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the laptop lasts around one year before dying ✝,&lt;/li&gt;
&lt;li&gt;the laptop suddenly starts from itself in his laptop, got hot, and runs into battery life issue(s),&lt;/li&gt;
&lt;li&gt;the audio does not work well, with terrible lagging and audio skipping,&lt;/li&gt;
&lt;li&gt;CPU / GPU performances become weak at very random times,&lt;/li&gt;
&lt;li&gt;and the SSD is &amp;ldquo;&lt;em&gt;excruciatingly&lt;/em&gt; slow&amp;rdquo; when the laptop is unplugged.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the second tweet, Omar Cornut exposes also the fact that its latest Windows laptop does not follow
the same rate of performance / price compared to an half-priced Apple macintosh.&lt;/p&gt;
&lt;p&gt;Buying a Windows laptop (or just computer hardware in general) there are two different things to differenciate:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the hardware and its manufacturer,&lt;/li&gt;
&lt;li&gt;and the operating system shipped with the laptop, coming from Microsoft.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;and we can rearrange the list of complaints of the first tweet based on this.&lt;/p&gt;
&lt;p&gt;The list of the laptop manufacturer faults:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bad hardware quality (including SSD),&lt;/li&gt;
&lt;li&gt;shitty cooling system,&lt;/li&gt;
&lt;li&gt;not focused on real-usage quality &amp;amp; tests,&lt;/li&gt;
&lt;li&gt;high pricing for shitty hardware.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list of the Microsoft Windows faults:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the hibernate system that does not seems to work for laptops,&lt;/li&gt;
&lt;li&gt;inexplicable performance drops,&lt;/li&gt;
&lt;li&gt;calculating superficial things in background, which explains the wake-up in the laptop.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both seem to fault here, and we can ask ourselves how evolved the professional laptops &amp;ldquo;industry&amp;rdquo; since the last 10 years.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: the title of the next sections can contains spoilers about each evolution.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-greediness-of-the-laptop-manufacturers&#34;&gt;
  The greediness of the laptop manufacturers
  &lt;a class=&#34;anchor&#34; href=&#34;#the-greediness-of-the-laptop-manufacturers&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Today, the based price of a professional laptop is between 1000 and 1200$.&lt;br&gt;
As an example, if you go to the website of the famous DELL manufacturer, you can find some XPS devices with latest
Intel chip in it, at least 16GB of RAM, 512GB of SSD, but no dedicated graphics card.&lt;br&gt;
If you count on a GPU, then you will have to upgrade some specs (like the size of your laptop and, then, the size of
your screen) to have a basic NVIDIA RTX 4050 mobile GPU in a 16&amp;quot; XPS for 2500$.&lt;/p&gt;
&lt;p&gt;4000$ for a laptop is a thing. And for this price you should get the &lt;em&gt;Rolls-Royce&lt;/em&gt; of the modern laptops with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;best hardware quality as possible,&lt;/li&gt;
&lt;li&gt;best customer service as possible,&lt;/li&gt;
&lt;li&gt;and best overall experience as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, in total, we should expect for a device that costs 4x the price of a &amp;ldquo;basic&amp;rdquo; professional laptop
&lt;strong&gt;the best reliability ever&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But how can we compute that reliability?&lt;/p&gt;
&lt;p&gt;As for smartphones, we can count like that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;best overall quality of each component, and its homogeneity,&lt;/li&gt;
&lt;li&gt;if the manufacturer shipped drivers for Windows only or for GNU/Linux also,&lt;/li&gt;
&lt;li&gt;the software support in terms of drivers,&lt;/li&gt;
&lt;li&gt;the battery life.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Among the best selling devices for professional we can count on many different brands.
I will only take care of four different here for my expose, and a recent one called &amp;ldquo;Framework&amp;rdquo;.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;the-quality-of-the-components&#34;&gt;
  The quality of the components
  &lt;a class=&#34;anchor&#34; href=&#34;#the-quality-of-the-components&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Professional laptops contain their own lot of good, bad, and weird components.
The Gaming category contains maybe the most non-sense use of components among the different categories of laptops.&lt;/p&gt;
&lt;p&gt;As an example you can find 4K panels on 14&amp;quot; screens, which consumes a lot of battery and is not very well different
than a 2K panel for this screen size. However the &amp;ldquo;4K screen&amp;rdquo; ad bumps up the price of the hardware.
As a personal opinion, I would prefer a 1080p or 2K OLED panel than a bad calibrated 4K panel&amp;hellip; especially on a 14&amp;quot;
device.&lt;/p&gt;
&lt;p&gt;RGB lighting is another example of &amp;ldquo;flashy&amp;rdquo; laptops that rely mostly on its design.
Except if you want to show off during a Twitch session, I don&amp;rsquo;t think this is what you really want to show working in
a coffee shop on Monday morning&amp;hellip;&lt;/p&gt;
&lt;p&gt;Slim designs are a weird thing for Gaming laptops, as they need to cooldown heavily to avoid throttling.
Slim designs reduce the space needed for components, increase the price of each component too as they have to be
specifically built for a laptop model specifically, and also diminishes the repairability of the laptop.
In a funny way, the most expensive laptops seem to be the slimest devices - so, more you spend money on a device and
less you care about reparaibility&amp;hellip;&lt;/p&gt;
&lt;p&gt;Finally, the most stupid idea are coming from Razer to introduce a high-end expensive mobile GPU with a 140W power with
a low TDP and power supply that &lt;strong&gt;can&amp;rsquo;t&lt;/strong&gt; fully power it&amp;hellip; So, you pay for the high-end mobile GPU and you only obtain
the same power than a chipper GPU card.
Razer is not the only manufacturer to blame here: the same thing happened since years about the CPU, where the cooling system was
not good enough to avoid general throttling, which reduces drastically the performances of your laptop.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/DEEc65x4SMs?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Talking about cooling systems, innovations about cooling systems stopped since years now, and manufacturers usually
install a larger fan and a more agressive &amp;ldquo;Extreme Performance&amp;rdquo; software profile (only available when plugged).&lt;/p&gt;
&lt;p&gt;And, finally, the CPU.
CPUs had a really low increase in terms of performance on Windows laptops but are, at least, as expensive as
previous generations of CPUs.
They consume more and more energy to try to performance better than the previous generation but sometimes fail because
of bad thermal performances and throttling.
You can check the prices of new high-end laptop CPUs &lt;a href=&#34;https://www.cpubenchmark.net/laptop.html&#34;&gt;here&lt;/a&gt;, which are mostly
in the same range of prices than a general business laptop.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;os-support&#34;&gt;
  OS support
  &lt;a class=&#34;anchor&#34; href=&#34;#os-support&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Windows 10 has been introduced in 2015, and its end is scheduled for 2025.
A majority of Windows 10 laptops, introduced in 2015, where &lt;strong&gt;not&lt;/strong&gt; suitable to move to Windows 11, so most of those
will just die once the EOL of Windows 10 will be claimed.&lt;/p&gt;
&lt;p&gt;Windows 12 specs will tell us if Microsoft is forcing people to buy new hardware, or if Windows 11 was only a
&amp;ldquo;step for security&amp;rdquo; as they claim.&lt;/p&gt;
&lt;p&gt;Except DELL no one supports GNU/Linux for hardware drivers, and DELL only does this for its XPS brand, no other.&lt;/p&gt;
&lt;p&gt;Another thing is the number of bloatwares shipped with a laptop today, and the number of background services that
are running to ask you to register somewhere for whatever reason&amp;hellip;
Those applications are really annoying and come with plenty of default softwares from Windows 10/11 that slow down
the overall performances of your computer.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;drivers-support&#34;&gt;
  Drivers support
  &lt;a class=&#34;anchor&#34; href=&#34;#drivers-support&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;About laptop lifespan per brand, it is very difficult to have reliable information from those manufacturers.
Despite searches I only found that Microsoft released &lt;a href=&#34;https://learn.microsoft.com/en-us/surface/surface-driver-firmware-lifecycle-support&#34;&gt;on official statement&lt;/a&gt; about 4 to 6 years of software support,
at least, depending of your Surface device.&lt;/p&gt;
&lt;p&gt;However, 2 years ago, a Medium user called &amp;ldquo;Greencodetech&amp;rdquo; has done its own searches on the subject and published a
paper about it &lt;a href=&#34;https://medium.com/@greencodetech810/average-laptop-lifespan-by-brand-128c11394dd3&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Its own searches led him to this top 5 (according to hardware models):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lenovo, with 5 to 7 years of drivers support,&lt;/li&gt;
&lt;li&gt;DELL, with 5 to 6 years of drivers support,&lt;/li&gt;
&lt;li&gt;HP, with 5 to 6 years of drivers support,&lt;/li&gt;
&lt;li&gt;Microsoft, with 4 to 6 years of drivers support,&lt;/li&gt;
&lt;li&gt;Acer, with 3 to 4 years of drivers support.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;the-battery-life&#34;&gt;
  The battery life
  &lt;a class=&#34;anchor&#34; href=&#34;#the-battery-life&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;A laptop without battery life is just as useful as a car without wheels: a theoritical portability.&lt;/p&gt;
&lt;p&gt;Most professional laptops support a &amp;ldquo;good&amp;rdquo; battery component, drained very quickly by the energy-consuming components
that compose the laptop.&lt;br&gt;
To avoid your battery life to end in less than 2h, Microsoft and laptop manufacturers imagine different profiles to
help components to consume less energy while reducing their performances.
So, as a result, your computer will lasts 4h but the compilation time will lasts 2x more than plugged&amp;hellip;&lt;/p&gt;
&lt;p&gt;Another fact is some components will be &lt;strong&gt;disabled&lt;/strong&gt; on purpose to avoid waste of energy&amp;hellip; so, as the manufacturer did
not increased the capacity of your battery life (or just did not invested on improving the situation here) you will
have a decent battery life but with weaker performances and disabled hardware parts.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;in-overall&#34;&gt;
  In overall&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#in-overall&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Professional laptops are as expensive as previous generations, but they are, at best, as &amp;ldquo;ok&amp;rdquo; as the previous generations,
if not weaker.&lt;/p&gt;
&lt;p&gt;The OS and drivers support is in average 5 years &lt;strong&gt;but&lt;/strong&gt;, if I am being honest here, I never found a person with a
5-years professional laptop in its hands since a while, mostly because the device died by itself, or some components
stopped working well, or just the need to upgrade to better specs, which is not what you can do easily on modern
professional laptops.&lt;/p&gt;
&lt;p&gt;The fact that certain brands like Razer, DELL, or Microsoft let you buy very expensive laptops with expensive components
on it that you can&amp;rsquo;t use at full speed and / or at full power is another fact that end-users are not respected.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;a-possible-future--the-framework-laptop&#34;&gt;
  A possible future : the Framework laptop
  &lt;a class=&#34;anchor&#34; href=&#34;#a-possible-future--the-framework-laptop&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;One &lt;strong&gt;possible&lt;/strong&gt; alternative is called &lt;a href=&#34;https://frame.work&#34;&gt;Framework&lt;/a&gt;, which focuses very heavily on scalable and modular
configurations, and long-lasting hardware.&lt;br&gt;
Unfortunately there is still no reliable data to know how really lasts a Framework laptop, and how reliable those modular
configurations perform.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-unreliable-state-of-microsoft-windows&#34;&gt;
  The unreliable state of Microsoft Windows
  &lt;a class=&#34;anchor&#34; href=&#34;#the-unreliable-state-of-microsoft-windows&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;How can we explain that our laptops have more powerful components than 10-15 years ago but software still feels &amp;ldquo;laggy&amp;rdquo;?&lt;br&gt;
A simple hypothesis is our computing devices are actually busy to execute shit instead of focusing only
on user&amp;rsquo;s demands.&lt;/p&gt;
&lt;p&gt;It is not a surprise that each new version of Windows from Microsoft is a fiasco.&lt;br&gt;
However, the new mainstream thing - since Windows 10 actually - is that each new update of Windows
introduces again &lt;a href=&#34;https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-23h2&#34;&gt;more bugs&lt;/a&gt;
(and more ways to lose your data), less useful features, more ads, and less performance!&lt;/p&gt;
&lt;p&gt;As an example, in 2022, Tom&amp;rsquo;s Hardware performed &lt;a href=&#34;https://www.tomshardware.fr/windows-10-vs-windows-11-quelles-performances-pour-un-pc-classique&#34;&gt;a benchmark&lt;/a&gt; on running the exact same software on a classical machine running
two different versions of Windows (10 and 11).
Tom&amp;rsquo;s Hardware found out that each software was running between 6% and 10% &lt;strong&gt;slower&lt;/strong&gt; on Windows 11 than Windows 10.&lt;/p&gt;
&lt;p&gt;The Microsoft marketing team does seem aware of this issue as they stated, releasing Windows 11:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Both operating systems have similar security features, update processes, and compatibility with hardware and software.
However, &lt;strong&gt;Windows 11 offers improved performance and features compared to Windows 10&lt;/strong&gt;, making it a better choice for those looking for a more modern and efficient operating system.
To get this statement, please follow &lt;a href=&#34;https://techcommunity.microsoft.com/t5/windows-11/windows-11-vs-windows-10-a-comprehensive-comparison-of-features/m-p/3760255&#34;&gt;this official Microsoft webpage&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also, Microsoft did not even tried to fix one of the most noticed bug on a laptop for Windows 10 and Windows 11:
&amp;ldquo;modern standby&amp;rdquo;, which leads to a Windows laptop that wakes up suddenly in your backpack.
This is the issue Jonathan Blow stated in its tweet.&lt;br&gt;
This issue has been raised by everyone, including all modern streamers and YouTubers, like Linus Tech Tips in the following
video.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/OHKKcd3sx2c?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Microsoft acknowledged the issue, and released several fixes that do not seem to work for everyone,
as this bug is regularly reported again on some official and unofficial Windows forums.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;is-there-an-os-alternative-for-gamedevs-&#34;&gt;
  Is there an OS alternative for gamedevs ?
  &lt;a class=&#34;anchor&#34; href=&#34;#is-there-an-os-alternative-for-gamedevs-&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;As I said earlier the two tweets authors are working in game and game engine development, and I understand why both
authors are targeting Windows as a default / main platform for their work, despite the weird state of this OS today and
the macOS and GNU/Linux alternatives today.&lt;br&gt;
First, as a game developer you may want to target the largest community of gamers as possible, and this community is 95% on&amp;hellip; Windows.&lt;br&gt;
Then, as a game developer you may want to target also the console gamers, on Xbox, PS5 and Nintendo Switch.
The main issue is that all tools from those console manufacturers, including the SDK, are exclusively built for&amp;hellip; Windows.&lt;/p&gt;
&lt;p&gt;Unfortunately, to target the main audience in gaming (industry / market), &lt;strong&gt;there is no big room for GNU/Linux or macOS&lt;/strong&gt;.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/llK5tk0jiN8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;!--

## The main question

Let&#39;s step back for a minute, and ask ourselves some questions.

*Since at most 10 years, did the battery life of our powerful professional Windows machines have been improved?*  
Definitely no.  
If you have your computer unplugged you will likely limit your battery settings to &#34;NORMAL&#34; or &#34;LOW ENERGY&#34;, which 
will drastically reduces the performances of your machine, otherwise the computer will not lasts more than 2h most of the time.

*Since at most 10 years, did the performances of our powerful professional Windows machines have been improved?*  
Yes! But the ratio Price / Performance is even more disturbing than before...

*Since at most 10 years, did the laptop hardware improved (better screen panel, incredible keyboard and glassy high-precision touchpads)?*  
It depends of the manufacturer, and the price you had to put on the device.  

So, based on all those information, **what is the purpose of a powerful Windows laptop nowadays?**  
And **do Microsoft Windows and laptop manufacturers care about professionals who want performance and mobility?**

--&gt;
</description>
    </item>
    
    <item>
      <title>We are doomed</title>
      <link>https://carette.xyz/posts/we_are_doomed/</link>
      <pubDate>Sun, 14 Jan 2024 20:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/we_are_doomed/</guid>
      <description>&lt;p&gt;I wanted to write about modern graphics APIs at first, how exclusive they are depending of the platform you are
developing on (and for), and how difficult to use they are.
However, after (over-)thinking about this blog post, I came to the conclusion that this problem could
be generalized to all software.&lt;/p&gt;
&lt;p&gt;This is a &lt;strong&gt;very&lt;/strong&gt; pessimistic view of some people call &amp;ldquo;modern software engineering&amp;rdquo;, observed by a 10 years professinal
experience engineer and 20 years programmer.&lt;/p&gt;
&lt;p&gt;Take it with one (or two) grain(s) of salt.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;once-upon-a-time-a-developer-and-a-graphics-renderer&#34;&gt;
  Once upon a time, a developer and a graphics renderer&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#once-upon-a-time-a-developer-and-a-graphics-renderer&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Three years ago I began to work on my custom graphics renderer.
&amp;ldquo;Just for fun&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;At that time I was working on macOS (an Apple Silicon hardware) so, naturally, I had four different graphics API available for my needs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;OpenGL: &lt;a href=&#34;https://venturebeat.com/games/apple-defends-end-of-opengl-as-mac-game-developers-threaten-to-leave/&#34;&gt;deprecated in 2018&lt;/a&gt; by Apple for their platforms,&lt;/li&gt;
&lt;li&gt;Vulkan: not supported natively by Apple, but Khronos is maintaining Vulkan for macOS through
&lt;a href=&#34;https://github.com/KhronosGroup/MoltenVK&#34;&gt;MoltenVK&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Metal: the official &lt;strong&gt;and exclusive&lt;/strong&gt; graphics API from Apple for their platforms,&lt;/li&gt;
&lt;li&gt;My own software renderer: &amp;hellip; naah&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I felt a bit lost there.&lt;br&gt;
I would go for OpenGL &lt;strong&gt;if&lt;/strong&gt; Apple did not deprecated the API (version 4.1, &lt;em&gt;circa&lt;/em&gt; 2010):
simple to use, simple to understand, a great community if you have questions &lt;strong&gt;and&lt;/strong&gt; a very good compatibility with
existing hardware and other operating systems.&lt;br&gt;
Ok, so Metal? The main drawback of Metal is that it is &lt;strong&gt;only&lt;/strong&gt; for Apple platforms, nothing else. I don&amp;rsquo;t know what
tomorrow will be made of, and I have absolutely no guarantee that Apple will not lockdown again their APIs / hardware /
platforms and make my project completely useless in a few years&amp;hellip; no go then!&lt;br&gt;
Ok, so Vulkan? As I said Khronos is maintaining a version of Vulkan for macOS using MoltenVK, a translation layer
to Metal. I liked the idea &lt;strong&gt;but&lt;/strong&gt; Metal is missing a lot of features compared to other hardware like AMD or Nvidia
hardware, and MoltenVK is like two years behind schedule compared to other platforms versions&amp;hellip; hugh&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At that moment I had the strange feeling that I was not choosing for the best graphics API, but the least worst of them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;But how is the state of the graphics APIs on Windows by the way?&lt;/strong&gt;&lt;br&gt;
Fortunately OpenGL still exists (actually it is more a living-dead API), version &lt;strong&gt;4.6&lt;/strong&gt;,
depending of your hardware (but AMD / Nvidia did the updated for OpenGL 4.6 so your hardware should
probably support it), and Windows has a great compatibility history to support old software and old DirectX versions.
But DirectX is &lt;strong&gt;only&lt;/strong&gt; available on Win32 platforms like Metal is for Apple ones.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ok, so we have four (4) different graphics APIs available, only two (&lt;em&gt;kinda-&lt;/em&gt;)multiplatforms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenGL, version 4.1 on macOS and 4.6 on the others (&lt;em&gt;kinda&lt;/em&gt;), but Khronos moved forward and is not interested on
maintaining OpenGL anymore&amp;hellip;&lt;/li&gt;
&lt;li&gt;and Vulkan.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Spoiler: I choosed Vulkan.&lt;br&gt;
The gap between OpenGL and Vulkan is abysmal, and I did realized that Vulkan was a sort a &amp;ldquo;bastard library&amp;rdquo;: made
for engine and graphics developers but its API is &lt;em&gt;so wild&lt;/em&gt; that it looks designed for device driver developers.
The documentation is unclear, the examples are quite complicated to understand and to adapt, and it seems that
&amp;ldquo;extensions&amp;rdquo; principle can be used for very specific hardware versions, which is not what we want as a &amp;ldquo;product developer&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Developing features took time, and I had hard times developing them using Vulkan, but I continue to work on this project&amp;hellip; until a few weeks ago.
I was sitting in front of my computer, on a performance issue &lt;strong&gt;on Windows&lt;/strong&gt; until I realized the same code, on both
Windows and macOS APIs, perform very differently.
The Windows version was 30% slower than before, but the code performed better on macOS&amp;hellip; I stopped there.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;dedication-to-complexity&#34;&gt;
  Dedication to complexity
  &lt;a class=&#34;anchor&#34; href=&#34;#dedication-to-complexity&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Looking back at when I first started programming when I was a kid (2002, on a old Compac PC running Debian)
the things were pretty simple : just find a good documentation (at that time we shared some
very good technical books with friends instead of googling everything like today), the distribution was
shipped with a C compiler and a text editor, the base standard library, and a very few APIs to make graphics.
If you want to exploit your dedicated hardware then you could use OpenGL (or other APIs) but most of the time you
exploited your entire CPU to render something on screen&amp;hellip; &lt;strong&gt;and it was very simple&lt;/strong&gt;!&lt;br&gt;
Also, we were running computers with 256MB of RAM, a single core CPU (less than 2GHz if I remember correctly) and
software at this time were running blazingly fast! Tools, games, &amp;hellip; everything was running ok.&lt;/p&gt;
&lt;p&gt;I have the feeling that software became (and still continue) very complicated and &lt;strong&gt;very&lt;/strong&gt; expensive in terms of resources
because of poor libraries and poor APIs, bloated operating systems, used by strong hardware but running poorly due to
all of this.
Engineers tend to over-think an API through the piece of hardware that has to be exploited by the end developer.&lt;br&gt;
This is very true for GPU hardware manufacturer, where one dedicated piece of hardware has a non-standardized API to
exploit it, which is not compatible with another manufacturer, and this is true also for console manufacturers like Sony,
Nintendo or Microsoft.
But this is true also for system software providers like Microsoft or Apple, through their own operating system and
tools.&lt;/p&gt;
&lt;p&gt;Complexity impacts everything now, from the programming language to the operating system, passing through the API you
are using to exploit your dedicated hardware, the &amp;ldquo;stack&amp;rdquo; you are developing your piece of code on, or the compiler
you are using.
We have very fast computers today which don&amp;rsquo;t seem fast at all as soon as you try to compile a simple project with
more than 20 C++ code files in it, mainly because the CPU is busy to run extra code and software running on your computer?&lt;br&gt;
A simple example: It takes 13 seconds to my new Windows computer to compile my 20+ C++ files project, or 780 frames
if you are developing a game at 60Hz refresh rate.&lt;br&gt;
Maybe because of Microsoft Defender, keeping an eye on newly created file in case of malware?
Another process that analyzes the content of your computer every second, or another process that limits your hardware
depending of your environment&amp;hellip;? Who knows! 🤷&lt;/p&gt;
&lt;p&gt;I wonder how much time the C++ compiler I had in 2002 would takes to compile a project with 20+ C++ files&amp;hellip;
13 seconds too maybe? :)&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;bloat-is-everywhere-and-nobody-seems-concerned&#34;&gt;
  Bloat is everywhere&amp;hellip; and nobody seems concerned
  &lt;a class=&#34;anchor&#34; href=&#34;#bloat-is-everywhere-and-nobody-seems-concerned&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The goal of a software engineer (or developer) is to solve real problems using a computer.
I am very pissed when I see software &amp;ldquo;engineers&amp;rdquo; more concerned about a vim configuration than thinking
why their shell profile takes three to four full seconds to load.&lt;/p&gt;
&lt;p&gt;As end users we have no choice to use what developers deliver.
But, as software engineers, we have no choice either to use what software and hardware providers deliver too, and the
quality of the tools or libraries is becoming weaker and weaker year by year, version by version&amp;hellip;&lt;/p&gt;
&lt;p&gt;Developers today are definitely not productive than before, mainly because they have to deal with a mountain of
libraries, APIs and abstraction, which increase the level of complexity of developing and releasing a &lt;strong&gt;good&lt;/strong&gt; software
for the end users, and distract them.&lt;/p&gt;
&lt;p&gt;But do we have a choice here?&lt;br&gt;
Imagine that you are (like me) porting games and game engines to consoles : you will have to deal, again, with new tools,
new APIs, new abstractions, to build games &lt;strong&gt;exclusively&lt;/strong&gt; using&amp;hellip; Windows.&lt;br&gt;
No tools to develop GNU/Linux (there was a time
&lt;a href=&#34;https://ps2linux.no-ip.info/playstation2-linux.com/coding-on-playstation2.html&#34;&gt;SCE released tools for Linux to develop on PlayStation 2&lt;/a&gt;
but this time is now  revoked), no tools for macOS, &amp;hellip; just Windows.
So, you are &lt;strong&gt;forced&lt;/strong&gt; (not encouraged, but forced) to use this operating system and tools (like Visual Studio), and to deal with its complexity,
to release a product on another platform.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t blame the software developers here.
They have to live, and they mostly operate by people only interested in retention rates and how much end users spent on
their tools and platforms.&lt;br&gt;
Also, mostly do not care about performance and optimization anymore as their own computers have enough of RAM to handle
the app itself, and do not even know how their own software is being executed&amp;hellip; This is very sad to me.&lt;/p&gt;
&lt;p&gt;As an example, I am still amazed the difference of time PhotoShop is taken now to open a simple image, compared to 10 years ago
for the same picture: much less time, much less RAM, and much (&lt;em&gt;much much much much&lt;/em&gt;) less HTTP calls too.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/ZSRHeXYDLko?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;h2 class=&#34;heading&#34; id=&#34;the-container-joker-card&#34;&gt;
  The &amp;ldquo;container&amp;rdquo; joker card
  &lt;a class=&#34;anchor&#34; href=&#34;#the-container-joker-card&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When I discuss about OSs behaviours I hear more and more oftenly this very unique sentence&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OS does not matter anymore as we use containers now&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, based on the &lt;em&gt;fact&lt;/em&gt; I could run, deploy and &amp;ldquo;save&amp;rdquo; my software in a container for 10 years, does it means I could develop
and run a game engine on a container and deploy the image everywhere &lt;strong&gt;without&lt;/strong&gt; platform incompatibility?&lt;br&gt;
If yes&amp;hellip; did you hear about the Docker incompatibility when Apple Silicon chips have been released&amp;hellip;? :)
Or maybe another platform incompatibility?&lt;/p&gt;
&lt;p&gt;As Docker mentions in their documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every Engine release strives to be backward compatible with its predecessors, and interface stability is always a priority at Docker.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;followed by&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In all cases, feature removal is communicated three releases in advance and documented as part of the deprecated features page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This implies that, if you find an old image you want to use, you must definitely use the version of the engine that
was used originally to develop and build the image &lt;strong&gt;if&lt;/strong&gt; your system still supports it.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;only&lt;/strong&gt; system with a good software compatibility that I know is Windows, and this explains a ton of things keeping
very old UI/UX frameworks, software and APIs to run, for example, Windows 95 compatible games like
&amp;ldquo;Roller Coaster Tycoon&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Otherwise, &lt;strong&gt;you are doomed&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;we_are_doomed_conclusion.jpg&#34; src=&#34;https://carette.xyz/images/we_are_doomed_conclusion.jpg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Generated using &lt;a href=&#34;https://memegenerator.net&#34;&gt;memegenerator&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Gaming on mac in 2023</title>
      <link>https://carette.xyz/posts/crossover_mac_retro_games/</link>
      <pubDate>Tue, 26 Dec 2023 12:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/crossover_mac_retro_games/</guid>
      <description>&lt;p&gt;If you know me since a while you know my love for the macintosh and the Apple Silicon chips.
Actually my main daily driver is an Macbook Air M2 and I have a Steam Deck next to me which I bought to play Windows games in an handheld format.
But, sometimes, I just want to play &amp;ldquo;old&amp;rdquo; games on the mac device, which may not be compatible with macOS x86/64, so no Rosetta 2 translation available&amp;hellip;&lt;/p&gt;
&lt;p&gt;In a &lt;a href=&#34;https://carette.xyz/posts/mac_source_ports&#34;&gt;post last year&lt;/a&gt; I wrote about &lt;strong&gt;mac source ports&lt;/strong&gt;, an excellent website that lists all games and game engines ports from Windows to macOS.
This time, as I have little free time, I tried out the new version of &lt;a href=&#34;https://www.codeweavers.com/crossover&#34;&gt;crossover&lt;/a&gt;, that I bought in a Black Friday discount (thanks &lt;a href=&#34;https://www.youtube.com/@Andytizer&#34;&gt;Andrew Tsai&lt;/a&gt;!) after checking sales on GOG and looking for a good game to play on.&lt;br&gt;
After a few searches I found out that one of my favorite games on Xbox 360, &lt;a href=&#34;https://en.wikipedia.org/wiki/Stranglehold_(video_game)&#34;&gt;&lt;strong&gt;Stranglehold&lt;/strong&gt;&lt;/a&gt;, was on sale at 2 euros!
I haven&amp;rsquo;t played this game for years and I was wondering how this game would run on CrossOver&amp;hellip; so I bought it, reinstalled CrossOver on my mac and tried out to create a bottle from scratch to play this game on my Macbook Air.&lt;/p&gt;
&lt;p&gt;First I did a quick search in the CrossOver database and I found out that the game has been rated 4/5 by some users, nice!&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;CrossOver page of Stranglehold&#34; src=&#34;https://carette.xyz/images/stranglehold_gog_3.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Unfortunately the bottle is using the Steam app as a backend, and I don&amp;rsquo;t want to have a static Steam application for each of my games.
Also I just bought the game on GOG so&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, first, I created a new bottle called &amp;ldquo;Stranglehold&amp;rdquo;, and I downloaded the files from GOG in a dedicated folder.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;GOG page of Stranglehold&#34; src=&#34;https://carette.xyz/images/stranglehold_gog_1.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Finder view of Stranglehold folder&#34; src=&#34;https://carette.xyz/images/stranglehold_gog_2.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The files are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one binary, that contains an installer for GOG Galaxy, and look for the files,&lt;/li&gt;
&lt;li&gt;and the .bin files that are basically disk images containing the install data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt;
_
If you want to look at all the data files you can download &lt;a href=&#34;https://constexpr.org/innoextract/#download&#34;&gt;&lt;code&gt;innoextract&lt;/code&gt;&lt;/a&gt; and just run &lt;code&gt;innoextract -l &amp;lt;GAME.EXE&amp;gt;&lt;/code&gt;.
An alternate tool is &lt;a href=&#34;https://www.macsourceports.com/utility/extractor&#34;&gt;&lt;code&gt;Extractor&lt;/code&gt;&lt;/a&gt; but it is only available for macOS.
_&lt;/p&gt;
&lt;p&gt;Just link the executable in the folder to the bottle, and the installation process will be executed automatically, &lt;strong&gt;very nice&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;CrossOver exposes a lot of configuration settings for a bottle, and you might be interested by some of them depending of the game your are running on.
Basically D3DMetal supports translation to DX12 and DX11 (kinda).
DXVK, in the other hand, can somewhat support DirectX versions between DX9 and DX11 (included).&lt;br&gt;
Stranglehold was developed using Unreal Engine 3, using DirectX 9.0, so using DXVK can be a good option to have better performances.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Stranglehold bottle view&#34; src=&#34;https://carette.xyz/images/stranglehold_gog_4.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;If you want to display some additional informations about how well the game is running, you can go to the game&amp;rsquo;s C drive, find the &lt;code&gt;cxbottle.conf&lt;/code&gt; file at the root of the bottle and add the following line to it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DXVK_HUD&amp;#34;&lt;/span&gt; = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fps,frametimes,gpuload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Stranglehold bottle view&#34; src=&#34;https://carette.xyz/images/stranglehold_gog_6.png&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;At the end I could enjoy Stranglehold on my mac, running without any issue!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2023, in a nutshell</title>
      <link>https://carette.xyz/posts/2023_in_a_nutshell/</link>
      <pubDate>Mon, 25 Dec 2023 12:16:16 +0100</pubDate>
      <guid>https://carette.xyz/posts/2023_in_a_nutshell/</guid>
      <description>&lt;p&gt;In my last year&amp;rsquo;s blog post I wrote&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2022 was a strange year for everyone I think.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I do think, as game developers (or just computer developers), we can agree that 2023 was way worst than 2022,
maybe one of the worst year since a long time actually.&lt;br&gt;
Despite records sales in the video game industry, and record earnings, the number of layoffs in the field &lt;a href=&#34;https://www.gamesindustry.biz/over-6000-games-industry-jobs-lost-in-2023-so-far&#34;&gt;was incredibly high&lt;/a&gt;
(more than 6000 jobs lost in 2023 only so far, recorded from January to November 2023).
Also, E3 communicated a few weeks ago they are definitely closing their doors, sounding the death knell of an era of
physical celebration for the video game industry.&lt;br&gt;
I am very sad for all developers who lost their jobs this year, and I sincerely hope that the industry will recover
quickly from this.&lt;/p&gt;
&lt;p&gt;Professionnally I ported two video games for 5 platforms each, one game engine (and another half for 2024), and I
helped porting two game engines to fix bugs in upcoming and released games.
Not so bad!
The main challenge of this year was porting &lt;em&gt;&lt;strong&gt;SHINORUBI&lt;/strong&gt;&lt;/em&gt; and its game engine called &lt;a href=&#34;https://v3x.net&#34;&gt;&lt;code&gt;V3X&lt;/code&gt;&lt;/a&gt;,
developed by &lt;a href=&#34;https://www.realtech-vr.com/home/&#34;&gt;&lt;code&gt;RealtechVR&lt;/code&gt;&lt;/a&gt; for five different platforms: PS4, PS5, Nintendo Switch,
Xbox One and Xbox Series consoles.
The work for &lt;em&gt;SHINORUBI&lt;/em&gt; began in September 2022, ended in late-November 2023, and the release is planned for January 2024.
Apart from that I helped to make fixes for existing game engines but the games have not been annunced yet by RedArtGames
so I can&amp;rsquo;t tell anything the games and game engines (yet).&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Shinorubi is almost here!&lt;br&gt;&lt;br&gt;The hellacious Danmaku style shmup from &lt;a href=&#34;https://x.com/LastBoss88?ref_src=twsrc%5Etfw&#34;&gt;@LastBoss88&lt;/a&gt; is coming digitally to Nintendo Switch, PlayStation and Xbox consoles on January 12, 2024!&lt;br&gt;&lt;br&gt;The limited Switch, PS5 &amp;amp; PS4 physical editions can still be pre-ordered from &lt;a href=&#34;https://t.co/rbcxlKLx2i&#34;&gt;https://t.co/rbcxlKLx2i&lt;/a&gt; &lt;a href=&#34;https://t.co/XyvBqgHHeC&#34;&gt;pic.twitter.com/XyvBqgHHeC&lt;/a&gt;&lt;/p&gt;&amp;mdash; Red Art Games (@RedArtGames) &lt;a href=&#34;https://x.com/RedArtGames/status/1730620502647930934?ref_src=twsrc%5Etfw&#34;&gt;December 1, 2023&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;I continued my own game engine in my spare time, but more and more I tend refocusing the game engine to a
renderer-only project, with a &lt;code&gt;Vulkan&lt;/code&gt; and &lt;code&gt;Metal&lt;/code&gt; backends.&lt;br&gt;
Also, I just finished the 2023 edition of &lt;strong&gt;advent of code&lt;/strong&gt;, an annual program (in December) of small programming puzzles
to solve &amp;ldquo;for fun&amp;rdquo;.
As always I did not participate to the competition, mainly because I had to get up at 6AM to get a chance to participate
(too early for me), but also because I wanted to do AoC for fun and without any stress.
Except the Day 24 Part 2 I did everything the release day, using &lt;code&gt;Swift&lt;/code&gt;.
This year I put on my list &lt;code&gt;Rust&lt;/code&gt;, &lt;code&gt;C++&lt;/code&gt; or &lt;code&gt;Swift&lt;/code&gt;, and asked to a friend to choose a number between 1 and 3 (included) - he
choosed &lt;code&gt;3&lt;/code&gt;&amp;hellip; so &lt;code&gt;Swift&lt;/code&gt; :)&lt;br&gt;
My AoC repository is available &lt;a href=&#34;https://github.com/k0pernicus/aoc2023&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I did not changed my computing environment: a &lt;strong&gt;M2 macbook air&lt;/strong&gt; only, which I use for everything except gaming.
This machine is pretty incredible: great power &amp;amp; excellent battery life, perfect combo!&lt;/p&gt;
&lt;p&gt;I played a very high number of good games this year:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Psychonauts 2&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HiFi-Rush&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Battlefield 4&lt;/strong&gt; (yes, I know, this one is old&amp;hellip;),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alan Wake 2&lt;/strong&gt; (my GOTY),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quake 2 Remastered&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assassin&amp;rsquo;s Creed: Mirage&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I do not expect anything from 2024 except stablization in the game &amp;amp; software development industry: let&amp;rsquo;s keep it simple.&lt;/p&gt;
&lt;p&gt;Time for me to close the lid, wish you the best for 2024!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The tunnel effect</title>
      <link>https://carette.xyz/posts/the_tunnel_effect_demoscene/</link>
      <pubDate>Mon, 28 Aug 2023 22:45:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_tunnel_effect_demoscene/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;the-demoscene&#34;&gt;
  The demoscene
  &lt;a class=&#34;anchor&#34; href=&#34;#the-demoscene&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The tunnel effect is a pretty old-school effect in graphics programming, coming directly from the demoscene.
If you take a look at &lt;a href=&#34;https://www.pouet.net&#34;&gt;pouet.net&lt;/a&gt; you may find many (many many) examples of a Tunnel effect
for different hardware configurations, like &lt;a href=&#34;https://www.pouet.net/prod.php?which=78044&#34;&gt;this one&lt;/a&gt; using 3D raycasting.&lt;/p&gt;
&lt;p&gt;In this collection of web demo effects you can find and experiment with this effect:
&lt;a href=&#34;https://seancode.com/demofx/&#34;&gt;https://seancode.com/demofx/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In one of the most well-known demos ever, &lt;a href=&#34;https://www.pouet.net/prod.php?which=63&#34;&gt;&amp;ldquo;Second Reality&amp;rdquo; from Future Crew&lt;/a&gt;,
the team presented a very nice Tunnel effect in&amp;hellip; &lt;strong&gt;1993&lt;/strong&gt;, &lt;em&gt;&lt;strong&gt;years&lt;/strong&gt;&lt;/em&gt; before any graphics card in a personal computer.
You can take a look at this effect, running on the CPU, &lt;a href=&#34;https://youtu.be/8G_aUxbbqWU?si=hRY4tsqnsgZA2Z4p&amp;amp;t=143&#34;&gt;on YouTube&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/8G_aUxbbqWU?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;The key word for running this on any PC at this time was &amp;ldquo;pre-calculation&amp;rdquo;, as the pixel distances and angles of the tunnel
are pre-computed, and the runtime is basically moving around those tables at each frame.&lt;br&gt;
Pre-calculation is what makes this demo running so fast and so smoothly at 60 frames per second, on a very old PC&amp;rsquo;s CPU.&lt;/p&gt;
&lt;p&gt;If you are interested in the CPU computation, you can take a look at &lt;a href=&#34;https://lodev.org/cgtutor/tunnel.html&#34;&gt;this excellent blog post&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;running-the-code&#34;&gt;
  Running the code
  &lt;a class=&#34;anchor&#34; href=&#34;#running-the-code&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Developing on &lt;a href=&#34;https://carette.xyz/posts/frame_engine_advances_2023&#34;&gt;&amp;ldquo;Frame Engine&amp;rdquo;&lt;/a&gt;, I wondered how long it would take to rewrite this
effect using a modern graphics API like Metal.&lt;/p&gt;
&lt;p&gt;First, as I transformed my 2D engine to full-3D, I forgot to include some very basic 2D meshes like a surface&amp;hellip; so,
I wrote a very basic one as an OBJ file:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-obj&#34; data-lang=&#34;obj&#34;&gt;mtllib 2D_surface.mtl

v 0.000000 1.000000 0.000000
v 0.000000 0.000000 0.000000
v 1.000000 0.000000 0.000000
v 1.000000 1.000000 0.000000
vt 0.000000 0.500000 0.000000s
vt 0.000000 0.000000 0.000000
vt 0.500000 0.000000 0.000000
vt 0.500000 0.500000 0.000000
# 4 vertices

f 1/1 2/2 3/3 4/4
# 1 element
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once I have the surface, let&amp;rsquo;s write the fragment shader.&lt;/p&gt;
&lt;p&gt;The Metal fragment shader is actually very simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define ANIM_DISTANCE 0.45
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define ANIM_ANGLE    0.25
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;float4 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tunnel&lt;/span&gt;(float2 worldPosition,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              texture2d&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;, access::sample&amp;gt; colorTexture,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              sampler colorSampler,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              constant FragmentUniforms&amp;amp; uniforms) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Compute the angle for the effect
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;  angle = atan2(1.0 + worldPosition.y, 1.0 + worldPosition.x) / PI; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// More the pixel is near the center and more it is distant for the effet
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;  distance = sqrt(dot(position, position));                    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Compute the UV of the texture to render
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    float2 uv = float2(angle, ANIM_DISTANCE + (ANIM_ANGLE / distance));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Return the color
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; colorTexture.sample(colorSampler, uv);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To make a movement, you can multiply for example the &lt;strong&gt;ANIM_DISTANCE&lt;/strong&gt; by your timer, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;float2 uv = float2(angle, cos(uniforms.time) * ANIM_DISTANCE + (ANIM_ANGLE / distance));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that we have the metal shader, let&amp;rsquo;s take a look at the sampler&amp;hellip;&lt;br&gt;
We want to repeat the texture motif for &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;t&lt;/code&gt;, we do want &lt;strong&gt;linear&lt;/strong&gt; filter near the eye, and &lt;strong&gt;nearest&lt;/strong&gt; filter
far the eye.&lt;/p&gt;
&lt;p&gt;Associated to the texture, we could set the sampler like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;samplerDescriptor&lt;/span&gt; = MTLSamplerDescriptor()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.normalizedCoordinates = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.minFilter             = .nearest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.magFilter             = .linear
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.sAddressMode          = .mirrorRepeat
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.tAddressMode          = .mirrorRepeat
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;samplerDescriptor.maxAnisotropy         = 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;self&lt;/span&gt;.samplerState = device.makeSamplerState(descriptor: samplerDescriptor)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using this setting, and a few textures, you should get the following results:&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;First example of the Tunnel effect, rendered in the Frame Engine editor&#34; src=&#34;https://carette.xyz/images/tunnel_ex_0.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Second example of the Tunnel effect, rendered in the Frame Engine editor&#34; src=&#34;https://carette.xyz/images/tunnel_ex_1.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The animated version is available on YouTube: &lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/GqaDGEvxQ5E?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;
.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Update on Frame engine (2/x)</title>
      <link>https://carette.xyz/posts/frame_engine_advances_2023/</link>
      <pubDate>Sun, 13 Aug 2023 15:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/frame_engine_advances_2023/</guid>
      <description>&lt;p&gt;Almost one year ago &lt;a href=&#34;https://carette.xyz/posts/frame_engine_advances_2022&#34;&gt;I posted my advances&lt;/a&gt; on &amp;ldquo;&lt;code&gt;Frame&lt;/code&gt;&amp;rdquo;, a custom game engine wrote in Swift with SwiftUI, and Metal as a backend.&lt;/p&gt;
&lt;p&gt;From August 2022 to August 2023, I made a &lt;strong&gt;journey&lt;/strong&gt; into two different graphics libraries: &lt;em&gt;Vulkan&lt;/em&gt;, and &lt;em&gt;Metal&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-new-project&#34;&gt;
  The new project
  &lt;a class=&#34;anchor&#34; href=&#34;#the-new-project&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I definitely wanted to take a deep look into Vulkan for multiple different reasons: i) it is cross-platform, and ii) Vulkan begins to be widely used as a &amp;ldquo;standard&amp;rdquo; for game engines rendering backend, iii) I needed to get deeper for my work.
Indeed, since July 2023, I port at RedArtGames a Vulkan game engine for all the modern consoles, and it made me curious to learn more, more, and more and this graphics library.&lt;/p&gt;
&lt;p&gt;Metal is great and very (very very) powerful, or at least powerful enough for me to create good 2D and 3D experiences for mac, iPhone and iPad users.
&lt;strong&gt;But&lt;/strong&gt; the issue with Metal is that it is used for Apple platforms only.
You can compile your shaders on Windows now, but you can&amp;rsquo;t (still?) run Metal application from other platforms.&lt;br&gt;
So, I took my bag and got into a journey to create a tiny 3D rendering program portable using Vulkan and Metal as backends, which could run on Windows, macOS and iPadOS.
At the end, after a year, this &amp;ldquo;tiny 3D rendering program&amp;rdquo; became my new graphics engine&amp;hellip;&lt;/p&gt;
&lt;p&gt;There exist some Vulkan binding projects for Swift, like SwiftVulkan, but I prefered this time a simpler approach, developing this program in good-old C++ (17).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-issue-with-vulkan&#34;&gt;
  The issue with Vulkan
  &lt;a class=&#34;anchor&#34; href=&#34;#the-issue-with-vulkan&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, I got into the documentation of Vulkan, which is very large and which you can simply fall into&amp;hellip; and getting more confuse at the end.
It is a very strange feeling: the documentation is very dense, too much straightforward most of the time (no context of the error at all for example), and when you get answer then two other questions pop in your mind based on what the documentation describes as the error&amp;hellip;&lt;br&gt;
Very strange.&lt;/p&gt;
&lt;p&gt;The Vulkan API (&lt;code&gt;1.3.211.0&lt;/code&gt; in my case) is &lt;strong&gt;too&lt;/strong&gt; verbose, and there is a rumor thats says you will have to write 300 lines of code before rendering your &amp;ldquo;&lt;em&gt;hello-world GPU graphics programming program&lt;/em&gt;&amp;rdquo; : the famous RGB triangle.&lt;br&gt;
&lt;strong&gt;Yes, it is 100% true.&lt;/strong&gt;&lt;br&gt;
I don&amp;rsquo;t have any issue with verbose APIs &lt;strong&gt;but&lt;/strong&gt;, to me, verbose APIs have to be verbose for a reason: like very long names to avoid unnecessary comments or dev doc, to let the reviewer understands what the code is doing or what is the current process in the graphics pipeline, etc.
To me this is not the case for Vulkan.&lt;br&gt;
What is the purpose of setting all your pipeline parts in your code if it has to be default one most of the time?&lt;br&gt;
What is the purpose of implementing a wild-variety of non-typed enums if it is not for making mistakes and scratch your head for 15 minutes? &lt;br&gt;
The API structures / classes are large and it is &lt;strong&gt;very&lt;/strong&gt; easy to make a mistake, simply put a wrong enum, and lose 3ms in performance because of this&amp;hellip;&lt;/p&gt;
&lt;p&gt;A nice thing about Vulkan otherwise is the internal validator.
The warning / error messages are good enough to get what is the problem right away, including a hyperlink to the online documentation.&lt;/p&gt;
&lt;p&gt;In terms of documentation, I think there is no official tutorial for Vulkan.
I found out a very old tutorial called &amp;ldquo;&lt;em&gt;Vulkan Tutorial&lt;/em&gt;&amp;rdquo; but, after looking at the description and the code, I wouldn&amp;rsquo;t recommend it to anyone as it is very outdated and contain multiple mistakes.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;lets-back-to-the-engine&#34;&gt;
  Let&amp;rsquo;s back to the engine&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-back-to-the-engine&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My engine has two backends now :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vulkan, used on Windows and macOS, using VoltenVK,&lt;/li&gt;
&lt;li&gt;Metal, used on macOS, iPhone and iPadOS, and using &lt;a href=&#34;https://developer.apple.com/metal/cpp/&#34;&gt;Metal-Cpp&lt;/a&gt; layer for C++.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the cross-platforms thing, I used the old-friend CMake to be assured that the engine could be built &amp;amp; run almost everywhere.
However one of my friends advice me to look at another build system called &lt;a href=&#34;https://premake.github.io&#34;&gt;&lt;code&gt;premake&lt;/code&gt;&lt;/a&gt;, which could simplify a lot all the CMakeFiles files I had to create to make everything portable.&lt;/p&gt;
&lt;p&gt;I implemented a debug view using &lt;a href=&#34;https://github.com/ocornut/imgui&#34;&gt;ImGui&lt;/a&gt; (again, big applauses for ocornut and the ImGui community for this awesome work), a nice graphical interface that runs almost everywhere, and the nice Docking features.&lt;/p&gt;
&lt;p&gt;I implemented all the conditions to have a &amp;ldquo;modern&amp;rdquo; scene:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a proper Scene architecture for thousands and thousands of objects to compute and render,&lt;/li&gt;
&lt;li&gt;a multitude of cameras in the Scene object, and a way to switch from one to another very easily,&lt;/li&gt;
&lt;li&gt;a proprietary solution to package 3D models, textures, &amp;hellip;&lt;/li&gt;
&lt;li&gt;multiple lighting solutions for the environment,&lt;/li&gt;
&lt;li&gt;a very simple collisions solution for objects in a scene,&lt;/li&gt;
&lt;li&gt;and a basic editor to quickly drag and drop objects from the computer to the virtual scene, move objects, move the scene&amp;rsquo;s main camera hitting &amp;ldquo;PLAY&amp;rdquo;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, I have implemented almost all of the things I had in my bucket lists from last year, except to let the developer modify and integrate its shaders via the game editor.&lt;/p&gt;
&lt;p&gt;I still don&amp;rsquo;t have a physics engine and sounds interpreter, as well as a game interpreter to run the objects scripts, but this is on list for August 2024&amp;hellip; if I can find the time!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;all-it-takes&#34;&gt;
  All it takes
  &lt;a class=&#34;anchor&#34; href=&#34;#all-it-takes&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A game engine is a very complex piece of software, and as all other complex softwares everywhere else, it costs in developing features, in refactoring, in debugging, in profiling, &amp;hellip; It costs &lt;strong&gt;your time&lt;/strong&gt;.
To find the time to search and make all of this, once the kids are in bed after work, twice a week at most, is a challenge for me today.&lt;/p&gt;
&lt;p&gt;I am very proud of what I learned and what I did after this one-year journey.
Metal is definitely a simpler API compared to Vulkan, just comparing the API complexity together, and I continue to think that Vulkan should have taken the same path as Metal in terms of simplifying the API, while offering great customization of the graphics pipeline &lt;strong&gt;if only necessary&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;See you in August 2024 for the third update 👀&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;screenshots&#34;&gt;
  Screenshots
  &lt;a class=&#34;anchor&#34; href=&#34;#screenshots&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A lighting scene, rendered on iPadOS&#34; src=&#34;https://carette.xyz/images/frame_advances_scene_ipad.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;A lighting scene, rendered on iPadOS&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;A small part of the editor and its basic debug interface&#34; src=&#34;https://carette.xyz/images/frame_advances_scene_editor.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;A small part of the editor and its basic debug interface&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The weird unreachable code</title>
      <link>https://carette.xyz/posts/the_unreachable_code_bug/</link>
      <pubDate>Sun, 12 Feb 2023 23:03:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_unreachable_code_bug/</guid>
      <description>&lt;p&gt;Last week I heard about a weird behaviour of a C++ program on Twitter.&lt;br&gt;
The code is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (1);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unreachable&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;wait... WHAT?!&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pretty simple, right? Two functions, one infinite loop, and the &lt;code&gt;unreachable&lt;/code&gt; function that is never called&amp;hellip;&lt;br&gt;
As you might expect the program will run until the user forces the program to quit, without any standard output,
no catch at all.&lt;/p&gt;
&lt;p&gt;However, &lt;strong&gt;under a certain condition&lt;/strong&gt;, it could also be executed in less than a millisecond and print&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wait... WHAT?!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I reproduced it on godbolt here for you if you do not believe me: &lt;a href=&#34;https://godbolt.org/z/MYhb9Ezv1&#34;&gt;https://godbolt.org/z/MYhb9Ezv1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, let me explain what is really happening under the hood.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-singular-points-of-the-program&#34;&gt;
  The singular points of the program
  &lt;a class=&#34;anchor&#34; href=&#34;#the-singular-points-of-the-program&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To explain the behaviour, let&amp;rsquo;s cut out the different parts of the program.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-main-function&#34;&gt;
  The main function
  &lt;a class=&#34;anchor&#34; href=&#34;#the-main-function&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (1);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function runs an infinite loop that is doing absolutely &lt;strong&gt;nothing&lt;/strong&gt;, and no instruction to break it somewhere.
The objective of the &lt;code&gt;main&lt;/code&gt; program is very very simple: &lt;strong&gt;loop over and do not stop&lt;/strong&gt;.&lt;br&gt;
Also, there is &lt;strong&gt;no&lt;/strong&gt; explicit return statement, but the compiler implicitely appends a &lt;code&gt;return 0&lt;/code&gt; statement at the end
of the code block.&lt;/p&gt;
&lt;p&gt;So, the final code, understood by the compiler, results as it is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (1) {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=&#34;heading&#34; id=&#34;the-unreachable-function&#34;&gt;
  The unreachable function
  &lt;a class=&#34;anchor&#34; href=&#34;#the-unreachable-function&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;unreachable&lt;/code&gt; is also very simple: print the message &amp;ldquo;&lt;em&gt;wait&amp;hellip; WHAT?!&lt;/em&gt;&amp;rdquo; and return.
The important thing to look here is that the function definition and implementation is done &lt;strong&gt;after&lt;/strong&gt; the &lt;code&gt;main&lt;/code&gt;
function, and this is very important to understand the behaviour of the final execution of the program.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-compiler-settings&#34;&gt;
  The compiler settings
  &lt;a class=&#34;anchor&#34; href=&#34;#the-compiler-settings&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Here, we are using clang13.0 (c++ frontend), with the following arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-01&lt;/code&gt;, which is the first entry of optimizations for clang,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-Werror&lt;/code&gt;, which enables all warning statements as errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;lets-play&#34;&gt;
  Let&amp;rsquo;s play
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-play&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;The main issue here is not coming from the program, or from the developer.
Actually, it comes from &lt;strong&gt;the compiler&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In godbolt, looking for the code generated by clang, the issue is on the first lines:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-assembly&#34; data-lang=&#34;assembly&#34;&gt;main:                                   # @main
unreachable():                          # @unreachable()
        push    rbx
        mov     edi, offset std::cout
        mov     esi, offset .L.str
        ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see the &lt;code&gt;@main&lt;/code&gt; &lt;strong&gt;label&lt;/strong&gt; is empty here, which results in executing the instructions contained in
the next &lt;code&gt;label&lt;/code&gt;&amp;hellip; which is &lt;code&gt;@unreachable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s interpret what the compiler might want to understand here&amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I am executing the &lt;code&gt;main&lt;/code&gt; function&amp;hellip;&lt;/li&gt;
&lt;li&gt;Hey, I don&amp;rsquo;t need to return anything from the &lt;code&gt;main&lt;/code&gt; function, as the loop is running forever! Ok, let&amp;rsquo;s remove it&amp;hellip;&lt;/li&gt;
&lt;li&gt;Hey, the loop is doing nothing, and the dev asks me to optimize the code&amp;hellip; let&amp;rsquo;s remove the loop then&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And then, we have a &lt;code&gt;main&lt;/code&gt; function that does not contain any &lt;code&gt;return&lt;/code&gt; statement, or any other instruction.&lt;br&gt;
Just an &lt;strong&gt;empty&lt;/strong&gt; function.&lt;/p&gt;
&lt;p&gt;This behaviour is quiet complex to understand at first as developers may want to say: &amp;ldquo;but, this is the same than
any other &lt;code&gt;void&lt;/code&gt; functions right?&amp;rdquo;.&lt;br&gt;
Absolutely&amp;hellip; not.&lt;/p&gt;
&lt;p&gt;If you take a look at the generated asm code from the following C++ function&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;do_nothing&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;it &lt;strong&gt;does&lt;/strong&gt; contain a &lt;code&gt;return&lt;/code&gt; statement:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-assembly&#34; data-lang=&#34;assembly&#34;&gt;do_nothing():                        # @do_nothing()
        ret                                  # &amp;lt;&amp;lt;&amp;lt;--- INSTRUCTION TO EXIT do_nothing()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So, the following program, using clang13.0 and &lt;code&gt;-O1&lt;/code&gt; optimization, does not execute the loop but does not print
anything:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (1) {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;do_nothing&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unreachable&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;wait... WHAT?!&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;as the generated asm code proves:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-assembly&#34; data-lang=&#34;assembly&#34;&gt;main:                                   # @main
do_nothing():                           # @do_nothing()
        ret                                     # &amp;lt;&amp;lt;&amp;lt;--- QUIT HERE
unreachable():                          # @unreachable() - NOT EXECUTED
        push    rbx
        mov     edi, offset std::cout
        mov     esi, offset .L.str
        ...
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&#34;heading&#34; id=&#34;the-strange-case-of-an-infinite-loop&#34;&gt;
  The strange case of an infinite loop
  &lt;a class=&#34;anchor&#34; href=&#34;#the-strange-case-of-an-infinite-loop&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;So, why does this occurs using an infinite loop ?&lt;/p&gt;
&lt;p&gt;Because an infinite loop is simply&amp;hellip; an &lt;strong&gt;undefined behavior&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The C standard (C11 to be more precise) &lt;a href=&#34;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1713.htm&#34;&gt;says this&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An iteration statement whose controlling expression is not a constant expression that performs no
input/output operations, does not access volatile objects, and performs no synchronization or atomic
operations in its body, controlling expression, or (in the case of a for statement)
its expression, may be assumed by the implementation to terminate&amp;hellip; This is intended to allow compiler
transformations such as removal of empty loops even when termination cannot be proven.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this case, &lt;code&gt;while(1)&lt;/code&gt; is an example of a constant expression, and then it may &lt;strong&gt;not&lt;/strong&gt; be assumed to
terminate.
So, the compiler may (or may not) decide to optimize it removing it from the code&amp;hellip; so does clang.&lt;/p&gt;
&lt;p&gt;This behaviour has been implemented for clang13.0, and is still used today in clang15.0.&lt;/p&gt;
&lt;p&gt;A fix that could implement clang for this case would be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;emit a &lt;code&gt;label&lt;/code&gt; (like &lt;code&gt;jmp loop&lt;/code&gt;) to jump over the infinite loop, and not remove it,&lt;/li&gt;
&lt;li&gt;or remove the infinite loop but emit another call to &lt;code&gt;return 0&lt;/code&gt; from &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>2022, in a nutshell</title>
      <link>https://carette.xyz/posts/2022_in_a_nutshell/</link>
      <pubDate>Tue, 27 Dec 2022 12:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/2022_in_a_nutshell/</guid>
      <description>&lt;p&gt;2022 was a strange year for everyone I think.
To me, it was a year full of reconsideration, of reflection on myself, the World, and my family&amp;rsquo;s future.
People tend to think that 2020 was the worst year to live recently, I don&amp;rsquo;t agree at all as I think the
worst may come &amp;ldquo;soon&amp;rdquo;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Anyway.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-blog-posts-statement&#34;&gt;
  The blog posts statement
  &lt;a class=&#34;anchor&#34; href=&#34;#the-blog-posts-statement&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I published nine posts this year (10 if you include the one you are reading):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;three technical topics&lt;/strong&gt;, mainly on low-level programming principles and graphics programming,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;three personal notes&lt;/strong&gt; about 2022 and personal changes,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;two high-level technical&lt;/strong&gt; notes, about demoscenes and publishing,&lt;/li&gt;
&lt;li&gt;and, finally, &lt;strong&gt;one non-technical note&lt;/strong&gt; about how to run old games on Apple Silicon macs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think I found a &amp;ldquo;good&amp;rdquo; publishing rate, and I expect to write more technical blog posts in the next year (maybe a
&amp;ldquo;&lt;em&gt;game engine series&lt;/em&gt;&amp;rdquo;, who knows).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;rethinking&#34;&gt;
  &amp;ldquo;Rethinking&amp;rdquo;
  &lt;a class=&#34;anchor&#34; href=&#34;#rethinking&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Professionally, 2022 got off to a &lt;em&gt;terrible&lt;/em&gt; start &lt;em&gt;but&lt;/em&gt; ended with the best work experience of my life.&lt;br&gt;
I switched in 2021 from an AI Engineer job to a Senior Software Engineer job, and 2022 was another transition
to a Game Developer career (to be honest, more a Game Engine Developer job), at Red Art Games.&lt;/p&gt;
&lt;p&gt;After eight months at &lt;a href=&#34;https://www.redartgames.com&#34;&gt;Red Art Games&lt;/a&gt;, I found out the video games industry
works great to me compared to other ones.
The thing I like the most is: &lt;strong&gt;your work has an end&lt;/strong&gt;.
Once the game is &amp;ldquo;ready to ship&amp;rdquo;, then you switch to another project and you don&amp;rsquo;t have to go back
(except if a player found a bug or if you want to develop an extension to the original game).&lt;br&gt;
Then, you take the experience you earned from the previous game, reconsider the full experience, take the best, and
finally make a transition to the new game, and redo the same process again and again for the next game(s).&lt;/p&gt;
&lt;p&gt;Compared to a web project, you don&amp;rsquo;t have to develop new features and reconsider the architecture of the current &amp;ldquo;stack&amp;rdquo;
to deliver new things each X months.
If you want to do more with an IP, then you develop a sequel or a new game in the same world, but it is another project.&lt;/p&gt;
&lt;p&gt;Also, after a few years using Go and Rust full-time, getting back to C++ 17/20 comforted me in the idea that the
language evolves in a good direction.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-i-expect-for-2023&#34;&gt;
  What I expect for 2023
  &lt;a class=&#34;anchor&#34; href=&#34;#what-i-expect-for-2023&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In 2022 I helped to port the games &lt;a href=&#34;https://www.youtube.com/watch?v=Rw2Uc3PFewA&#34;&gt;&amp;ldquo;OmegaBot&amp;rdquo;&lt;/a&gt; and &lt;a href=&#34;https://www.youtube.com/watch?v=UEBPGROX3UY&#34;&gt;&amp;ldquo;Shinorubi&amp;rdquo;&lt;/a&gt; on consoles, which are great projects for very different reasons.&lt;br&gt;
For 2023, I expect &lt;strong&gt;more cool games to port&lt;/strong&gt;, more complex tasks to learn new skills or to perfect my own skills, and a
few &amp;ldquo;easy&amp;rdquo; tasks to take a deep breathe between two complex ones.&lt;/p&gt;
&lt;p&gt;At the beginning of my gamedev career, I did not know what I wanted to do, and what I wanted to become.
After eight months working in a video game studio, I understood I am more interested in game engine development and
optimization (on the game engine side) than just &amp;ldquo;developing a game&amp;rdquo;.&lt;br&gt;
So, I would explore &lt;strong&gt;more game engine development &amp;ldquo;stuff&amp;rdquo;&lt;/strong&gt;, and maybe refine again my skills and where I want to contribute
at the gamedev side.&lt;/p&gt;
&lt;p&gt;In a more personal way, I sold my gaming laptop for a &lt;a href=&#34;https://www.steamdeck.com/fr/&#34;&gt;Steam Deck from Valve&lt;/a&gt;, which is
actually the &amp;ldquo;2022&amp;rsquo;s Game Gear&amp;rdquo; compared to the Nintendo Switch.
The Steam Deck is powerful, has some great features and works well, but more and more I play on it and more and more I
understand why the Nintendo Switch is the best handheld device since five years now.
Don&amp;rsquo;t get me wrong: it is awesome to play to &amp;ldquo;Death Stranding&amp;rdquo; or &amp;ldquo;Spiderman&amp;rdquo; on the Steam Deck, but I still consider
it (and its OS) has a beta for geeks and hackers, and not a device for everyone.
So, I expect &lt;strong&gt;a Nintendo Switch 2&lt;/strong&gt; for 2023, with more power and a slightly better battery.&lt;/p&gt;
&lt;p&gt;Finally, in an idealistic future: &lt;strong&gt;less war&lt;/strong&gt;, &lt;strong&gt;more love&lt;/strong&gt;, and an &lt;strong&gt;eco-friendly society&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-i-do-not-expect-for-2023&#34;&gt;
  What I do not expect for 2023
  &lt;a class=&#34;anchor&#34; href=&#34;#what-i-do-not-expect-for-2023&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The beta version of &amp;ldquo;Cyberpunk 2077&amp;rdquo;, which is still in alpha version since almost three years&amp;hellip;&lt;br&gt;
If CD Projekt still think they can make an &amp;lsquo;ok&amp;rsquo; game with what they done yet :)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fun with data alignment</title>
      <link>https://carette.xyz/posts/fun_with_data_alignment/</link>
      <pubDate>Fri, 18 Nov 2022 21:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/fun_with_data_alignment/</guid>
      <description>&lt;p&gt;Whoever worked on system programming know that data alignment is very important to save memory space,
or avoid runtime crashes casting from a specific type to another.&lt;br&gt;
After some months on porting games to console systems, I noticed how data alignment could be, sometimes,
a source of errors and a lack of knowledge.&lt;br&gt;
I wanted to discuss about data alignment in this technical article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is the technical stack I used for this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MacBook Air M1 (base model, 2020),&lt;/li&gt;
&lt;li&gt;clang 14.0.0 (Apple version), with C++17 support.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-problem&#34;&gt;
  The problem
  &lt;a class=&#34;anchor&#34; href=&#34;#the-problem&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;What is a data structure alignment?
An alignment is an integer value representing &lt;strong&gt;the number of bytes between successive addresses&lt;/strong&gt; at which a given struct, or object, can be allocated.&lt;br&gt;
In short: it a way to arrange and access an address in the computer memory.&lt;/p&gt;
&lt;!--
Just imagine a book&#39;s page: it has a fixed size, and can contains a maximum of `n` lines of size `x`.
They can contains a single line of size `y` (where `y &lt;= x`), `n-1` lines of size `x`, or just no line at all...
If the size of a line is stricly lower than `x`, then there could be some padding to let the next line begin right below.  
This is a brief overview of how works the memory of a computer: the memory is composed of `n` blocks (or pages) of fixed size `x`, which is composed itself by data structures (lines), which are themselves composed by words.
--&gt;
&lt;p&gt;As an example, for basic types on a 64bits system (&lt;em&gt;we will consider the following examples running on a 64bits system&lt;/em&gt;), an &lt;code&gt;int&lt;/code&gt; type sizes 4 bytes, a &lt;code&gt;char&lt;/code&gt; type sizes 1 byte, a &lt;code&gt;double&lt;/code&gt; type size 8 bytes, etc.&lt;/p&gt;
&lt;p&gt;But what about a &lt;code&gt;struct&lt;/code&gt;?
A first approach to compute the size of a &lt;code&gt;struct&lt;/code&gt; is to consider that the size of a &lt;code&gt;struct&lt;/code&gt; is equals to the sum of its fields size.&lt;br&gt;
As an example, we could compute the size of the following &lt;code&gt;Example&lt;/code&gt; C/C++ structure as 4 + 1 bytes, which results to 5 bytes in total.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Example&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; a; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; b; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, &lt;code&gt;Example&lt;/code&gt; is not 5 bytes but&amp;hellip; &lt;strong&gt;8&lt;/strong&gt; bytes, which is 3 bytes more than our hypothesis.&lt;br&gt;
To explain this behaviour, we will consecutively split the issue for five different structs and compare our expectations to the reality.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;how-to-compute-struct-sizes-&#34;&gt;
  How to compute struct sizes ?
  &lt;a class=&#34;anchor&#34; href=&#34;#how-to-compute-struct-sizes-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;da01&#34;&gt;
  DA01
  &lt;a class=&#34;anchor&#34; href=&#34;#da01&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA01&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a, b, c, d; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 * 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;DA01&lt;/code&gt; the maximum size taken by one field is &lt;strong&gt;1 byte&lt;/strong&gt;.
We have 4 fields of 1 byte, which results to &lt;strong&gt;4 bytes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;da02&#34;&gt;
  DA02
  &lt;a class=&#34;anchor&#34; href=&#34;#da02&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA02&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Padding of 3 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; b;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;DA02&lt;/code&gt; the maximum size taken by one field is &lt;strong&gt;4 bytes&lt;/strong&gt; (&lt;code&gt;b&lt;/code&gt;).
We have a field of 1 byte and another of 4 bytes, which results to &lt;strong&gt;8 bytes&lt;/strong&gt; as we have &lt;strong&gt;3 padding bytes&lt;/strong&gt; to allocate
memory for &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;da03&#34;&gt;
  DA03
  &lt;a class=&#34;anchor&#34; href=&#34;#da03&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA03&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Padding of 3 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; b; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; c, d, e; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 3 * 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Padding of 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;DA03&lt;/code&gt; the maximum size taken by one field is &lt;strong&gt;4 bytes&lt;/strong&gt; (&lt;code&gt;b&lt;/code&gt;).
We have a field of 1 byte and the second one of 4 bytes, and then three other 1 byte fields.
This results to &lt;strong&gt;12 bytes&lt;/strong&gt; as we have &lt;strong&gt;3 padding bytes&lt;/strong&gt; for &lt;code&gt;a&lt;/code&gt;, and &lt;strong&gt;1 padding byte&lt;/strong&gt; for &lt;code&gt;e&lt;/code&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;da04&#34;&gt;
  DA04
  &lt;a class=&#34;anchor&#34; href=&#34;#da04&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA04&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a, b, c, d; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 * 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; e; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;DA04&lt;/code&gt; the maximum size taken by one field is &lt;strong&gt;4 bytes&lt;/strong&gt; (&lt;code&gt;e&lt;/code&gt;).
We have 4 fields of 1 byte consecutively, which results to 4 bytes and &lt;strong&gt;no padding&lt;/strong&gt; needed.
This results to &lt;strong&gt;8 bytes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;da05&#34;&gt;
  DA05
  &lt;a class=&#34;anchor&#34; href=&#34;#da05&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA05&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 1 byte
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Padding of 7 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt; b; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 8 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, for &lt;code&gt;DA05&lt;/code&gt;, the maximum size taken by one field is &lt;strong&gt;8 bytes&lt;/strong&gt; (&lt;code&gt;b&lt;/code&gt;).
We have a field of 1 byte at first, and we must insert paddings to get 8 bytes in total - so, a &lt;strong&gt;padding of 7 bytes&lt;/strong&gt;.
This results to &lt;strong&gt;16 bytes&lt;/strong&gt; in total.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;summary&#34;&gt;
  Summary
  &lt;a class=&#34;anchor&#34; href=&#34;#summary&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Struct&lt;/th&gt;
					&lt;th&gt;Supposed size (in bytes)&lt;/th&gt;
					&lt;th&gt;Real size (in bytes)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;DA01&lt;/td&gt;
					&lt;td&gt;04&lt;/td&gt;
					&lt;td&gt;04&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DA02&lt;/td&gt;
					&lt;td&gt;05&lt;/td&gt;
					&lt;td&gt;08&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DA03&lt;/td&gt;
					&lt;td&gt;08&lt;/td&gt;
					&lt;td&gt;12&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DA04&lt;/td&gt;
					&lt;td&gt;08&lt;/td&gt;
					&lt;td&gt;08&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DA05&lt;/td&gt;
					&lt;td&gt;09&lt;/td&gt;
					&lt;td&gt;16&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The difference of size between &lt;code&gt;DA03&lt;/code&gt; and &lt;code&gt;DA04&lt;/code&gt;, which contain the same fields but using a different order, should alerts you how data alignment could be important to manage and save some space in your programs.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-benchmarks&#34;&gt;
  The benchmarks
  &lt;a class=&#34;anchor&#34; href=&#34;#the-benchmarks&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you want to reproduce the results by yourself, this is the simple program I used:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA01&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a, b, c, d;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; b;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA03&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; b;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; c, d, e;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA04&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a, b, c, d;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; e;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DA05&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;double&lt;/span&gt; b;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;template&lt;/span&gt; &amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;typename&lt;/span&gt; T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; getSize(T s, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;uint8_t&lt;/span&gt; expected_size, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt;* &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    printf(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;* %s: expected %d bytes, got %lu bytes (alignment of %lu byte(s)) &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;, name, expected_size, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s), _Alignof(s));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; DA01 s = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        getSize(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            s,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.a) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.b) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.c) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.d),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DA01&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; DA02 s = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        getSize(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            s,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.a) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.b),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DA02&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; DA03 s = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        getSize(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            s,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.a) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.b) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.c) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.d) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.e),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DA03&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; DA04 s = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        getSize(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            s,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.a) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.b) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.c) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.d) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.e),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DA04&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; DA05 s = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        getSize(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            s,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.a) + &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(s.b),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;DA05&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you execute the program, using any optimization (&lt;code&gt;-Oxxx&lt;/code&gt;) compiler parameter you want, you would obtain the
following output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA01: expected 4 bytes, got 4 bytes (alignment of 1 byte(s))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA02: expected 5 bytes, got 8 bytes (alignment of 4 byte(s))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA03: expected 8 bytes, got 12 bytes (alignment of 4 byte(s))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA04: expected 8 bytes, got 8 bytes (alignment of 4 byte(s))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA05: expected 9 bytes, got 16 bytes (alignment of 8 byte(s))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=&#34;heading&#34; id=&#34;why-does-this-matter-&#34;&gt;
  Why does this matter ?
  &lt;a class=&#34;anchor&#34; href=&#34;#why-does-this-matter-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As you might know, the CPU accesses memory by a &lt;strong&gt;single&lt;/strong&gt; memory &lt;em&gt;WORD&lt;/em&gt; at each CPU clock.&lt;br&gt;
As long as the memory &lt;em&gt;WORD&lt;/em&gt; size is, at least, as large as the largest data type supported,
aligned accesses will &lt;strong&gt;always&lt;/strong&gt; access a single memory &lt;em&gt;WORD&lt;/em&gt;. This may not be true for misaligned data accesses.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;performance&#34;&gt;
  Performance
  &lt;a class=&#34;anchor&#34; href=&#34;#performance&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;As I explained before the system tries to grab a value, and parse it, from its data alignment information.&lt;br&gt;
As an example, there is absolutely no issue for the following structure to parse it with a manual alignment of 1 byte.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Example&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; a, b, c, d; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 fields, 4 reads.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, let&amp;rsquo;s consider the following structure&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Example&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; a; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 1 fields, but 4 reads if the data alignment is set to 1 byte.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As we know, for a x86/64 or arm 64 architecture, an &lt;code&gt;int&lt;/code&gt; type has a size of 4 bytes.
If we specify a data alignment of 1 byte, this mean that the system will have to read &lt;strong&gt;4 times&lt;/strong&gt; the fields in
order to get the real value behind &lt;code&gt;a&lt;/code&gt;, and make something with.&lt;br&gt;
This would be at most &lt;strong&gt;4 times slower&lt;/strong&gt; than specifying a data alignment of 4 bytes for this &lt;code&gt;Example&lt;/code&gt; structure, which could
grab the entire value in only one read (and I did not count the data consolidation cost).&lt;/p&gt;
&lt;p&gt;And I don&amp;rsquo;t talk about misaligned continuous fields in a struct that can reduces significantively the reading and parsing
of the data stored in it, and might results to undefined behaviors.&lt;/p&gt;
&lt;p&gt;Also, a correct alignment for your data structures may help very much the cache system.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;undefined-behaviors&#34;&gt;
  Undefined behaviors
  &lt;a class=&#34;anchor&#34; href=&#34;#undefined-behaviors&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;In system programming you could consider to cast one type to another&amp;hellip; and so a structure or a basic type.&lt;/p&gt;
&lt;p&gt;As an example, you could theoritically cast, or copy, a &lt;code&gt;uint8_t&lt;/code&gt; type to a &lt;code&gt;uint32_t&lt;/code&gt; type.&lt;br&gt;
However, the size is not correct, and so the data alignment.&lt;br&gt;
So, a &lt;strong&gt;page fault&lt;/strong&gt; error could happen finishing the cast and reading the result value, a 32 bytes value from an 8 bytes aligned value&amp;hellip; outch!&lt;/p&gt;
&lt;p&gt;Undefined behaviors can also happen, which are most of the time much harder to find and solve than crashes.&lt;/p&gt;
&lt;p&gt;This may happen very frequently when you try to copy a data structure from a memory place to another, which belongs to
another hardware / chip.
This is frequent for systems with APU(s).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;alignment-specification&#34;&gt;
  Alignment specification
  &lt;a class=&#34;anchor&#34; href=&#34;#alignment-specification&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;in-the-code&#34;&gt;
  In the code
  &lt;a class=&#34;anchor&#34; href=&#34;#in-the-code&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;There are different ways to specify a data alignment for one, or all, data structure(s).&lt;/p&gt;
&lt;p&gt;As an example you could specify a data alignment using pragmas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#pragma pack&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#pragma data_align&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#pragma align&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You could also use the &lt;code&gt;alignas&lt;/code&gt; keyword specifying the data structure, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;alignas&lt;/span&gt;(32) AlignAsExample
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt; a[4]; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// 4 * 8 bytes, which results to 32 bytes. Nice!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or using, for example, the &lt;code&gt;__declspec(align(#))&lt;/code&gt; keyword.&lt;br&gt;
However, as the official Microsoft documentation states for MSVC:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The compiler doesn&amp;rsquo;t guarantee or attempt to preserve the alignment attribute of data during a copy or data transform operation.
You can take a look at this documentation &lt;a href=&#34;https://learn.microsoft.com/en-us/cpp/cpp/align-cpp?view=msvc-170&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This may be the principal method to use, as you may want to use a different data alignment per struct, and not for your
entire program.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;via-your-compilers-options&#34;&gt;
  Via your compiler&amp;rsquo;s options
  &lt;a class=&#34;anchor&#34; href=&#34;#via-your-compilers-options&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Fortunately you can specify the alignment for each or all structs &lt;strong&gt;in&lt;/strong&gt; the code, or via a compiler&amp;rsquo;s setting.&lt;br&gt;
On my local &lt;code&gt;clang&lt;/code&gt; compiler the option to specify the maximum alignment data size is &lt;code&gt;-fpack-struct&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As an example, compiling the same code (from the &amp;ldquo;Benchmarks&amp;rdquo; section) with a &lt;code&gt;-fpack-struct&lt;/code&gt; of &lt;strong&gt;1 byte&lt;/strong&gt; outputs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA01: expected 4 bytes, got 4 bytes (alignment of 1 bytes) 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA02: expected 5 bytes, got 5 bytes (alignment of 1 bytes) 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA03: expected 8 bytes, got 8 bytes (alignment of 1 bytes) 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA04: expected 8 bytes, got 8 bytes (alignment of 1 bytes) 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* DA05: expected 9 bytes, got 9 bytes (alignment of 1 bytes)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Update on Frame engine (1/x)</title>
      <link>https://carette.xyz/posts/frame_engine_advances_2022/</link>
      <pubDate>Wed, 17 Aug 2022 19:20:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/frame_engine_advances_2022/</guid>
      <description>&lt;p&gt;Today I wanted to share my advancements on &lt;code&gt;Frame&lt;/code&gt;, a game engine I began almost two years ago, for Apple devices
only.&lt;/p&gt;
&lt;p&gt;In December 2020 I played a bit with Swift, SwiftUI, and Metal, on a custom game engine called &amp;ldquo;&lt;code&gt;Frame&lt;/code&gt;&amp;rdquo;.&lt;br&gt;
At that time I was not yet a father, and I had a lot of spare time (too much maybe) to spend on this project.&lt;br&gt;
I dropped the project a year after, in December 2021, as it became very difficult for me to focus and spend my
spare time on this kind of difficult project.&lt;/p&gt;
&lt;p&gt;As making games is hard, making game engines is 100x harder, trust me.&lt;/p&gt;
&lt;p&gt;Recently, during an incredible sunny day, I re-opened the &lt;code&gt;Frame&lt;/code&gt; project, looked at the code and, using the strength
of a powerful and deep voice, said &lt;strong&gt;&amp;ldquo;WhAt ThE F#$% Is ThIs CoDe?!&amp;rdquo;&lt;/strong&gt;.&lt;br&gt;
After one year and a half I became a much better Swift programmer, and I noticed quickly the core mistakes
I made, which &amp;ldquo;forced me&amp;rdquo; to step back from the project.&lt;br&gt;
So, during two week-ends and a few days of vacations, I get back on &amp;ldquo;&lt;code&gt;Frame&lt;/code&gt;&amp;rdquo; to deliver a much better experience to
the game developer (actually &amp;lsquo;me&amp;rsquo;), more features, better performance, and&amp;hellip; more platforms support!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;better-code-abstraction&#34;&gt;
  Better code abstraction
  &lt;a class=&#34;anchor&#34; href=&#34;#better-code-abstraction&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The first thing I made was to make my Swift code &lt;strong&gt;simpler to understand&lt;/strong&gt; and &lt;strong&gt;better to maintain&lt;/strong&gt;.&lt;br&gt;
I removed a lot of duplicated things, introduced new code abstraction for better code management, make the &lt;code&gt;Scene&lt;/code&gt; object
as a real code representation of a  &lt;em&gt;game scene&lt;/em&gt;, etc.&lt;/p&gt;
&lt;p&gt;The mistakes I made in the first version of the engine was the consequence of how I learned Swift and SwiftUI, and
how I understood the concepts at this time.&lt;/p&gt;
&lt;p&gt;Now, as I became better using those tools, I am able to detect some anti-patterns and to fix them quickly.&lt;br&gt;
Pretty nice!&lt;/p&gt;
&lt;p&gt;In the first version of &lt;code&gt;Frame&lt;/code&gt;, which was a simple 2D rendering tool, this is my codebase
(using &lt;a href=&#34;http://cloc.sourceforge.net&#34;&gt;cloc&lt;/a&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Language                     files          blank        comment           code
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Swift                           18            170            249            741
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Metal                            2              8             19             28
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SUM:                            20            178            268            769
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the new version of &lt;code&gt;Frame&lt;/code&gt;, which is basically a 2D/3D rendering tool with proper 3D objects and multi-platforms support:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Language                     files          blank        comment           code
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Swift                           14            142            204            791
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Metal                            1             14             13             59
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C/C++ Header                     1              7             11             24
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SUM:                            16            163            228            874
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which is &amp;ldquo;only&amp;rdquo; 100 more lines in total, not bad at all!&lt;/p&gt;
&lt;p&gt;The C/C++ header is to use only one representation of data structures to pass in the shaders,
instead of duplicating the data structures each time.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-camera-object&#34;&gt;
  The camera object
  &lt;a class=&#34;anchor&#34; href=&#34;#the-camera-object&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In the previous version of &lt;code&gt;Frame&lt;/code&gt;, there was no proper camera - only a fixed &amp;ldquo;eye&amp;rdquo; at origin (0, 0, 0) that displays
everything around him with a limit of (1, 1, 1).&lt;/p&gt;
&lt;p&gt;The camera is now an object, and contains a proper Field of View (FOV) property, and a limit (the &lt;code&gt;far limit&lt;/code&gt;) to avoid declaring and rendering very far objects from the camera (something that could exists at runtime, but so tiny in
the scene that you can&amp;rsquo;t see it very well).&lt;/p&gt;
&lt;p&gt;The camera position and angle can be updated using native gestures through SwiftUI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;drag to move the camera in the scene (actually, move the scene objects around the camera&amp;hellip;),&lt;/li&gt;
&lt;li&gt;pinch-in and pinch-out to zoom-in and zoom-out in the scene,&lt;/li&gt;
&lt;li&gt;and use the rotation gesture to rotate the camera around a particular 3D object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Actually, the camera is a special Swift 3D object (see next section) that does not contain any mesh or texture, and
not rendered.&lt;/p&gt;
&lt;p&gt;An example of the interaction in a very basic 3D scene that contains 5 differents objects:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the camera,&lt;/li&gt;
&lt;li&gt;the light bubble, which lights up and lights down the objects of the scene,&lt;/li&gt;
&lt;li&gt;three different 3D boxes, each with a proper texture.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/NkvK1In-568?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;h2 class=&#34;heading&#34; id=&#34;3d-objects-and-textures-support&#34;&gt;
  3D objects and textures support
  &lt;a class=&#34;anchor&#34; href=&#34;#3d-objects-and-textures-support&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;For 3D objects I can now render dynamically any &lt;code&gt;.obj&lt;/code&gt; file for an abstract 3D object, as soon as it packaged in the app (which is not really useful for a game engine, I admit it).&lt;/p&gt;
&lt;p&gt;The 3D object can move its own position in the scene, its euler angles, etc.
There is no limit for it.&lt;/p&gt;
&lt;p&gt;Any 3D object derived from a &lt;code&gt;BaseObject3D&lt;/code&gt; protocol, which derived itself from &lt;code&gt;ObservableObject&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;protocol&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;BaseObject3D&lt;/span&gt;: ObservableObject {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/// The position of the object in the world space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;position&lt;/span&gt;: simd_float3 { &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;get&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/// The visualization angle of the object in the world space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle&lt;/span&gt;: simd_float3 { &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;get&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;set&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/// A name to describe the object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tag&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;String&lt;/span&gt; { &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;get&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/// Function to update the attributes of the BaseObject3D, each&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/// time the render function must be called&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;BaseObject3D&lt;/code&gt; is very simple, but I will make it a bit more comfy to add new attributes and
information, like the meshes to use, the texture to load and to render, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;I added support for textures, and created another shader to display them correctly.&lt;br&gt;
I still have some issues to render a texture on rounded 3D objects (like a sphere), but this will be fixed
anytime soon.&lt;/p&gt;
&lt;p&gt;Also, I implemented a first version of a &lt;code&gt;Light&lt;/code&gt; object, to light up (and down) 3D objects that belong to
the rendered scene.&lt;br&gt;
There are still big improvements to make for the &lt;code&gt;Light&lt;/code&gt; object but the basic version works quite well.&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;An example of the light bubble in a 3D scene&#34; src=&#34;https://carette.xyz/images/frame_advances_light_bubble.jpg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-renderer&#34;&gt;
  The renderer
  &lt;a class=&#34;anchor&#34; href=&#34;#the-renderer&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This can be part of the &lt;a href=&#34;#anchor&#34; title=&#34;Better code abstraction&#34;&gt;first section&lt;/a&gt; but the scene and the
rendering code were really intricated and very difficult to maintain without touching of each other.&lt;br&gt;
Normally, in a modern and &amp;ldquo;generic&amp;rdquo; engine, this should not happens: the renderer should run without any internal
knowledge of the scene to render: just vertices, colors, and textures to draw.&lt;/p&gt;
&lt;p&gt;The first version of the renderer was not great, and difficult to maintain.&lt;br&gt;
I also made some abstractions to avoid containing the renderer in the internal &lt;code&gt;Coordinator&lt;/code&gt; object of the engine view,
which should be a &lt;code&gt;NSViewRepresentable&lt;/code&gt; derived object.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;better-performances&#34;&gt;
  Better performances
  &lt;a class=&#34;anchor&#34; href=&#34;#better-performances&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Now, running the full engine, creating and rendering a simple 3D scene is taking 24MB of RAM &lt;strong&gt;maximum&lt;/strong&gt; and,
of course, the rendering is done 60 frames per second.&lt;/p&gt;
&lt;p&gt;Simplifying the code and the rendering reduced drastically the RAM taken by the app, from 100MB to 24MB.
There are new things to be done in order to increase the performances, but I am happy about the improvements for now.&lt;/p&gt;
&lt;p&gt;The renderer takes, in average, 4ms in debug mode, so I can render this
basic scene at 250 FPS&amp;hellip; in &lt;strong&gt;debug mode&lt;/strong&gt;, and for each platform.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;natively-on-ios-ipados-and-macos&#34;&gt;
  Natively on iOS, iPadOS, and macOS
  &lt;a class=&#34;anchor&#34; href=&#34;#natively-on-ios-ipados-and-macos&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The main drawback of my initial project was the support of multiple Apple platforms.&lt;br&gt;
At the beginning I imagined &lt;code&gt;Frame&lt;/code&gt; as a game engine to run on macOS, to developer games for macOS.
However, more and more I worked on &lt;code&gt;Frame&lt;/code&gt; and more and more I was convinced to run the engine on the iPad and develop games on the iPad directly could be a really nice feature.&lt;/p&gt;
&lt;p&gt;Now, &lt;code&gt;Frame&lt;/code&gt; is supported natively&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; on iOS, iPadOS, and macOS.&lt;/p&gt;
&lt;p&gt;The devices I test all along the changes were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;my mac (&lt;em&gt;macbook air m1&lt;/em&gt; - base model),&lt;/li&gt;
&lt;li&gt;my iPad (&lt;em&gt;iPad 9th gen&lt;/em&gt; - base model),&lt;/li&gt;
&lt;li&gt;two iPhone simulators: &lt;em&gt;iPhone SE&lt;/em&gt; (for compatibility with older iPhone models) and &lt;em&gt;iPhone 13&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The debugger of the engine (the right part of the renderer) is not displayed correctly in the simulator, but it
renders well on real hardware.&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Frame on macOS&#34; src=&#34;https://carette.xyz/images/frame_advances_plat_macOS.jpeg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Frame on iPadOS&#34; src=&#34;https://carette.xyz/images/frame_advances_plat_iPadOS.jpeg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;Frame on iOS&#34; src=&#34;https://carette.xyz/images/frame_advances_plat_iOS.jpeg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-annoying-part-xcode&#34;&gt;
  The annoying part: Xcode
  &lt;a class=&#34;anchor&#34; href=&#34;#the-annoying-part-xcode&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I use Apple devices as a developer since more than 12 years now, and I am noticing each year the decline of Apple
to develop appealing and stable tools for developers&amp;hellip; like &lt;em&gt;Xcode&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Xcode&lt;/em&gt; is a messy developer tool, greedy for computing resources, to write code for Apple devices.&lt;/p&gt;
&lt;p&gt;Some annoying features from &lt;em&gt;Xcode&lt;/em&gt; are still present since a few years now, like &lt;em&gt;Xcode Preview&lt;/em&gt;, which does not reload
correctly, or some random build errors (clean + build again fixes the issue), or some cache issues, and very annoying
simulator issues to emulate the iPad app on the macbook through Catalyst (pinch-in and pinch-out works half of the time).&lt;/p&gt;
&lt;p&gt;Those issues are present since I worked on the first version of &lt;code&gt;Frame&lt;/code&gt; - almost two years ago - and I am frustrated to use
a buggy (developer) tool to develop a big project.&lt;br&gt;
I never thought I would say this but, concerning developer tools, Microsoft delivers much better developer tools for their
platform, like &lt;em&gt;Visual Studio 2019&lt;/em&gt; or &lt;em&gt;Visual Studio 2022&lt;/em&gt;&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion-and-future&#34;&gt;
  Conclusion and future
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion-and-future&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I made big improvements over two weeks of (hard) work on &lt;code&gt;Frame&lt;/code&gt;, and I am very happy with the changes for this
new version.&lt;br&gt;
Of course &lt;code&gt;Frame&lt;/code&gt; is absolutely not ready to create a very simple game using it, but it&amp;rsquo;s a new beginning for me and
I am excited to see what I will do next on it.
I know it will take me, at least, another two years to make very simple games using it, building and delivering
as packages on the iOS and macOS App Store.&lt;/p&gt;
&lt;p&gt;The list of features to implement keeps to grow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keyboard handler for iPadOS and macOS,&lt;/li&gt;
&lt;li&gt;multiple shaders support,&lt;/li&gt;
&lt;li&gt;better UI/UX,&lt;/li&gt;
&lt;li&gt;import external (not-in-the-app-bundle) 3D objects,&lt;/li&gt;
&lt;li&gt;integrate first 3D objects interaction(s) with the fingers and/or the mouse,&lt;/li&gt;
&lt;li&gt;let the developer modify and integrate its own Metal shaders in a dedicated native text editor,&lt;/li&gt;
&lt;li&gt;collision support,&lt;/li&gt;
&lt;li&gt;Metal 2 and Metal 3 support,&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code of &lt;code&gt;Frame&lt;/code&gt; will be kept private until I am done with it, and ready for interested people
to take a look and use it.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Using the same Swift / SwiftUI code, and one click (on &lt;em&gt;Xcode&lt;/em&gt;) to build and deploy
on the platform of your choice.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How to publish a bad programming article</title>
      <link>https://carette.xyz/posts/how_to_make_a_bad_article/</link>
      <pubDate>Tue, 09 Aug 2022 23:48:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/how_to_make_a_bad_article/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;[10th of August 2022 - Article Update]&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
A friend of mine told me he would not used the word &amp;ldquo;instructions&amp;rdquo; talking
about the size of a binary program, as there are not only instructions but the ELF structure, the imports, etc.&lt;br&gt;
After its careful review, I removed the word &amp;ldquo;instructions&amp;rdquo; for &amp;ldquo;lines&amp;rdquo; (even if I don&amp;rsquo;t really like the word &amp;ldquo;lines&amp;rdquo;&amp;hellip;).&lt;br&gt;
Thanks Eric for the review! :)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;After going to &lt;a href=&#34;https://news.ycombinator.com&#34;&gt;famous orange website&lt;/a&gt; I noticed an article claiming that &amp;lsquo;&lt;a href=&#34;https://lemire.me/blog/2022/08/09/hello-world-is-slower-in-c-than-in-c-linux/&#34;&gt;“Hello world” is slower in C++ than in C (Linux)&lt;/a&gt;&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;I was intrigued by the title at first but, after reading the first two paragraphs, I became mortified.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-issue-with-the-article&#34;&gt;
  The issue with the article
  &lt;a class=&#34;anchor&#34; href=&#34;#the-issue-with-the-article&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;C++ is a &lt;strong&gt;programming language&lt;/strong&gt; that includes its own standard library, but can also work with the
C standard library.
When you make comparisons, and especially if you publish the results publicly, you have to make sure
that what you are comparing can actually be compared (in short: do not compare apples with oranges).&lt;/p&gt;
&lt;p&gt;In this article, the author compares two different programs.&lt;br&gt;
A C program:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;hello world&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; EXIT_SUCCESS;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and a C++ program:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;hello world&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; EXIT_SUCCESS;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, as you already noticed, those programs are valid C and C++ programs but &lt;strong&gt;those programs compare the &lt;code&gt;stdio&lt;/code&gt; module against the &lt;code&gt;iostream&lt;/code&gt; module&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;std::endl&lt;/code&gt; does a buffer flush before printing the message on the standard output compared to the C version,
so the code is not strictly equivalent to the C sample&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;lets-redo-the-experiment&#34;&gt;
  Let&amp;rsquo;s redo the experiment
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-redo-the-experiment&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If we want to compare both languages, we actually have to compare the binaries (size / memory performance / execution time / &amp;hellip;)
of the same program compiled by different compilers: a C compiler, and a C++ compiler.&lt;br&gt;
So, if we really want to compare the languages, lets take only one code sample (the C sample), compiled with &lt;strong&gt;the same&lt;/strong&gt;
parameters, lets run them at least 5_000 times x 10 times (to avoid some computer working behaviours) and extract the
median of those bench (and the standard deviation as well, always interesting to take a look at this).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Also, the author did not explained which version of gcc/g++/clang, and which version of c++, to use to &lt;strong&gt;reproduce&lt;/strong&gt; the
results, which is a bad sign&amp;hellip;&lt;/p&gt;
&lt;p&gt;After updating the Makefile:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;all&lt;/span&gt;: helloc hellocpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	hyperfine --runs 5000 ./helloc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	hyperfine --runs 5000 ./hellocpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;helloc&lt;/span&gt;: hello.c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	clang -O2 -o helloc hello.c -Wall
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hellocpp&lt;/span&gt;: hello.cpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	clang -O2 -std=c++17 -o hellocpp hello.cpp -Wall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, the .cpp and the .c files are stricly equivalent:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;hello world&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; EXIT_SUCCESS;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I used &lt;code&gt;clang&lt;/code&gt; version 13.1.6 for this experiment.&lt;/p&gt;
&lt;p&gt;After compiling the binaries, lets compare the size first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; wc -c &amp;lt; helloc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   33427
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; wc -c &amp;lt; hellocpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   33429
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The C binary has 33427 lines, and the Cpp binary 33429 lines&amp;hellip; quite a lot to print an &amp;ldquo;hello world&amp;rdquo;!&lt;br&gt;
So, both binaries are different, as the cpp output has 2 lines more than the C one (could be instructions, a header
difference in the ELF structure, etc&amp;hellip;).&lt;/p&gt;
&lt;p&gt;And how many lines differ?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; cmp -l helloc hellocpp | wc -l
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   376
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;376 lines are different between both binaries, which is 1.12% of the entire size of the cpp binary (not so much).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-issue-with-hyperfine&#34;&gt;
  The issue with hyperfine
  &lt;a class=&#34;anchor&#34; href=&#34;#the-issue-with-hyperfine&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;hyperfine&lt;/code&gt; is a correct tool to make basic benchmarks but, as every software in the market, its performance and results
depend of the conditions during the tests.
To demonstrate this, I launched &lt;code&gt;hyperfine&lt;/code&gt; 5000 times for the same C program.
While &lt;code&gt;hyperfine&lt;/code&gt; was running the C program, I opened my text editor and began to write this article, knowing
that it should reduce drastically (all is relative) the performance running this simple C program.&lt;br&gt;
For the C++ one, I let &lt;code&gt;hyperfine&lt;/code&gt; running without touching the computer, and&amp;hellip; the results are amazing, as
&lt;strong&gt;C++ is now three times faster than C&lt;/strong&gt;!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; hyperfine --runs 10000 ./helloc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Benchmark 1: ./helloc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Time (mean ± σ):      10.7 ms ±   6.0 ms    [User: 1.5 ms, System: 3.0 ms]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Range (min … max):     0.0 ms … 193.3 ms    10000 runs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; hyperfine --runs 10000 ./hellocpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Benchmark 1: ./hellocpp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Time (mean ± σ):       3.4 ms ±   6.8 ms    [User: 0.4 ms, System: 0.8 ms]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Range (min … max):     0.0 ms … 424.8 ms    10000 runs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is, of course, an example of &amp;ldquo;&lt;strong&gt;what you should absolutely avoid&lt;/strong&gt;&amp;rdquo;, as the conditions to test the first
and the second programs were not the same.
And, if comparison conditions are not the same, then you can&amp;rsquo;t compare the results&amp;hellip;&lt;/p&gt;
&lt;p&gt;Also, this is to demonstrate why you should run multiple times your benchmarks, with no software running in the background (especially for very little programs like those).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;running-the-real-tests&#34;&gt;
  Running the real tests
  &lt;a class=&#34;anchor&#34; href=&#34;#running-the-real-tests&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Running the same both programs with the same conditions &lt;strong&gt;only ten times&lt;/strong&gt;, this is the median of the observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C: &lt;strong&gt;3.2ms&lt;/strong&gt;, standard deviation of &lt;strong&gt;0.8ms&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;C++ (with c++17): &lt;strong&gt;3.2ms&lt;/strong&gt;, standard deviation of &lt;strong&gt;0.9ms&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Same thing.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The author stated in its blog post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What we are testing by running these programs is the overhead due to the choice of programming language.
[&amp;hellip;]
One millisecond of overhead, if it is indeed correct, is a huge penalty.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is wrong&lt;/strong&gt;, as the author measured the overhead due to the choice of API used to print to the standard
output, and not the overhead of running the same program compiled with a C compiler, and another with the C++
compiler.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Final Note&lt;/strong&gt;: to finish, the author just demonstrated that &lt;code&gt;iostream&lt;/code&gt; is slower than &lt;code&gt;printf&lt;/code&gt;, and I think every
good or curious C++ developer in the world already knew that&amp;hellip;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The demoscene</title>
      <link>https://carette.xyz/posts/the_demoscene/</link>
      <pubDate>Wed, 27 Jul 2022 20:25:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_demoscene/</guid>
      <description>&lt;p&gt;Among all the computer subcultures that exist, the demoscene subculture is, without a doubt, the one that impresses me
the most.&lt;br&gt;
The demoscene is composed by demomakers, a worldwide network of very creative minds involved in the making of
(non-commercial) &lt;strong&gt;demos&lt;/strong&gt;, just for fun.&lt;/p&gt;
&lt;p&gt;But was is a &lt;em&gt;demo&lt;/em&gt;?
A demo is a technical and/or aesthetic achievement made by demomakers - most of the time by groups of demomakers -, to show off their programming, visual and musical skills through an innovative computer program.&lt;br&gt;
There are many demoscene productions: games, graphics, music, &amp;hellip; all with an idea of solving a challenge,
making a new big technical achievement, innovating, while having a lot fun.&lt;/p&gt;
&lt;p&gt;There exists a nice file browser in &lt;a href=&#34;https://www.scene.org&#34;&gt;scene.org&lt;/a&gt; for 2022, &lt;a href=&#34;https://files.scene.org/browse/parties/2022/&#34;&gt;here&lt;/a&gt;, that you can browse to look for great and fun achievements, with the only goal of making something
&amp;ldquo;great and fun&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;As an example, this is a &lt;em&gt;demo&lt;/em&gt; of a low-fidelity modern cinematic on an Amiga 500, a 34 years old computer, called
&amp;ldquo;Eon&amp;rdquo; by &lt;em&gt;The Black Lotus&lt;/em&gt;: &lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/i1O4_58HVIg?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;The Amiga 500 was the most popular computer of the Amiga family, composed by a Motorola 68000 CPU (7,09 MHz PAL, or 7,14MHz NTSC), and 512 KBytes of RAM, which is &lt;strong&gt;16384 times less&lt;/strong&gt; RAM than actual modern computers.
In the 80s, the Amiga offered a beautiful and colorful display, a better sound and a more advanced operating system than
most of its competitors &lt;strong&gt;as standard&lt;/strong&gt;.&lt;br&gt;
The Amiga 500 for the demoscene is not an exception: the demomaking computers family that were commonly used
were: the Commodore 64, the Atari ST and, of course, the Amiga family.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://commons.wikimedia.org/wiki/File:Amiga500_system.jpg#small&#34;&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;The Amiga 500&#34; src=&#34;https://upload.wikimedia.org/wikipedia/commons/c/c3/Amiga500_system.jpg&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Composed generally between 3 and 8 people, demomakers masterize their tools, and have so much creative minds to push the boundaries of programming, graphics, and music composition.&lt;/p&gt;
&lt;p&gt;Another demo from &lt;em&gt;The Black Lotus&lt;/em&gt; shows, in &lt;strong&gt;2006&lt;/strong&gt;, a very impressive demo called &amp;ldquo;Starstruck&amp;rdquo; running on an
(accelerated) Amiga 1200, competing with the best games of the time on recent hardware:
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/eqnZH7Pa3vo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;The demoscene contains multiple contests itself.
The most known are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;4k&lt;/strong&gt; contests: the demo must be self-contained in an executable of 4KBytes,&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;64k&lt;/strong&gt; contests (or &lt;strong&gt;intros&lt;/strong&gt;): the demo must be self-contained in an executable of 64KBytes,&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Demo&lt;/strong&gt; contests: people express their creativity in building small executables (generally 4MBytes) with great graphics,&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Gfx&lt;/strong&gt; contests: graphics contests,&lt;/li&gt;
&lt;li&gt;and the &lt;strong&gt;Mod&lt;/strong&gt; contests: for musicians, to express their creativity creating partitions based on new unique sounds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;About video games, a lot of newly created studios come from demoscenes like &lt;a href=&#34;https://www.starbreeze.com&#34;&gt;Starbreeze&lt;/a&gt;,
&lt;a href=&#34;https://www.remedygames.com&#34;&gt;Remedy&lt;/a&gt;, &lt;a href=&#34;https://techland.net&#34;&gt;Techland&lt;/a&gt;,
&lt;a href=&#34;https://www.guerrilla-games.com&#34;&gt;Guerilla Games&lt;/a&gt;, or &lt;a href=&#34;http://www.housemarque.com&#34;&gt;Housemarque&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;links&#34;&gt;
  Links
  &lt;a class=&#34;anchor&#34; href=&#34;#links&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;To know if there is a demoparty near your location: &lt;a href=&#34;https://www.demoparty.net&#34;&gt;https://www.demoparty.net&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;A web forum that lists great demos: &lt;a href=&#34;https://www.pouet.net&#34;&gt;https://www.pouet.net&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Old games on m1 macs, natively</title>
      <link>https://carette.xyz/posts/mac_source_ports/</link>
      <pubDate>Wed, 09 Mar 2022 09:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/mac_source_ports/</guid>
      <description>&lt;p&gt;Apple Silicon chips on the mac changed &lt;strong&gt;everything&lt;/strong&gt;&amp;hellip; except the gaming industry (yet).&lt;br&gt;
Even though M1 chips (M1, , M1 Pro, and M1 Max) have been sold a lot (+25% this January compared to January 2021, which had already broke all the records for mac sales), a very few companies updated their actual games to run on M1 chips.&lt;/p&gt;
&lt;p&gt;Even if a few solutions exist to run windows games on the M1 mac, running a windows VM using &lt;a href=&#34;https://www.parallels.com/fr/products/desktop/&#34;&gt;Parallels&lt;/a&gt;, or translating at runtime all the API calls via &lt;a href=&#34;https://www.codeweavers.com/crossover&#34;&gt;Crossover&lt;/a&gt;, those products are expensive to run - in terms of both money and computer resources -, still labeled as &amp;ldquo;experimental&amp;rdquo;, and there is a high risk to not run all your games.&lt;/p&gt;
&lt;p&gt;I recently heard about a website that lists old games ports (think about a port as a &amp;ldquo;translation&amp;rdquo; of a game from a given architecture [x86, x86_64, powerpc, &amp;hellip;] to another) for mac, including arm as a target, and finally found the website: &lt;a href=&#34;https://macsourceports.com&#34;&gt;https://macsourceports.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/mac_source_ports_2022.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; The home page of Mac Source Ports website &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Mac Source Ports games are &lt;strong&gt;universal&lt;/strong&gt;, to run in both x86_64 architecture (basically an intel chip) and arm architecture (M1 chip).&lt;br&gt;
Those ports are &lt;strong&gt;signed&lt;/strong&gt; and &lt;strong&gt;notarized&lt;/strong&gt;, so no issue running them on your mac and no awful pop-up asking to push the application into the bin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt; the ports contain only the &lt;em&gt;technical&lt;/em&gt; work about the game, which &lt;strong&gt;not&lt;/strong&gt; include the data.
So, you will have to buy the game first (&lt;a href=&#34;https://www.gog.com&#34;&gt;GOG&lt;/a&gt; is a great platform to buy DRM-free old games), extract the data from the official executables, and drag-and-drop the data files in the app you downloaded from Mac Source Ports.&lt;br&gt;
A software is freely available to extract the data from an executable &lt;a href=&#34;https://macsourceports.com/utilities&#34;&gt;here&lt;/a&gt;, signed and notarized (universal binary).&lt;/p&gt;
&lt;p&gt;There is a great list of old good games to play again and again and again:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System Shock,&lt;/li&gt;
&lt;li&gt;Return to Castle Wolfenstein,&lt;/li&gt;
&lt;li&gt;all Quake games and all old Doom games,&lt;/li&gt;
&lt;li&gt;Star Wars Jedi Knight: Dark Forces II&lt;/li&gt;
&lt;li&gt;RollerCoaster Tycoon 2,&lt;/li&gt;
&lt;li&gt;Diablo,&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The website lists all known ports, and do not hesitate to contact the author of the website directly if you know a port that can be used in both x86_64 and arm architectures.&lt;/p&gt;
&lt;p&gt;As stated by the author in the &lt;a href=&#34;https://macsourceports.com/faq&#34;&gt;FAQ&lt;/a&gt; section (&amp;ldquo;Why don&amp;rsquo;t you have Game X?&amp;rdquo;), if the source code of the game is not available the port can&amp;rsquo;t be done.
That is the only drawback of a port work.
Fortunately there are still some companies all around the world that release the source code of good old games (excluding the game data) to work on the ports, like ID software.&lt;/p&gt;
&lt;p&gt;The full list of games is available: &lt;a href=&#34;https://macsourceports.com/games&#34;&gt;https://macsourceports.com/games&lt;/a&gt;, and the source code of some ports is available on github: &lt;a href=&#34;https://github.com/MacSourcePorts&#34;&gt;https://github.com/MacSourcePorts&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The case of OpenGL, in C&#43;&#43;, on m1 mac</title>
      <link>https://carette.xyz/posts/opengl_and_cpp_on_m1_mac/</link>
      <pubDate>Mon, 07 Mar 2022 16:45:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/opengl_and_cpp_on_m1_mac/</guid>
      <description>&lt;p&gt;Since a long time now I was interested in learning computer graphics and &amp;ldquo;do stuff&amp;rdquo; with computer graphics APIs.&lt;br&gt;
I began to work on a very simple Game engine in Swift / Metal last year but I began to switch to a Windows machine
a few months ago, and Swift / Metal is not compatible with Windows (and will never be I think).&lt;/p&gt;
&lt;p&gt;Here, I wanted to go further in exploring OpenGL and / or Vulkan, for multi-platform GL.&lt;br&gt;
I choosed OpenGL because I am prototyping with GameMaker Studio 2, and writing shaders for it.&lt;br&gt;
Shaders in GMS2 use [GLSL](&lt;a href=&#34;https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)&#34;&gt;https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)&lt;/a&gt;, the &lt;em&gt;OpenGL Shading Language&lt;/em&gt;,
for OpenGL.&lt;/p&gt;
&lt;p&gt;I am using modern C++ (C++17) for this project, mainly because I really like modern C++.&lt;/p&gt;
&lt;p&gt;The goal of this (first?) part is to draw the famous RGB triangle, on the m1 mac, using C++17.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;why-not-metal-with-c-&#34;&gt;
  Why not Metal with C++ ?
  &lt;a class=&#34;anchor&#34; href=&#34;#why-not-metal-with-c-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Even if &lt;a href=&#34;https://developer.apple.com/metal/&#34;&gt;Apple Metal&lt;/a&gt; is great (actually, the API is pretty awesome), it is unfortunately specific to Apple products, and I wanted to work on something with platforms that &lt;strong&gt;do not&lt;/strong&gt; include &lt;em&gt;only&lt;/em&gt; Apple.&lt;br&gt;
Also, Metal is still a pretty young API and the documentation is not quite right sometimes&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;and-why-not-vulkan&#34;&gt;
  And why not Vulkan?
  &lt;a class=&#34;anchor&#34; href=&#34;#and-why-not-vulkan&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I am not opposed to Vulkan at all: performances are great, great ideas behind, and multiplatforms.
However, Vulkan is still young and is &lt;strong&gt;way more&lt;/strong&gt; complicated to learn than learning OpenGL.&lt;br&gt;
For this project I wanted to do simple graphics computing before, and it seems OpenGL is still supported in a large
range of operating systems (despite the fact that Apple deprecated the version &amp;gt;= 4.2 a few years ago to introduce
Metal).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;pre-requisites&#34;&gt;
  Pre-requisites
  &lt;a class=&#34;anchor&#34; href=&#34;#pre-requisites&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;compile-and-install-glfw&#34;&gt;
  Compile and install GLFW
  &lt;a class=&#34;anchor&#34; href=&#34;#compile-and-install-glfw&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;In this project, we will use GLFW.&lt;/p&gt;
&lt;p&gt;GLFW is an Open Source API for creating windows, contexts and surfaces, receiving input and events, for OpenGL,
OpenGL ES (outch&amp;hellip;), and Vulkan on desktop.
What does it means it that GLFW is a &lt;strong&gt;helper&lt;/strong&gt; library that starts the OpenGL &amp;ldquo;context&amp;rdquo; (a running copy of OpenGL, tied to a window) for us, and talks to a lot of platforms / operating systems in the same way.&lt;br&gt;
The current version of GLFW, writing this article, is the third: GLFW3.&lt;/p&gt;
&lt;p&gt;In homebrew, GLFW3 is not universal (so, not compatible with m1 macs).&lt;br&gt;
An issue on Github is still opened about this: &lt;a href=&#34;https://github.com/patriciogonzalezvivo/glslViewer/issues/219&#34;&gt;https://github.com/patriciogonzalezvivo/glslViewer/issues/219&lt;/a&gt;.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;compile-it-yourself&#34;&gt;
  Compile it yourself
  &lt;a class=&#34;anchor&#34; href=&#34;#compile-it-yourself&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;To use it, you will need to compile it yourself.&lt;br&gt;
For this, you will need to install &lt;code&gt;cmake&lt;/code&gt;: &lt;code&gt;brew install cmake&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once &lt;code&gt;cmake&lt;/code&gt; has been installed, you can install your arm64 compatible version of glfw3:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Remove GLFW&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew uninstall glfw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# Build GLFW from source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/glfw/glfw.git &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cd&lt;/span&gt; glfw &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cmake -DCMAKE_OSX_ARCHITECTURES=arm64 . &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make &amp;amp;&amp;amp; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can tweak the &lt;code&gt;make install&lt;/code&gt; statement in order to install the libraries in your prefered space.&lt;br&gt;
I choosed here the default location, which is &lt;code&gt;/usr/local/lib&lt;/code&gt;.&lt;/p&gt;
&lt;h4 class=&#34;heading&#34; id=&#34;pass-the-architecture-via-homebrew&#34;&gt;
  Pass the architecture via homebrew
  &lt;a class=&#34;anchor&#34; href=&#34;#pass-the-architecture-via-homebrew&#34;&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Another way to install it is to install it directly from source via homebrew:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install --from-source glfw3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but please to check first that &lt;code&gt;brew&lt;/code&gt; does not link by default to rosetta2 (and then produce x86_64 binaries,
which are not compatible with arm64).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-code&#34;&gt;
  The code
  &lt;a class=&#34;anchor&#34; href=&#34;#the-code&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In a file named &lt;code&gt;test_opengl.cpp&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#ifdef __APPLE__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Defined before OpenGL and GLUT includes to avoid deprecation messages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define GL_SILENCE_DEPRECATION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; **argv)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!glfwInit()) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;GLFW lib has been initialized...&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The line to compile the project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;g++ helloworld.cpp -o test_opengl -std=c++17 -framework Cocoa -framework OpenGL -framework IOKit -lglfw3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Exciting &lt;code&gt;test_opengl&lt;/code&gt; you should get a &lt;code&gt;Initialized...&lt;/code&gt; message on your stdout, and a quick open/closed window.&lt;br&gt;
Initialisation worked, yay!&lt;/p&gt;
&lt;p&gt;Also, we force the usage of modern C++, here &lt;code&gt;c++17&lt;/code&gt; specs.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;about-gl_silence_deprecation&#34;&gt;
  About GL_SILENCE_DEPRECATION
  &lt;a class=&#34;anchor&#34; href=&#34;#about-gl_silence_deprecation&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Apple deprecated OpenGL since macOS Catalina, as Apple wanted to force their own tech: Metal.&lt;br&gt;
OpenGL has been designed 25 years ago and lacks a lot of features now (and does not match right the modern
hardware architecture: GPU pipeline has changed, unsupported multithreaded operation, etc.).&lt;br&gt;
So, compiling the project without this flag will show a ton of warnings that
&lt;code&gt;OpenGL is now deprecated on Apple devices / platforms&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Defining &lt;code&gt;GL_SILENCE_DEPRECATION&lt;/code&gt; allows us to remove a ton of this kind of flags and focus on real problems.&lt;/p&gt;
&lt;p&gt;To know more about why Apple deprecated OpenGL (and introduced Metal), please to take a look &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2018/604/&#34;&gt;at this talk from WWDC2018&lt;/a&gt;.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-case-of-including-the-frameworks-everywhere&#34;&gt;
  The case of including the .frameworks everywhere&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#the-case-of-including-the-frameworks-everywhere&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;When checking the &lt;a href=&#34;https://www.glfw.org/docs/latest/build_guide.html#build_link_osx&#34;&gt;online documentation of GLFW3&lt;/a&gt;, it
is required to include official Apple frameworks for Cocoa, OpenGL, and IOKit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you still wish to build manually, you need to add the required frameworks and libraries to your command-line yourself using the -l and -framework switches.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;a-more-complex-example&#34;&gt;
  A more complex example
  &lt;a class=&#34;anchor&#34; href=&#34;#a-more-complex-example&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s create a window, and wait for the user to close it using his prefered signal, or by pressing the Escape key:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#ifdef __APPLE__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Defined before OpenGL and GLUT includes to avoid deprecation messages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define GL_SILENCE_DEPRECATION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; size_t WIDTH = 640;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; size_t HEIGHT = 480;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt;* WINDOW_NAME = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Test OpenGL&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt; * Callback to handle the &amp;#34;close window&amp;#34; event, once the user pressed the Escape key.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;quit_callback&lt;/span&gt;(GLFWwindow *window, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; key, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; scancode, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; action, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; _mods)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (key == GLFW_KEY_ESCAPE &amp;amp;&amp;amp; action == GLFW_PRESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwSetWindowShouldClose(window, GLFW_TRUE);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    GLFWwindow *window;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!glfwInit()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::cerr &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ERROR: could not start GLFW3&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Initialize the lib
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Minimum target is OpenGL 4.1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    window = glfwCreateWindow(HEIGHT, WIDTH, WINDOW_NAME, &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;NULL&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;NULL&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!window)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::cerr &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ERROR: could not open window with GLFW3&amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Close the window as soon as the Escape key has been pressed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwSetKeyCallback(window, quit_callback);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Makes the window context current
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwMakeContextCurrent(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; GLubyte* renderer = glGetString(GL_RENDERER);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; GLubyte* version = glGetString(GL_VERSION);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Renderer: &amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; renderer &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std::cout &amp;lt;&amp;lt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;OpenGL version supported: &amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; version &amp;lt;&amp;lt; std::endl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Now we have a current OpenGL context, we can use OpenGL normally
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (!glfwWindowShouldClose(window))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Render
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glClear(GL_COLOR_BUFFER_BIT);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Swap front and back buffers
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwSwapBuffers(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Poll for and process events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwPollEvents();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// ... here, the user closed the window
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On my mac, it runs flawlessly and write on the standard output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Renderer: Apple M1
OpenGL version supported: 4.1 Metal - 76.3
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&#34;heading&#34; id=&#34;improve-the-build-system&#34;&gt;
  Improve the build system
  &lt;a class=&#34;anchor&#34; href=&#34;#improve-the-build-system&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In order to avoid copy/pasting complex command lines to build an executable, but also to improve our build system with system conditions (like if the OS is Microsoft Windows, if macOS, if the kernel is linux, etc&amp;hellip;), we will need something more robust.&lt;br&gt;
For this, we will create our own CMakeFiles.txt file, which contains all the rules to build our own executable.&lt;/p&gt;
&lt;p&gt;On macOS, you will need to install &lt;code&gt;cmake&lt;/code&gt; (and make) using &lt;code&gt;brew&lt;/code&gt;: &lt;code&gt;brew install cmake make&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cmake&#34; data-lang=&#34;cmake&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cmake_minimum_required&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;VERSION&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;3.22&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;FATAL_ERROR&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;project&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;VERSION&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;1.0&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;add_definitions&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;-std=c++17&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;CXX_FLAGS&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-Wall&amp;#34;&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;CMAKE_CXX_FLAGS,&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;${CXX_FLAGS}&amp;#34;&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;CMAKE_BUILD_TYPE&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;Debug&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;add_executable&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myapp&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;main.cpp&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;find_package&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;glfw3&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;3.4&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;REQUIRED&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;find_package&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;OpenGL&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;REQUIRED&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;target_include_directories&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;PUBLIC&lt;/span&gt; ${&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;OPENGL_INCLUDE_DIR&lt;/span&gt;})&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;target_link_libraries&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-framework Cocoa&amp;#34;&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;target_link_libraries&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-framework OpenGL&amp;#34;&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;target_link_libraries&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-framework IOKit&amp;#34;&lt;/span&gt;)&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;target_link_libraries&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;myproject&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;glfw&lt;/span&gt; ${&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;OPENGL_gl_LIBRARY&lt;/span&gt;})&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, &lt;code&gt;cmake . &amp;amp;&amp;amp; make&lt;/code&gt; will produce a binary called &lt;code&gt;myapp&lt;/code&gt;, which displays the same black window than before.&lt;br&gt;
Nice!&lt;/p&gt;
&lt;p&gt;This setup will simplify a lot of things later, especially for conditional builds and testing (because, yes, we can execute some tests using &lt;code&gt;cmake&lt;/code&gt;).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-shaders&#34;&gt;
  The shaders
  &lt;a class=&#34;anchor&#34; href=&#34;#the-shaders&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I will use specific features of C++17, like &lt;code&gt;optional&lt;/code&gt;, in order to improve the code and avoid to throw errors / exceptions everywhere&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* shader_utils.h */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#ifndef _SHADER_UTILS_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define _SHADER_UTILS_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;namespace&lt;/span&gt; ShaderUtils
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        FRAGMENT_SHADER_TYPE,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VERTEX_SHADER_TYPE,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;private&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief The vertex shader ID, as an optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::optional&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;&amp;gt; vertexShader = std::nullopt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief The fragment shader ID, as an optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::optional&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;&amp;gt; fragmentShader = std::nullopt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief The GPU program ID (or shader ID), as an optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::optional&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;&amp;gt; program = std::nullopt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Stores if the shader has been registered or not
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; registered = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;public&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Constructor
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Program();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Destructor
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ~Program();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Register a shader
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @param shader_type The type: fragment or vertex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @param shader_source The source code as a string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @return true The shader has been successfully registered
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @return false The shader has not been registered - error is logged
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;registerShader&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; Type shader_type, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; *shader_source);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Register the GPU program (or shader), after compilation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * of the fragment and vertex shaders.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @return true The shader has been successfully registered
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @return false The shader has not been successfully registered - error is logged
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;registerProgram&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Returns the GPU program ID object, as optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @return std::optional&amp;lt;unsigned int&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std::optional&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;&amp;gt; getProgram() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         * @brief Returns if the GPU program object has been registered or not
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;         */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;programIsRegistered&lt;/span&gt;() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif &lt;/span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* SHADER_UTILS_H */&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the implementation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* shader_utils.cpp */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#ifdef __APPLE__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* Defined before OpenGL and GLUT includes to avoid deprecation messages */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define GL_SILENCE_DEPRECATION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;#34;logs.h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Simple macros for DEBUG, INFO, ... messages
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;#34;shader_utils.h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ShaderUtils::Program::Program() {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ShaderUtils::Program::~Program()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (vertexShader.has_value())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glDeleteShader(vertexShader.value());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (vertexShader.has_value())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glDeleteShader(fragmentShader.value());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (registered &amp;amp;&amp;amp; program.has_value())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glDeleteProgram(program.value());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; ShaderUtils::Program::registerShader(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; ShaderUtils::Type shader_type, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; *shader_source)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; success = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; errorMessage[1024] = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; isFragmentShader = shader_type == ShaderUtils::Type::FRAGMENT_SHADER_TYPE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;auto&lt;/span&gt; real_shader_type = !isFragmentShader ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;auto&lt;/span&gt; shader = glCreateShader(real_shader_type);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Now, pass the shaders
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glShaderSource(shader, 1, &amp;amp;shader_source, &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;NULL&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// And now, compile them
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glCompileShader(shader);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glGetShaderiv(shader, GL_COMPILE_STATUS, &amp;amp;success);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!success)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glGetShaderInfoLog(shader, 1024, &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;NULL&lt;/span&gt;, errorMessage);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (isFragmentShader) { error(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Fragment shader compilation error : &amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; errorMessage); }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;else&lt;/span&gt; { error(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Vertex shader compilation error : &amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; errorMessage); }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (isFragmentShader) { fragmentShader = shader; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;else&lt;/span&gt; { vertexShader = shader; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; ShaderUtils::Program::registerProgram()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (registered)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        error(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;program is already registered&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!vertexShader.has_value() || !fragmentShader.has_value())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        error(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;cannot compile program without vertex and fragment shaders&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; success = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; errorMessage[1024] = {};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; vertexShaderValue = vertexShader.value();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; fragmentShaderValue = fragmentShader.value();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    program = glCreateProgram();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; programValue = program.value();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glAttachShader(programValue, vertexShaderValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glAttachShader(programValue, fragmentShaderValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glLinkProgram(programValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glGetProgramiv(programValue, GL_LINK_STATUS, &amp;amp;success);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!success)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glGetProgramInfoLog(programValue, 1024, &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;NULL&lt;/span&gt;, errorMessage);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        error(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Shader linking error: &amp;#34;&lt;/span&gt; &amp;lt;&amp;lt; errorMessage);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// We can now delete our vertex and fragment shaders
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glDeleteShader(vertexShaderValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glDeleteShader(fragmentShaderValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glUseProgram(programValue);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    registered = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;std::optional&amp;lt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;&amp;gt; ShaderUtils::Program::getProgram() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; program;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;bool&lt;/span&gt; ShaderUtils::Program::programIsRegistered() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; registered;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using those helpers, our shaders registration take a few lines of code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// in main.cpp, just before the `while` loop
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;auto&lt;/span&gt; shader_utils = ShaderUtils::Program{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!shader_utils.registerShader(ShaderUtils::Type::VERTEX_SHADER_TYPE, basicVertexShaderSource))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!shader_utils.registerShader(ShaderUtils::Type::FRAGMENT_SHADER_TYPE, basicFragmentShaderSource))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; (!shader_utils.registerProgram())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; -1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As our current target is the basic RGB triangle, our shaders are very simple.&lt;/p&gt;
&lt;p&gt;For the vertex shader source:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-vert&#34; data-lang=&#34;vert&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#version 410 core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;layout (location = 0) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec3&lt;/span&gt; vertexPosition;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;layout (location = 1) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec3&lt;/span&gt; vertexColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;layout (location = 0) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;out&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec3&lt;/span&gt; fragmentColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; main() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gl_Position = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec4&lt;/span&gt;(vertexPosition, 1.0); &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// `w` is used for perspective&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fragmentColor = vertexColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;, and the fragment shader source:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-frag&#34; data-lang=&#34;frag&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#version 410 core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;layout (location = 0) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec3&lt;/span&gt; fragmentColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;out&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec4&lt;/span&gt; finalColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; main() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    finalColor = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;vec4&lt;/span&gt;(fragmentColor, 1.0);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For this, you can easily write down those shaders in dedicated files, and load them interactively via the command line.&lt;br&gt;
For this exercise, I am writing those shaders down into two dedicated strings, and use them non-interactively:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; *basicVertexShaderSource = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#version 410 core&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;layout (location = 0) in vec3 vertexPosition;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;layout (location = 1) in vec3 vertexColor;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;layout (location = 0) out vec3 fragmentColor;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;void main()&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;{&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;    gl_Position = vec4(vertexPosition, 1.0);&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// `w` is used for perspective
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;    fragmentColor = vertexColor;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;}&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\0&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;char&lt;/span&gt; *basicFragmentShaderSource = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#version 410 core&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;layout (location = 0) in vec3 fragmentColor;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;out vec4 finalColor;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;void main()&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;{&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;    finalColor = vec4(fragmentColor, 1.0);&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;}&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\0&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=&#34;heading&#34; id=&#34;a-story-about-vertices&#34;&gt;
  A story about vertices&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#a-story-about-vertices&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We have our main program, we have our shaders&amp;hellip; now, let&amp;rsquo;s draw the famous triangle!&lt;/p&gt;
&lt;p&gt;The array will contains 6 elements, with the following labels &lt;code&gt;x, y, z, r, g, b&lt;/code&gt;.&lt;br&gt;
The offset for a position will be &lt;code&gt;0&lt;/code&gt;, and the offset for a color will be &lt;code&gt;3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I wrote down the basic specification in a specific library component:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// in maths_utils.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#ifndef _MATHS_UTILS_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#define _MATHS_UTILS_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;namespace&lt;/span&gt; MathsUtils
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; VERTEX_ELEMENTS_NB = 6;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @brief Reassemble all elements of a vertex in a dedicated type
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * Contains, in the following order: x, y, z (position, in 3D), r, g, b (RGB colors)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt; vertex[VERTEX_ELEMENTS_NB];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ... &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Some uninteresting functions for this exercise
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @brief Returns the number of individual vertex arrays inside a vertices array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @param vertices - an array of vertex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @return The number of the individual vertex arrays
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; getNbVertex(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; vertex vertices[]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @brief Sums and returns the number of individual elements stored in the vertices array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @param vertices - an array of vertex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     * @return The sum of all individual elements stored in the vertices array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getNbElements&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; vertex vertices[]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#endif &lt;/span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* _MATHS_UTILS_H */&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The implementation is straightforward:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// in maths_utils.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;#34;maths_utils.h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; MathsUtils::getNbVertex(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; MathsUtils::vertex vertices[])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;)(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(*vertices) / MathsUtils::VERTEX_ELEMENTS_NB);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; MathsUtils::getNbElements(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;const&lt;/span&gt; MathsUtils::vertex vertices[])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; MathsUtils::getNbVertex(vertices) * VERTEX_ELEMENTS_NB;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, we end with the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Specify position attribute - 0 as offset
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, MathsUtils::VERTEX_ELEMENTS_NB * &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;), (GLvoid *)0);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glEnableVertexAttribArray(0);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Specify color attribute - 3 as offset
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, MathsUtils::VERTEX_ELEMENTS_NB * &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;), (GLvoid *)(3 * &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;float&lt;/span&gt;)));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glEnableVertexAttribArray(1);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glBindBuffer(GL_ARRAY_BUFFER, 0);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we have to explicit say that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we want to use the GPU program,&lt;/li&gt;
&lt;li&gt;bind the vertex array,&lt;/li&gt;
&lt;li&gt;and draw the triangle.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the while loop, we could just write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;while&lt;/span&gt; (!glfwWindowShouldClose(window))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Render
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glClearColor(0.5, 0.5, 0.5, 1.0);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glClear(GL_COLOR_BUFFER_BIT);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glUseProgram(shader_utils.getProgram().value());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glBindVertexArray(VAO);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glDrawArrays(GL_TRIANGLES, 0, 3);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Poll for and process events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwPollEvents();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Swap front and back buffers
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwSwapBuffers(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and, do not forget the delete the buffer right after:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glDeleteBuffers(1, &amp;amp;VBO);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glDeleteVertexArrays(1, &amp;amp;VAO);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, hit &lt;code&gt;cmake . &amp;amp;&amp;amp; make&lt;/code&gt;, launch the program and&amp;hellip; tadaaaa!&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/rgb_opengl_triangle_m1.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; An RGB triangle, built with OpenGL 4.1 on a macbook air m1 &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The full code is available at: &lt;a href=&#34;https://github.com/k0pernicus/opengl-explorer&#34;&gt;https://github.com/k0pernicus/opengl-explorer&lt;/a&gt;, commit &lt;code&gt;0e311828fb34b272809432254307e8561e951335&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/k0pernicus/opengl-explorer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cd&lt;/span&gt; opengl-explorer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git checkout -b rgb_triangle 0e311828fb34b272809432254307e8561e951335
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The m1 mac is an awesome machine, but lacks of continuity for OpenGL (especially as OpenGL 4.5 &amp;gt;= introduces a lot of new exciting features that make the code less verbose).&lt;br&gt;
As OpenGL 4.1 is still robust and, as Apple did not completely removed OpenGL from the stack, it is still interesting to draw things with OpenGL.&lt;br&gt;
&lt;strong&gt;However&lt;/strong&gt; Vulkan may be interesting at this point for further / longer multiplatform compatibility (despites its complexity).&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know if I will continue on this kind of exercises, and go further on trasnformations for example&amp;hellip; but do not hesitate to give me some feedbacks (by emails) if you want to know more about X or Y.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>macOS hidden features</title>
      <link>https://carette.xyz/posts/macos_cmdline_hidden_features/</link>
      <pubDate>Sat, 20 Mar 2021 12:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/macos_cmdline_hidden_features/</guid>
      <description>&lt;p&gt;I just discovered a very good dotfiles that contains a lot of hidden features in macOS, or to manage you system through the console.&lt;br&gt;
Please check it out &lt;a href=&#34;https://github.com/mathiasbynens/dotfiles/blob/master/.macos&#34;&gt;here&lt;/a&gt; if you are interested in.
Thanks to &lt;a href=&#34;https://github.com/mathiasbynens&#34;&gt;Mathias Bynens&lt;/a&gt; for this!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Conditional compilation and optin dependencies with Rust &#39;features&#39;</title>
      <link>https://carette.xyz/posts/rust_features/</link>
      <pubDate>Fri, 12 Mar 2021 00:45:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/rust_features/</guid>
      <description>&lt;p&gt;I am a long time Rust user/fan - since 2014 - and I still have some troubles to follow the community in terms of RFCs, or accepted features to be included in an upcoming version of the language.
Most of the time, checking for the new features, I have the feeling that I don&amp;rsquo;t need to use them for my current &amp;amp; past projects&amp;hellip; like a purist C / C++ developer who uses the strict minimum of the features to make something great.&lt;br&gt;
And sometimes I am wrong.&lt;/p&gt;
&lt;p&gt;I am working on a game engine since a while now - a Wolfenstein3D-like engine, with the goal to run Wolfenstein 3D on it and develop new mods for it &amp;ldquo;easily&amp;rdquo;.&lt;br&gt;
I had to postpone the work since a while now and I recently rewrote (almost) everything from scratch after dumb mistakes, as I did not understood how a game engine is working, and more and more difficulties to introduce some new features in the project&amp;hellip; like &lt;strong&gt;&lt;em&gt;cross-platforms compatibility&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
To introduce this feature, we need to make feasible the usage of multiple OS specific low-level libraries (sound, graphics, etc&amp;hellip;), which means different API usage, different API implementation, most of the time incompatible with each other&amp;hellip; in the &lt;strong&gt;same&lt;/strong&gt; common piece of code.&lt;br&gt;
So, we need an &lt;strong&gt;API&lt;/strong&gt;, or interface, that can communicate with different backends (let&amp;rsquo;s call them &lt;strong&gt;packages&lt;/strong&gt;), based on the operating system platform - so, chosen before / during the compilation of the engine.&lt;/p&gt;
&lt;p&gt;Rust proposes since the beginning some specific features for conditional compilation options (like the &lt;code&gt;cfg&lt;/code&gt; attributes), but since the 1.18 they introduced a more powerful feature called &lt;code&gt;features&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The repository that contains the demonstration is &lt;a href=&#34;https://github.com/k0pernicus/rust-features-example&#34;&gt;available here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-problem&#34;&gt;
  The problem
  &lt;a class=&#34;anchor&#34; href=&#34;#the-problem&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I have an awesome game called &amp;ldquo;guess a number&amp;rdquo;, a textual game written fully in English, and I want to make it accessible for the International: French guys, Spanish, Italian, Greek, etc&amp;hellip;&lt;br&gt;
More important, I want this game to be translated by &lt;strong&gt;anyone&lt;/strong&gt;, based on the original English texts only&amp;hellip;&lt;/p&gt;
&lt;p&gt;So solution to this could be to make my game public, and let people contribute in including their own i18n &lt;strong&gt;Rust module&lt;/strong&gt;, write a menu to let the user choose the language, etc&amp;hellip;&lt;br&gt;
But I don&amp;rsquo;t like this solution is that my game is &lt;strong&gt;very&lt;/strong&gt; small (90 lines of code, including comments and many many blank lines), and I don&amp;rsquo;t want to compile the game with &lt;strong&gt;all&lt;/strong&gt; the languages into it, or let the user choose the language on runtime.&lt;br&gt;
I want the game to be &lt;strong&gt;included&lt;/strong&gt; with the user&amp;rsquo;s prefered language &lt;strong&gt;only&lt;/strong&gt;: included at compile time.&lt;/p&gt;
&lt;p&gt;This is where Rust &lt;code&gt;features&lt;/code&gt; comes in.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-brief-introduction&#34;&gt;
  A brief introduction
  &lt;a class=&#34;anchor&#34; href=&#34;#a-brief-introduction&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Rust &lt;code&gt;features&lt;/code&gt; allows &lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/features.html&#34;&gt;to include, at compile time, packages as optional dependencies, or a set of other features&lt;/a&gt;.&lt;br&gt;
And this is perfect for our usage, because I want to propose as many builds as available translations (including English).&lt;/p&gt;
&lt;p&gt;To do this, in &lt;a href=&#34;https://github.com/k0pernicus/rust-features-example&#34;&gt;our example&lt;/a&gt;, we need first to declare our different linguistic packages (or features):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[dependencies.english-linguistic-pkg]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;optional = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;default-features = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;path = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;english-linguistic-pkg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[dependencies.french-linguistic-pkg]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;optional = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;default-features = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;path = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;french-linguistic-pkg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[features]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;english = [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;english-linguistic-pkg&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;french = [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;french-linguistic-pkg&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A feature &lt;strong&gt;is&lt;/strong&gt; a dependency - so you need to declare it anyway in the Cargo.toml file, even if you don&amp;rsquo;t want to use it &lt;strong&gt;by default&lt;/strong&gt; in your final build.
Here, we define two different dependencies: &lt;code&gt;english-linguistic-pkg&lt;/code&gt; for English, and &lt;code&gt;french-linguistic-pkg&lt;/code&gt; for French.
We need to declare those as &lt;strong&gt;features&lt;/strong&gt;, in the &lt;code&gt;[features]&lt;/code&gt; section.&lt;br&gt;
For simplicity, we create an alias for each of those: &lt;code&gt;english&lt;/code&gt; and &lt;code&gt;french&lt;/code&gt;, in order to simplify the declaration of which language package to use.&lt;br&gt;
As an example, you could use&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build --feature english
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;instead of&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build --features english-linguistic-pkg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, I included both dependencies in the game crate.
Of course, those packages could be available in a dedicated repository, and fetch directly using an URL&amp;hellip;&lt;/p&gt;
&lt;p&gt;A benefit of using &lt;code&gt;features&lt;/code&gt; is to use configuration conditional check to use the choosen package in the &lt;strong&gt;same namespace&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// in main.rs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[cfg(feature = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;english&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;use&lt;/span&gt; english_linguistic_pkg &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; i18n;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[cfg(feature = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;french&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;use&lt;/span&gt; french_linguistic_pkg &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; i18n;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using configuration conditional checks, &lt;code&gt;i18n&lt;/code&gt; is a namespace that can be linked to &lt;code&gt;english_linguistic_pkg&lt;/code&gt; or &lt;code&gt;french_linguistic_pkg&lt;/code&gt;.
This means, obviously, that both &lt;code&gt;english_linguistic_pkg&lt;/code&gt; and &lt;code&gt;french_linguistic_pkg&lt;/code&gt; must share the &lt;strong&gt;exact&lt;/strong&gt; same contracts.&lt;/p&gt;
&lt;p&gt;So, &lt;code&gt;print_message(i18n::SAY_HELLO)&lt;/code&gt; can print &amp;ldquo;hello&amp;rdquo; if the English package has been selected, or &amp;ldquo;bonjour&amp;rdquo; if the French one has been chosen instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One namespace to rule them all!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;lets-build&#34;&gt;
  Let&amp;rsquo;s build!
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-build&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ok, it&amp;rsquo;s time to build our game!&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;cargo build&lt;/code&gt;, the panics:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0433]: failed to resolve: use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:46:27
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;46 |             print_message(i18n::INVALID_INPUT, None);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |                           ^^^^ use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0433]: failed to resolve: use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:66:23
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;66 |         print_message(i18n::GUESS_A_NUMBER, Some(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |                       ^^^^ use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0433]: failed to resolve: use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:69:48
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;69 |             Ordering::Equal =&amp;gt; { print_message(i18n::PREDICTION_WIN, None); break; },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   |                                                ^^^^ use of undeclared crate or module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Oops!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;i18n&lt;/code&gt; has not been found because&amp;hellip; we forgot to &lt;em&gt;link&lt;/em&gt; the linguistic package we want to build with!&lt;/p&gt;
&lt;p&gt;Using the following command, we give the information to &lt;code&gt;cargo&lt;/code&gt; that we want to include the English package with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; cargo build --features english
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Compiling rust-features-example v0.1.0 (/Users/antonin/Devel/rust-features-example)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.69s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Wouhou, it works!&lt;/p&gt;
&lt;p&gt;How about the French one?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; cargo build --features french
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Compiling rust-features-example v0.1.0 (/Users/antonin/Devel/rust-features-example)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.67s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=&#34;heading&#34; id=&#34;the-default-features-key&#34;&gt;
  The &amp;lsquo;default&amp;rsquo; features key
  &lt;a class=&#34;anchor&#34; href=&#34;#the-default-features-key&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s come back to the first error: &lt;code&gt;use of undeclared crate or module i18n&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is possible to solve this issue setting a &lt;strong&gt;default&lt;/strong&gt; package to use.
We can do that configuring the &lt;code&gt;default&lt;/code&gt; key to the linguistic package we want to use &lt;strong&gt;by default&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[features]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;default = [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;english&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s try to build the project, without specifying explicitly any package:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Compiling rust-features-example v0.1.0 (/Users/antonin/Devel/rust-features-example)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.29s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yes! It finally works!&lt;br&gt;
How about the French one now?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0252]: the name &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt; is defined multiple &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;times&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; --&amp;gt; src/main.rs:4:9
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 | pub use english_linguistic_pkg as i18n;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |         ------------------------------ previous import of the module &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt; here
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 | &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;#[cfg(feature = &amp;#34;french&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 | pub use french_linguistic_pkg as i18n;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt; reimported here
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  = note: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;i18n&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt; must be defined only once in the &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;type&lt;/span&gt; namespace of this module
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;help: you can use &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt;as&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&lt;/span&gt; to change the binding name of the import
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 | pub use french_linguistic_pkg as other_i18n;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Outch!
This is rude&amp;hellip;&lt;/p&gt;
&lt;p&gt;Looking at the error message, we understand that both English and French packages may be included in the final build.
The solution is simple, as we just have to set to disable the default feature(s):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo run --no-default-features --features french
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After some thoughts, it comes to my mind that putting English as a &lt;code&gt;default&lt;/code&gt; feature is not intuitive, especially if you will have to deal with &lt;code&gt;cargo&lt;/code&gt; to build binaries with other linguistic packages&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;advantages-and-disadvantages&#34;&gt;
  Advantages and disadvantages
  &lt;a class=&#34;anchor&#34; href=&#34;#advantages-and-disadvantages&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As always in every language, a feature always comes with advantages and disadvantages&amp;hellip;&lt;/p&gt;
&lt;p&gt;I can notice several advantages here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;no multiple useless packages inside the binary, as used &lt;strong&gt;in compile time&lt;/strong&gt;, which can reduce the binary size,&lt;/li&gt;
&lt;li&gt;really easy to plug a new translation: just update the &lt;code&gt;Cargo.toml&lt;/code&gt; file, and include a conditional compilation option to use it in the project (in the main.rs, or lib.rs if you are working on a Rust library).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;About the disadvantages, the developer has to produce as many binaries as available translations, and that you will have to maintain multiple packages&amp;hellip; also, one modification in your English package and you have to ask to all to update their translation packages.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt; I would say that this feature miss some real examples in the rust doc, and &lt;a href=&#34;https://kevinlynagh.com/rust-zig/&#34;&gt;sometimes can be difficult to understand and to use for developers&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;references&#34;&gt;
  References:
  &lt;a class=&#34;anchor&#34; href=&#34;#references&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/features.html&#34;&gt;https://doc.rust-lang.org/cargo/reference/features.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Do you trust your FOSS?</title>
      <link>https://carette.xyz/posts/do-you-trust-your-foss/</link>
      <pubDate>Sat, 02 Jan 2021 16:07:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/do-you-trust-your-foss/</guid>
      <description>&lt;p&gt;People tend to believe that free and open source softwares (&lt;em&gt;FOSS&lt;/em&gt;) are &lt;strong&gt;way more trustable&lt;/strong&gt; than proprietary softwares&amp;hellip; and &lt;strong&gt;I want to believe this idea&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, the idea behind this blog post is that it is not because a software has a free or open source licence that someone already checked and validated its &lt;strong&gt;full&lt;/strong&gt; source code (including the dependencies)!&lt;br&gt;
As an example, how many times did you put a star on a github project without checking the code at 100%?
Doing this, you can unfortunately promote a vulnerable library, which could be shared to your github followers who can believe that, as you trusted this library enough to star it is &lt;strong&gt;obviously trustable&lt;/strong&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;This is a typical &lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Chain_of_trust&#34;&gt;chain of trust&lt;/a&gt;&lt;/strong&gt; problem.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-first-level-of-trust&#34;&gt;
  The first level of trust
  &lt;a class=&#34;anchor&#34; href=&#34;#the-first-level-of-trust&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To enable the confidence to a software, you have to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;trust the developer,&lt;/li&gt;
&lt;li&gt;check and validate the source code of the project,&lt;/li&gt;
&lt;li&gt;check and validate the dependencies of the project, and the dependencies of the dependencies, and so on&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is already a &lt;strong&gt;big&lt;/strong&gt; measure to be sure that the software you are installing on your computer can be trusted&amp;hellip; as a minimum level!&lt;br&gt;
Especially if you want to install a big FOSS project like emacs&amp;hellip; or even bigger: chromium or the linux kernel!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you don&amp;rsquo;t belive me about trusting your dependencies, please check this &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2020-7699&#34;&gt;NodeJS module CVE&lt;/a&gt; from 2020, which has been used seven million times.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s imagine here that you checked everything, and that everything is fine&amp;hellip;
The next step is to install the software on your machine.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-second-level-of-trust&#34;&gt;
  The second level of trust
  &lt;a class=&#34;anchor&#34; href=&#34;#the-second-level-of-trust&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The simplest solution to install a sofware on your system is&amp;hellip; to use a package manager.&lt;br&gt;
Using this, you will have to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;trust that the package manager is installing the right package in your system (comparing the hash for example&amp;hellip; if the hash function does not produce hash collisions!),&lt;/li&gt;
&lt;li&gt;check and validate that the software, available in your package manager server(s), corresponds to the build of the source code you checked right before,&lt;/li&gt;
&lt;li&gt;check and validate that the maintainer of this packet is also the developer and, if not, trust or not the maintainer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Outch&amp;hellip; this is becoming a more complex issue as you have to trust a lot of newcomers now&amp;hellip;&lt;br&gt;
So, let&amp;rsquo;s do like all Gentoo users: compile the software, wait for a few minutes / hours / days (if you want to install Chromium for example&amp;hellip;) and install it yourself!&lt;/p&gt;
&lt;p&gt;But the issue remains the same as the question now is: &amp;ldquo;&lt;strong&gt;can you fully trust your compiler?&lt;/strong&gt;&amp;rdquo; ;-)&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/nt0ASzS4O6A?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;A great presentation on how to introduce flaws into binaries via compiler extension(s)&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;People tend to think that a software is trustable (and secure) because its licence is GPL or MIT, which tends to be wrong, especially since a basic CLI can be a weird gigantic pile of dependencies&amp;hellip;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t get me wrong: I don&amp;rsquo;t say that free and open source softwares are bad, and I don&amp;rsquo;t believe to this idea!
On the contrary, I do think at 200% that FOSS are &lt;strong&gt;absolutely&lt;/strong&gt; a necessity for developers and end-users.&lt;br&gt;
I am grateful for FOSS and all people that work on their spare time to develop great tools, free to use, free to modify, and free to distribute.
Unfortunately, some persons are taking advantage of this wrong &amp;ldquo;trust situation&amp;rdquo; to introduce widely new flaws and vulnerabilities&amp;hellip;&lt;/p&gt;
&lt;p&gt;The battle of trusting your softwares is unfortunately not yet won.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Anyway, thanks Flash...</title>
      <link>https://carette.xyz/posts/anyway_thanks_flash/</link>
      <pubDate>Thu, 31 Dec 2020 21:20:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/anyway_thanks_flash/</guid>
      <description>&lt;p&gt;This is truly the end of some good indie games&amp;hellip; and a security threat.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Even with the effort to preserve flash projects, Flash on it&amp;#39;s own was a stepping stone for a lot of people, And it paved way for content creation on the internet pre-youtube days. &lt;br&gt;&lt;br&gt;Thanks Flash &lt;a href=&#34;https://t.co/iBRMvHHAIT&#34;&gt;pic.twitter.com/iBRMvHHAIT&lt;/a&gt;&lt;/p&gt;&amp;mdash; FABINO (@KinoFabino) &lt;a href=&#34;https://x.com/KinoFabino/status/1344723932243488770?ref_src=twsrc%5Etfw&#34;&gt;December 31, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


</description>
    </item>
    
    <item>
      <title>Know your threat model</title>
      <link>https://carette.xyz/posts/know_your_threat_model/</link>
      <pubDate>Thu, 31 Dec 2020 18:00:00 +0100</pubDate>
      <guid>https://carette.xyz/posts/know_your_threat_model/</guid>
      <description>&lt;p&gt;Last week, a &lt;a href=&#34;https://madaidans-insecurities.github.io/guides/linux-hardening.html&#34;&gt;very good blog post&lt;/a&gt; has been published about how Linux &lt;strong&gt;by default&lt;/strong&gt; is &amp;ldquo;not a secure operating system&amp;rdquo;&amp;hellip; (kernel actually).&lt;br&gt;
I agree with most of the ideas and methods explained in it, &lt;strong&gt;but&lt;/strong&gt; this article has a big issue: the target is absolutely not defined.
Unfortunately, this has been posted on hackernews (&lt;em&gt;oops&lt;/em&gt;) this morning (&lt;em&gt;iich&lt;/em&gt;) and, as expected (&lt;em&gt;ouuh&lt;/em&gt;), it has created a lot of comments and criticisms (&lt;em&gt;oh my&amp;hellip;&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;After a first read, you can think that Linux is absolutely &lt;strong&gt;not&lt;/strong&gt; a good / decent kernel, which is absolutely false!
Linux is an &lt;strong&gt;amazing&lt;/strong&gt; open-source kernel, built by thousands of amazing contributors all over the world, making a lot of efforts to make the kernel the most generalistic (it runs on various architectures), fast, and secure as possible.&lt;br&gt;
However, if you think that Linux is a secure kernel, you are &lt;strong&gt;wrong&lt;/strong&gt;, especially because of the first rule of computer security: &lt;strong&gt;absolutely no system is secure&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We all know that the most common GNU/Linux users are &lt;strong&gt;nerds&lt;/strong&gt;: people who love computers, test multiple (new) operating systems or softwares, and &lt;strong&gt;hack&lt;/strong&gt; most of the time&amp;hellip; or just people who think that Linux is &amp;ldquo;cool&amp;rdquo; and install it on their PC just &amp;ldquo;to feel like an&amp;rsquo;hacker, y&amp;rsquo;a know&amp;rdquo; (:facepalm:)&amp;hellip;&lt;/p&gt;
&lt;p&gt;When reading a blog post like this, which can be summarized as &amp;ldquo;a GNU/Linux distro is not secure &lt;em&gt;by default&lt;/em&gt;&amp;rdquo;, it resonates mostly for paranoid people and people who are scared about their &amp;ldquo;privacy&amp;rdquo;&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt; &lt;em&gt;don&amp;rsquo;t forget that &amp;ldquo;security&amp;rdquo; and &amp;ldquo;privacy&amp;rdquo; are not synonyms, and are not necessarily connected together. You can have a very secure OS where developers could fix all the bugs fast based on all your logs, which can be a privacy nightmare for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But first, I will explain the three different categories of persons who are using a GNU/Linux distribution today, and their specific threat model:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the students, the isolated nerds, the &amp;ldquo;random cool guys&amp;rdquo; in a small town somewhere or some random programmers all over the world, the /r/unixporn participants, etc. : you are &lt;strong&gt;not&lt;/strong&gt; the target of this article.&lt;br&gt;
Sorry to tell, but &lt;em&gt;&lt;strong&gt;nobody&lt;/strong&gt;&lt;/em&gt; is interested in knowing which kind of tools or vim themes you are using, what you ordered for your family recently at Christmas, or which porn&amp;rsquo;s categories you are interested in Pornhub.
Even Google, Facebook, or the NSA does not really care about you (except if you really did something unusual&amp;hellip;).&lt;br&gt;
You are just &lt;strong&gt;a number&lt;/strong&gt;, an ID inside a database column.
Nothing more.&lt;/li&gt;
&lt;li&gt;the company&amp;rsquo;s members, especially employees: people who want a minimum of security to avoid targeted hacks, which are &lt;strong&gt;not&lt;/strong&gt; making people lives in danger.&lt;br&gt;
Depending on what / where you are working, you &lt;strong&gt;can&lt;/strong&gt; be a potential target, and you can be interested in this article.
As always, if you work in a company, be careful about what you are clicking on, but mainly on social engineering techniques: sometimes, some people just need to make a phone call to get all the informations they want&amp;hellip;&lt;br&gt;
If you are in this specific category and don&amp;rsquo;t know how to start, please ask some advices to your IT department, or to do that for you.&lt;/li&gt;
&lt;li&gt;finally, the persons who are &lt;strong&gt;deeply&lt;/strong&gt; concerned about high security and privacy levels, like the journalists, (h)activists, whistleblowers, computer scientists who work in security and / or on critical systems, big companies like banks, and security agencies&amp;hellip;&lt;br&gt;
People whose lives (or other persons lives) may be in danger.&lt;br&gt;
For those, I think this blog article can be a good guide to make their life a bit less &amp;ldquo;paranoid&amp;rdquo;, and reduce at the same time the surface of attack of their device(s).&lt;br&gt;
For those persons, I include that some good tools like Qubes or Tor could be a game changer for them, in their daily life.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/authorization.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Comic from xkcd, &amp;lsquo;Authorization&amp;rsquo; (&lt;a href=&#34;https://xkcd.com/1200/&#34;&gt;https://xkcd.com/1200/&lt;/a&gt;) &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Whether you are part of the 1st, 2nd or 3rd category, even if you don&amp;rsquo;t use a GNU/Linux distribution but another OS like Windows or macOS, the following (&lt;em&gt;basic&lt;/em&gt;) rules can help you to manage your security:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;encrypt your data&lt;/strong&gt; - if you are tweaking your kernel but did not thought about encrypting your data&amp;hellip; oh boy&amp;hellip;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set a firewall&lt;/strong&gt; - put it to basic (no ssh by default, accept all that goes out),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;use a password manager&lt;/strong&gt; - some great tools like &lt;a href=&#34;https://bitwarden.com/&#34;&gt;Bitwarden&lt;/a&gt; are open source and can create strong passwords for your online accounts&amp;hellip; but please to create a strong password to open your password wallet!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;do not click on everything, everywhere&lt;/strong&gt;, and be careful about what you install on your kernel (just because &lt;em&gt;&amp;ldquo;RGB IS SO COOL ON MY KEYBOARD MAN!&amp;rdquo;&lt;/em&gt; does not means that you have to install a specific driver in your kernel space :/).&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>AlphaFold 2: a new AI achievement</title>
      <link>https://carette.xyz/posts/alphafold/</link>
      <pubDate>Thu, 03 Dec 2020 23:22:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/alphafold/</guid>
      <description>&lt;p&gt;The last 30th of November, &lt;a href=&#34;https://deepmind.com/&#34;&gt;DeepMind&lt;/a&gt; published on their website
&lt;a href=&#34;https://deepmind.com/blog/article/alphafold-a-solution-to-a-50-year-old-grand-challenge-in-biology&#34;&gt;an article about &lt;em&gt;AlphaFold&lt;/em&gt; 2&lt;/a&gt;,
an Artificial Intelligence that solves with 92.4 &lt;em&gt;GDT&lt;/em&gt;, on simple protein structure, a 50 years old grand challenge: the &lt;strong&gt;protein folding problem&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;DeepMind released the first version of &lt;em&gt;AlphaFold&lt;/em&gt; in 2018.&lt;br&gt;
This first version achieved a score of 58 in the Global Distance Test (&lt;em&gt;GDT&lt;/em&gt;) at the Critical Assessment of Structure Prediction (&lt;em&gt;CASP&lt;/em&gt;) competitions, which was the highest score at that time.&lt;br&gt;
For this occasion, an article &lt;a href=&#34;https://www.nature.com/articles/s41586-019-1923-7.epdf?author_access_token=Z_KaZKDqtKzbE7Wd5HtwI9RgN0jAjWel9jnR3ZoTv0MCcgAwHMgRx9mvLjNQdB2TlQQaa7l420UCtGo8vYQ39gg8lFWR9mAZtvsN_1PrccXfIbc6e-tGSgazNL_XdtQzn1PHfy21qdcxV7Pw-k3htw%3D%3D&#34;&gt;has been published on Nature&lt;/a&gt;, and the source code publicly available on &lt;a href=&#34;https://github.com/deepmind/deepmind-research/tree/master/alphafold_casp13&#34;&gt;Github&lt;/a&gt;.
With version 2, DeepMind&amp;rsquo;s dedicated team performed a median score of &lt;strong&gt;92.4&lt;/strong&gt; &lt;em&gt;GDT&lt;/em&gt; overall across all targets on the same competition dataset, and a median score of &lt;strong&gt;87.0&lt;/strong&gt; &lt;em&gt;GDT&lt;/em&gt; for the very hardest protein targets.&lt;br&gt;
Almost 30 more &lt;em&gt;GDT&lt;/em&gt; in two years, a &lt;em&gt;&lt;strong&gt;huge&lt;/strong&gt;&lt;/em&gt; improvement between those two years.&lt;/p&gt;
&lt;p&gt;In this blog post, I will decompose this breakthrough into several parts: talk about the protein folding problem, the competition and the achievements before &lt;em&gt;AlphaFold&lt;/em&gt;, and very quickly about both &lt;em&gt;AlphaFold&lt;/em&gt; 1 and 2.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;protein-folding-what&#34;&gt;
  Protein? Folding? What?
  &lt;a class=&#34;anchor&#34; href=&#34;#protein-folding-what&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A protein is a macromolecule (= &lt;strong&gt;big&lt;/strong&gt; molecule) that performs a vast array of functions within organisms,
from transporting molecules to DNA replication[1].&lt;br&gt;
In short: &lt;strong&gt;proteins are essential to life&lt;/strong&gt;.&lt;br&gt;
Like every other chain of molecules - a protein is composed by amino acids - two proteins are different by their content, or composition.&lt;br&gt;
However, something is specific and unique to a protein: &lt;strong&gt;its 3D structure&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;Indeed, a protein with the same amino acids than a second one have two different functions if their 3D structure (or their physical shape in space) vary, as
a shape can deliver, or hide, an activation section for every other molecule around in order to interact specifically with.&lt;br&gt;
Even &lt;a href=&#34;https://www.researchgate.net/post/Does_sequence_similarity_between_two_proteins_mean_structural_similarity&#34;&gt;if people are still fighting again on asking ourselves if we can simplify the sequence similarity measure between two proteins as a structural similarity&lt;/a&gt;, we will
assume that the 3D structure of a protein &lt;strong&gt;determines its own function&lt;/strong&gt; within an organism.&lt;/p&gt;
&lt;p&gt;The structure of a protein is, almost all the time, &lt;strong&gt;very&lt;/strong&gt; complex to understand, as it depends of four different levels of
complexity: hydrophobic interactions, hydrogen bonds, the Van der Waals forces between nearby amino acids,
and di-sulphide connections between cysteine molecules.&lt;/p&gt;
&lt;p&gt;To test all the possible folds of a protein using brute force methods is not possible then, as, based on the Levinthal&amp;rsquo;s paradox,
it could be more than &lt;strong&gt;10^143 ways&lt;/strong&gt; to fold a single protein, which is way more than playing chess (&lt;strong&gt;10^120&lt;/strong&gt;) but less than all
the possible moves in the game of Go (&lt;strong&gt;10^360&lt;/strong&gt;).&lt;br&gt;
Obviously, misfolding a protein has way more implications than making a wrong move in a Go game&amp;hellip;&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/3D_protein_structure.jpg#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Ribbon diagram of the 3D structure of hemoglobin - credits to Azom.com[2] &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Unfortunately, a protein can be modified, or &lt;strong&gt;misfold&lt;/strong&gt;, and lead to strong issues in the organism&amp;hellip;&lt;br&gt;
Indeed, an accumulation of misfolded proteins - proteins that contain at least one structure modifications -
can lead one or multiple disease(s), &lt;a href=&#34;https://www.nature.com/scitable/topicpage/protein-misfolding-and-degenerative-diseases-14434929/&#34;&gt;sometimes neurodegenerative like Alzheimer&amp;rsquo;s disease, or Huntington&amp;rsquo;s disease&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, reducing the problem of identifying a protein by its amino-acids sequence can help the scientists to design a specific protein
for a drug, or to understand how a modification, or mutation, in a protein can cause a specific disease.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;competitions-researches-and-results&#34;&gt;
  Competitions, researches and results
  &lt;a class=&#34;anchor&#34; href=&#34;#competitions-researches-and-results&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Every two years a community-wide worldwide experiment for protein structure prediction, called &lt;a href=&#34;https://en.wikipedia.org/wiki/CASP&#34;&gt;&lt;em&gt;CASP&lt;/em&gt;&lt;/a&gt;,
is launching global competitions to review the recent scientific researches and results on protein folding.
This review is done by computing the &lt;a href=&#34;https://en.wikipedia.org/wiki/Global_distance_test&#34;&gt;&lt;em&gt;GDT&lt;/em&gt;, or &lt;em&gt;G&lt;/em&gt;lobal &lt;em&gt;D&lt;/em&gt;istance &lt;em&gt;T&lt;/em&gt;est&lt;/a&gt; using a
complex dataset of 200 million of proteins.&lt;br&gt;
A &lt;em&gt;GDT&lt;/em&gt; is a measure of similarity &lt;strong&gt;between two protein structures with identical amino acid sequences and different shapes&lt;/strong&gt; - in short,
a prediction accuracy for proteins shape.&lt;br&gt;
Claimed by the Science community, the higher total score of &lt;em&gt;GDTs&lt;/em&gt;, the better a given model is in comparison to reference structure.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;CASP&lt;/em&gt; competitions for protein folding are performed since 1994, and new algorithms and results are evaluated
by this community every two years.&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/CASP_2020.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; CASP results, 30th November of 2020 - credits to DeepMind[3] &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-alphafold-breakthrough&#34;&gt;
  The AlphaFold breakthrough
  &lt;a class=&#34;anchor&#34; href=&#34;#the-alphafold-breakthrough&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;CASP&lt;/em&gt; 13, in 2018, has been won by the first version of &lt;em&gt;AlphaFold&lt;/em&gt;, with 58 &lt;em&gt;GDT&lt;/em&gt;, which was the highest score at this time.&lt;br&gt;
This year, &lt;em&gt;CASP&lt;/em&gt; 14 has been won by the second version of &lt;em&gt;AlphaFold&lt;/em&gt; with nearly 90 &lt;em&gt;GDT&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The secret of the second version of &lt;em&gt;AlphaFold&lt;/em&gt; is not known yet, but, as stated by Mirko Torrisi, Gianluca Pollastri, and Quan Le,
the secret of the first version is known as a distance map predictor, implemented as a very deep convolutional neural networks,
trained on more than 170_000 proteins by 200 GPUs.[4][5][6]&lt;/p&gt;
&lt;p&gt;&lt;em&gt;AlphaFold&lt;/em&gt; 1 has two steps in the process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a Convolutional Neural Network (&lt;a href=&#34;https://en.wikipedia.org/wiki/Convolutional_neural_network&#34;&gt;CNN&lt;/a&gt;), that takes&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;at least - as input the amino acids residue sequences, and output the distance metrics between the amino-acids in space,&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;a &lt;a href=&#34;https://en.wikipedia.org/wiki/Gradient_descent&#34;&gt;Gradient descent optimisation&lt;/a&gt; of folding the 3D structure to
match the distances between amino-acids in the protein.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/alphafold_1_struct.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; AlphaFold 1 architecture - credits to DeepMind[6] &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;As stated by the team of &lt;em&gt;AlphaFold&lt;/em&gt;, &lt;a href=&#34;https://fortune.com/2020/12/01/lessons-from-deepminds-a-i-breakthrough-eye-on-ai/&#34;&gt;the second version of the model may be &lt;strong&gt;significantly&lt;/strong&gt; different from the first one&lt;/a&gt;, as the first version has a (light) tendency of overfit the data.&lt;/p&gt;
&lt;p&gt;People tend to think that the second version replaced the CNNs with transformers, an &lt;a href=&#34;https://towardsdatascience.com/intuitive-understanding-of-attention-mechanism-in-deep-learning-6c9482aecf4f&#34;&gt;attention-based neural network&lt;/a&gt;, and speculate on more accurate feature engineering
of amino acids residue sequences.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;whats-next-&#34;&gt;
  What&amp;rsquo;s next ?
  &lt;a class=&#34;anchor&#34; href=&#34;#whats-next-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;In some sense the problem is solved.&amp;rdquo;
&lt;a href=&#34;https://www.nature.com/articles/d41586-020-03348-4&#34;&gt;John Moult&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;AlphaFold&lt;/em&gt; &lt;strong&gt;will&lt;/strong&gt; have implications for areas like drug design or treatments, biomaterials, environmental sustainability - like
designing enzymes to eat the plastic in our oceans - or agriculture.&lt;br&gt;
Indeed, &lt;em&gt;AlphaFold&lt;/em&gt; could be used to understand how protein structure can lead to specific diseases, how to identify proteins
that have malfunctioned, but also learn unknown functions of genes encoded in DNA.&lt;/p&gt;
&lt;p&gt;Both &lt;em&gt;AlphaFold&lt;/em&gt; versions are the work of incredible talented engineers and researchers at DeepMind, but also
of all the researchers who participated since the last fifty decades at least.&lt;br&gt;
So, congratulations to John Jumper, Richard Evans, Alexander Pritzel, Tim Green, Michael Figurnov,
Kathryn Tunyasuvunakool, Olaf Ronneberger, Russ Bates, Augustin Žídek, Alex Bridgland, Clemens Meyer, Simon A. A. Kohl,
Anna Potapenko, Andrew J. Ballard, Andrew Cowie, Bernardino Romera-Paredes, Stanislav Nikolov, Rishub Jain, Jonas Adler,
Trevor Back, Stig Petersen, David Reiman, Martin Steinegger, Michalina Pacholska, David Silver, Oriol Vinyals,
Andrew W Senior, Koray Kavukcuoglu, Pushmeet Kohli, Demis Hassabis, and all the other engineers and researchers
who have been involved in any way in this subject.&lt;/p&gt;
&lt;p&gt;As stated in their blog post, DeepMind is pretty optimistic about the impact &lt;em&gt;AlphaFold&lt;/em&gt; can have on the wider world&amp;hellip; I am too!&lt;br&gt;
To me, &lt;em&gt;AlphaFold&lt;/em&gt; is another proof that AI can be beneficial for humanity.&lt;/p&gt;
&lt;p&gt;Five years after &lt;a href=&#34;https://deepmind.com/research/case-studies/alphago-the-story-so-far&#34;&gt;Alphago&lt;/a&gt;, DeepMind just solved another
big challenge&amp;hellip; Who knows which big challenge DeepMind will solve in 2025!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;online-resources&#34;&gt;
  Online resources
  &lt;a class=&#34;anchor&#34; href=&#34;#online-resources&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;a href=&#34;https://en.wikipedia.org/wiki/Protein&#34;&gt;Wikipedia - Protein definition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;a href=&#34;https://www.azom.com/article.aspx?ArticleID=11177&#34;&gt;An introduction to proteins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;a href=&#34;https://deepmind.com/blog/article/alphafold-a-solution-to-a-50-year-old-grand-challenge-in-biology&#34;&gt;DeepMind - AlphaFold: a solution to a 50-year-old grand challenge in biology&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;a href=&#34;https://en.wikipedia.org/wiki/AlphaFold&#34;&gt;Wikipedia - AlphaFold&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5] &lt;a href=&#34;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7305407/&#34;&gt;Deep learning methods in protein structure prediction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[6] &lt;a href=&#34;https://deepmind.com/blog/article/AlphaFold-Using-AI-for-scientific-discovery&#34;&gt;DeepMind - AlphaFold: Using AI for scientific discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=KpedmJdrTpY&amp;amp;t=7s&#34;&gt;YouTube - Protein folding explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=W7wJDJ56c88&#34;&gt;YouTube - Alex Fridman about DeepMind AlphaFold&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=gg7WjuFs8F4&#34;&gt;YouTube - The making of a scientific breakthrough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Slow... for your safety!</title>
      <link>https://carette.xyz/posts/macos_big_fail/</link>
      <pubDate>Fri, 13 Nov 2020 17:30:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/macos_big_fail/</guid>
      <description>&lt;p&gt;&lt;strong&gt;EDIT (15th of November 2020)&lt;/strong&gt;&lt;br&gt;
I made a mistake in explaining that OCSP send in its request the hash binary, which is not correct, and I am sorry for that.&lt;br&gt;
Indeed, OCSP send out the hash of the app developer certificate, as explained &lt;a href=&#34;https://blog.jacopo.io/en/post/apple-ocsp/&#34;&gt;in this great blog post&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Apple released it&amp;rsquo;s new mac operating system update - macOS Big Sur - yesterday night, a version that introduces a new design, closer to the iOS / iPadOS interface, new security updates (goodbye hacky kernel extensions&amp;hellip;), new features &amp;amp; apps via Catalyst and&amp;hellip; an optimized version of macOS for Apple Silicon devices.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;first-the-hype&#34;&gt;
  First, the hype&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#first-the-hype&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The update night was a big &amp;ldquo;update party&amp;rdquo; for many people, as Big Sur is a trully big next step for the mac, and for its users.&lt;/p&gt;
&lt;p&gt;It &lt;strong&gt;was&lt;/strong&gt; a &amp;ldquo;big update party&amp;rdquo;, but not for the good reasons&amp;hellip;&lt;br&gt;
Indeed, in one single night, Apple demonstrated to everyone the main drawbacks of their &amp;ldquo;new security updates and protocols for macOS&amp;rdquo;, and it was bad, really bad.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;-then-the-outages&#34;&gt;
  &amp;hellip; then, the outages
  &lt;a class=&#34;anchor&#34; href=&#34;#-then-the-outages&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;At 7PM yesterday, Apple released Big Sur.&lt;br&gt;
People got the notification, shared the excitement, and &lt;del&gt;downloaded it&lt;/del&gt; tried to download it.&lt;/p&gt;
&lt;p&gt;The image size of Big Sur to download was &lt;strong&gt;12.1 GB&lt;/strong&gt;, which is &lt;strong&gt;4 GB more than the previous version of macOS&lt;/strong&gt;: Catalina.&lt;/p&gt;
&lt;p&gt;The image is huge, and I do think that, despite the latest precautions taken by Apple, the servers were not fully ready to handle the hype&amp;hellip; which leads to an outage, a worldwide fail, and a lot of good memes.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;It Just Works.™ &lt;a href=&#34;https://x.com/hashtag/Apple?src=hash&amp;amp;ref_src=twsrc%5Etfw&#34;&gt;#Apple&lt;/a&gt; &lt;a href=&#34;https://x.com/hashtag/macOS?src=hash&amp;amp;ref_src=twsrc%5Etfw&#34;&gt;#macOS&lt;/a&gt; &lt;a href=&#34;https://t.co/FTGzn7ZYBU&#34;&gt;pic.twitter.com/FTGzn7ZYBU&lt;/a&gt;&lt;/p&gt;&amp;mdash; ᴺᴼᵀ Jony Ive (@JonyIveParody) &lt;a href=&#34;https://x.com/JonyIveParody/status/1326999537790185473?ref_src=twsrc%5Etfw&#34;&gt;November 12, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;Then, the situation gotten worse and worse as Apple decided to release, during the outage, new beta versions of many tools and operating systems (iOS, watchOS, &amp;hellip;) for the developers.&lt;/p&gt;
&lt;p&gt;In parallel to this situation - and I don&amp;rsquo;t know exactly if the following issues were related to the Big Sur update - the Apple Developers app kept crashing all the time, Apple Card and Apple Pay were under outage also, iMessage stopped as well as Apple Plans APIs and big services for the developers&amp;hellip; and the final customers.&lt;br&gt;
And this, as a domino game, leads to another fail&amp;hellip;&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/macos_big_fail_system_status_apps.png&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Apple System Status during the outage, for apps and APIs [1] &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/macos_big_fail_system_status.png&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Apple System Status during the outage, for devs [1] &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;slow-by-design&#34;&gt;
  Slow by design
  &lt;a class=&#34;anchor&#34; href=&#34;#slow-by-design&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I stopped very quickly to try to download Big Sur, as many people all over the world were complaining about the situation, and decided to work on my own stuff&amp;hellip; but then, I noticed that opening apps like Firefox took me &lt;strong&gt;almost 20 seconds&lt;/strong&gt; on my latest Macbook Pro, as well as iTerm, VSCode, and many other dev apps (because, yes, I am writing code in my spare time - blame me!).&lt;br&gt;
I restarted the machine, and got the same issues.&lt;/p&gt;
&lt;p&gt;This was weird, but it became even weirder when I saw on Twitter that other developers have exactly the same issues, in the same time&amp;hellip;&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;🤔 FYI, seems to be something going on with super sluggish app launching right now. It doesn’t seem to be just us. We are looking into it! &lt;a href=&#34;https://t.co/RZduhcBwiX&#34;&gt;https://t.co/RZduhcBwiX&lt;/a&gt;&lt;/p&gt;&amp;mdash; Panic (@panic) &lt;a href=&#34;https://x.com/panic/status/1326991320519335936?ref_src=twsrc%5Etfw&#34;&gt;November 12, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;Then, suddenly, Jeff Johnson proposed this solution:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Hey Apple users:&lt;br&gt;&lt;br&gt;If you&amp;#39;re now experiencing hangs launching apps on the Mac, I figured out the problem using Little Snitch.&lt;br&gt;&lt;br&gt;It&amp;#39;s trustd connecting to &lt;a href=&#34;https://t.co/FzIGwbGRan&#34;&gt;https://t.co/FzIGwbGRan&lt;/a&gt;&lt;br&gt;&lt;br&gt;Denying that connection fixes it, because OCSP is a soft failure.&lt;br&gt;&lt;br&gt;(Disconnect internet also fixes.) &lt;a href=&#34;https://t.co/w9YciFltrb&#34;&gt;pic.twitter.com/w9YciFltrb&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jeff Johnson (@lapcatsoftware) &lt;a href=&#34;https://x.com/lapcatsoftware/status/1326990296412991489?ref_src=twsrc%5Etfw&#34;&gt;November 12, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;A lot of people reacted to this tweet as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Wait&amp;hellip; how a network request - that I did not send - can slow down all my tools on my local machine?!&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let me explain the magic behind &lt;code&gt;Gatekeeper&lt;/code&gt;&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;foryoursecurity&#34;&gt;
  #ForYourSecurity
  &lt;a class=&#34;anchor&#34; href=&#34;#foryoursecurity&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apple introduced in 2012 &lt;code&gt;Gatekeeper&lt;/code&gt;, a &amp;ldquo;security-first tool&amp;rdquo; to make sure that all the softwares you launch, on your mac, have been &lt;strong&gt;verified&lt;/strong&gt; by Apple itself, and do not contain any code intentionally designed to cause damage on user&amp;rsquo;s computer.&lt;br&gt;
&lt;code&gt;Gatekeeper&lt;/code&gt; has been recently updated (on macOS Sierra) to disallow the system to install software that have not been approved by Apple (downloaded from the App Store) &lt;em&gt;and&lt;/em&gt; unapproved by the user manually.
Because of this, each user has now to allow manually, in the system preferences, that he wants to run &lt;em&gt;this&lt;/em&gt; specific software on its own machine.&lt;/p&gt;
&lt;p&gt;But, to check if a given software has been validated or not by Apple, &lt;code&gt;Gatekeeper&lt;/code&gt; has to check the validity of the soft (&lt;del&gt;a simple hash of the binary&lt;/del&gt; a hash about the app developer certificate[2]) &lt;strong&gt;over the internet to Apple servers&lt;/strong&gt; after a given time you opened it at first (&lt;strong&gt;not each time&lt;/strong&gt; [2]).&lt;br&gt;
The service daemon is called &lt;code&gt;trustd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This means that if Apple servers are slow to answer, &lt;code&gt;Gatekeeper&lt;/code&gt; will block the opening of the software until it got a response&amp;hellip; which can take a while.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: yes, libc can make a phonecall!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Introduce security checks like this to the detriment of the consumer is &lt;strong&gt;ugly&lt;/strong&gt;, and the main decision that has been taken by a lot of developers yesterday, to run their software faster at that moment, was just to block the request from &lt;code&gt;trustd&lt;/code&gt; using some great firewall tools, like &lt;a href=&#34;https://objective-see.com/products/lulu.html&#34;&gt;&lt;code&gt;LuLu&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://www.obdev.at/products/littlesnitch/index.html&#34;&gt;&lt;code&gt;Little Snitch&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, this method will not work anymore on macOS Big Sur as &lt;code&gt;trustd&lt;/code&gt; can&amp;rsquo;t be block by users anymore.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;On Big Sur, trustd is in Apple&amp;#39;s &amp;quot;ContentFilterExclusionList&amp;quot; &lt;br&gt;....meaning firewalls can&amp;#39;t block it! 😭&lt;br&gt;&lt;br&gt;Welcome to the future? 😱 &lt;a href=&#34;https://t.co/8PkmWkcZDS&#34;&gt;https://t.co/8PkmWkcZDS&lt;/a&gt; &lt;a href=&#34;https://t.co/ypYxLRGULn&#34;&gt;pic.twitter.com/ypYxLRGULn&lt;/a&gt;&lt;/p&gt;&amp;mdash; Patrick Wardle (@patrickwardle) &lt;a href=&#34;https://x.com/patrickwardle/status/1327034191523975168?ref_src=twsrc%5Etfw&#34;&gt;November 12, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.x.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;h2 class=&#34;heading&#34; id=&#34;here-comes-the-sun&#34;&gt;
  &amp;ldquo;Here comes the sun&amp;hellip;&amp;rdquo;
  &lt;a class=&#34;anchor&#34; href=&#34;#here-comes-the-sun&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apple fixed &lt;strong&gt;all&lt;/strong&gt; of those issues in less than two hours, hopefully!&lt;br&gt;
I will not blame the company for the outages, the update fail, all of this&amp;hellip; but for the decision to maintain the disastrous architecture of &lt;code&gt;Gatekeeper&lt;/code&gt; to the detriment of the mac user.&lt;br&gt;
This needs to be change, but the update pointed by Patrick Wardle does not presume anything good on this side unfortunately&amp;hellip;&lt;/p&gt;
&lt;p&gt;[1] Screenshots to credit to &lt;a href=&#34;https://9to5mac.com&#34;&gt;9to5mac&lt;/a&gt; - got from this &lt;a href=&#34;https://9to5mac.com/2020/11/12/apple-widespread-outages-big-sur-downloads-catalina-imessage/&#34;&gt;9to5mac article&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a href=&#34;https://blog.jacopo.io/en/post/apple-ocsp/&#34;&gt;https://blog.jacopo.io/en/post/apple-ocsp/&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Macintoshgarden</title>
      <link>https://carette.xyz/posts/macintoshgarden/</link>
      <pubDate>Mon, 05 Oct 2020 20:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/macintoshgarden/</guid>
      <description>&lt;p&gt;if &amp;ldquo;macintoshgarden&amp;rdquo; doesn&amp;rsquo;t give you a smile on your face, I&amp;rsquo;m pretty sure you don&amp;rsquo;t know this site&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://macintoshgarden.org&#34;&gt;macintoshgarden&lt;/a&gt; is an abandonware archive dedicated to supporting the Macintosh computer platform, from the
&lt;a href=&#34;https://macintoshgarden.org/apps/think-c&#34;&gt;Symantec THINK C 5.0&lt;/a&gt; compiler, to &lt;a href=&#34;https://macintoshgarden.org/games/quake-ii&#34;&gt;Quake II&lt;/a&gt; and
&lt;a href=&#34;https://macintoshgarden.org/apps/snow-leopard-powerpc&#34;&gt;the original Snow Leopard build for PowerPC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This website is organized into different categories, according to the categories of softwares you are looking for
(&lt;a href=&#34;https://macintoshgarden.org/apps/development-tools&#34;&gt;development tools&lt;/a&gt;, &lt;a href=&#34;https://macintoshgarden.org/apps/utilities&#34;&gt;utilities&lt;/a&gt;,
&lt;a href=&#34;https://macintoshgarden.org/apps/visual-arts-graphics&#34;&gt;visual arts graphics&lt;/a&gt;, &lt;a href=&#34;https://macintoshgarden.org/games/all&#34;&gt;games&lt;/a&gt;, etc&amp;hellip;), or
the guide you are looking for, like &lt;a href=&#34;https://macintoshgarden.org/guides&#34;&gt;an introduction to emulation for Macintosh softwares&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you never heard about macintoshgarden but interested about, do not hesitate to take a look at this &amp;ldquo;gold mine&amp;rdquo;
of original (and great) Macintosh platform softwares.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Books recommendation (1/x)</title>
      <link>https://carette.xyz/posts/recommended_books_1/</link>
      <pubDate>Thu, 16 Jul 2020 00:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/recommended_books_1/</guid>
      <description>&lt;p&gt;In 2019, I read an average of three books a month, including comic books.&lt;/p&gt;
&lt;p&gt;Unfortunately, during the lockdown since March, it was difficult to read new interesting books, due to several reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;no new release;&lt;/li&gt;
&lt;li&gt;physical bookstores close their doors;&lt;/li&gt;
&lt;li&gt;people ordered a lot of books to avoid boredom, which has sharply reduced stocks (and the choice of books as well);&lt;/li&gt;
&lt;li&gt;parcel and mail delivery has been greatly impacted too, and delays have been extended from two days to one month.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This strange situation gave me the opportunity to read again some books I like(d), and to make a short list of books I recommend.&lt;/p&gt;
&lt;p&gt;All the books I recommend have a link to &lt;a href=&#34;https://www.goodreads.com&#34;&gt;goodreads&lt;/a&gt; if you want to learn more about a particular one.&lt;/p&gt;
&lt;p&gt;This is the first part of this recommendation list.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;cs-related-books&#34;&gt;
  CS related books
  &lt;a class=&#34;anchor&#34; href=&#34;#cs-related-books&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;hackers-heroes-of-the-computer-revolution-by-steven-levy&#34;&gt;
  &amp;ldquo;Hackers: Heroes of the Computer Revolution“, by Steven Levy
  &lt;a class=&#34;anchor&#34; href=&#34;#hackers-heroes-of-the-computer-revolution-by-steven-levy&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;First published in 1984, this book changed life of many IT people around the world.&lt;br&gt;
This book describes accurately what hackers look like from the 40&amp;rsquo;s to the 90&amp;rsquo;s, from isolated mainframe nerds to the computer revolution that changed our world forever, and the birth of the &amp;ldquo;hacker ethic&amp;rdquo; around the DEC PDP computer in MIT.&lt;br&gt;
An inspiring &amp;ldquo;documentary book&amp;rdquo; for all computer nerds.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/56829.Hackers&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;masters-of-doom-by-david-kushner&#34;&gt;
  &amp;ldquo;Masters of Doom&amp;rdquo;, by David Kushner
  &lt;a class=&#34;anchor&#34; href=&#34;#masters-of-doom-by-david-kushner&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;I consider John Carmack and John Romero as trully computer heroes.
From the first Keen to Quake, &lt;em&gt;&amp;ldquo;Masters of Doom&amp;rdquo;&lt;/em&gt; describes how those guys (and their friends / colleagues at IdSoftware) revolutionized the video game and computer industry in early 90&amp;rsquo;s.&lt;br&gt;
The book is well written, and full of great stories.&lt;br&gt;
Also, it is very interesting to read how they developed their hacker spirits via video games and computers, and how the previous book I mentioned (&lt;em&gt;&amp;ldquo;Hackers: Heroes of the Computer Revolution“&lt;/em&gt;) forged them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/222146.Masters_of_Doom&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;code-the-hidden-language-of-computer-hardware-and-software-by-charles-petzold&#34;&gt;
  &amp;ldquo;Code: The Hidden Language of Computer Hardware and Software&amp;rdquo;, by Charles Petzold
  &lt;a class=&#34;anchor&#34; href=&#34;#code-the-hidden-language-of-computer-hardware-and-software-by-charles-petzold&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Do you want to know &lt;strong&gt;everything&lt;/strong&gt; behind the scenes of computer hardware and software, from atoms to assembly language?
If yes, this is a book for you!&lt;br&gt;
I would say that this book can be an introduction to &lt;em&gt;&amp;ldquo;Hackers: Heroes of the Computer Revolution&amp;rdquo;&lt;/em&gt;, as it describes how Human was ingenious enough to manipulate language and invent new means of communicating with each other.&lt;br&gt;
A must read for curious people and hackers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/44882.Code&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;sciencefiction-books&#34;&gt;
  (Science)Fiction books
  &lt;a class=&#34;anchor&#34; href=&#34;#sciencefiction-books&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;neuromancer-by-william-gibson&#34;&gt;
  &amp;ldquo;Neuromancer&amp;rdquo;, by William Gibson
  &lt;a class=&#34;anchor&#34; href=&#34;#neuromancer-by-william-gibson&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;A science fiction masterpiece, written and released before the release of the first Macintosh in 1984, that exposes one of the most brilliant vision of the twentieth century.&lt;br&gt;
Just &amp;ldquo;Wow&amp;rdquo;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/6088007-neuromancer&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;the-millenium-trilogy-from-stieg-larsson&#34;&gt;
  The &amp;ldquo;Millenium&amp;rdquo; trilogy, from Stieg Larsson
  &lt;a class=&#34;anchor&#34; href=&#34;#the-millenium-trilogy-from-stieg-larsson&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;A brilliant trilogy with one of the most charismatic figures of the 21st century: Lisbeth Salander.&lt;br&gt;
From a complete description of Sweden in its sad moments to the striking psychology of its characters, the first trilogy exposes a crazy, gripping story about murders, hacking, and misogyny.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/2429135.The_Girl_with_the_Dragon_Tattoo&#34;&gt;#1 The Girl with the Dragon Tattoo - Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/5060378-the-girl-who-played-with-fire&#34;&gt;#2 The Girl who Played with Fire - Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/6892870-the-girl-who-kicked-the-hornet-s-nest&#34;&gt;#3 The Girl who kicked the Hornet&amp;rsquo;s Nest - Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;comic-books&#34;&gt;
  Comic books
  &lt;a class=&#34;anchor&#34; href=&#34;#comic-books&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;scott-pilgrim-by-bryan-lee-omalley&#34;&gt;
  &amp;ldquo;Scott Pilgrim&amp;rdquo;, by Bryan Lee O&amp;rsquo;Malley
  &lt;a class=&#34;anchor&#34; href=&#34;#scott-pilgrim-by-bryan-lee-omalley&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Fun, geeky, including a great love story.&lt;br&gt;
For all comic books / manga lovers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/8697402-scott-pilgrim-the-complete-series&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;v-for-vendetta-by-alan-moore&#34;&gt;
  &amp;ldquo;V for Vendetta&amp;rdquo;, by Alan Moore
  &lt;a class=&#34;anchor&#34; href=&#34;#v-for-vendetta-by-alan-moore&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Who said that comic books are apolitical&amp;hellip;?&lt;br&gt;
&lt;strong&gt;The&lt;/strong&gt; comic book for adults.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/5805.V_for_Vendetta&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;wizzywig-portrait-of-a-serial-hacker-by-ed-piskor&#34;&gt;
  &amp;ldquo;Wizzywig: Portrait of a Serial Hacker&amp;rdquo;, by Ed Piskor
  &lt;a class=&#34;anchor&#34; href=&#34;#wizzywig-portrait-of-a-serial-hacker-by-ed-piskor&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;From early blue-boxing and phone phreaking days to the Internet, this comic book relates the story of a computer hacker (Kevin Mitnick?) during the 80&amp;rsquo;s.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/13644998-wizzywig&#34;&gt;Goodreads link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The state of memory safety in Chromium</title>
      <link>https://carette.xyz/posts/memory_safety_chromium/</link>
      <pubDate>Sun, 24 May 2020 00:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/memory_safety_chromium/</guid>
      <description>&lt;p&gt;As &lt;a href=&#34;https://medium.com/tadaweb/security-by-design-a-brief-introduction-to-rust-378060e45038&#34;&gt;Microsoft last year&lt;/a&gt;, the Chromium project team, responsible for the Chromium browser (which is the base of many open source and proprietary projects like Chrome, Brave, or Visual Studio Code), released a blog post last week about &lt;a href=&#34;https://www.chromium.org/Home/chromium-security/memory-safety&#34;&gt;memory bugs in Chromium&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-analysis&#34;&gt;
  The analysis
  &lt;a class=&#34;anchor&#34; href=&#34;#the-analysis&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The analysis has been based on both past and present 912 high or critical severity security issues, since 2015.&lt;br&gt;
Based on those bugs, the observation is clear:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Chromium project finds that around 70% of our serious security bugs are memory safety problems.&lt;br&gt;
[&amp;hellip;] Around 70% of our high severity security bugs are memory unsafety problems (that is, mistakes with C/C++ pointers). Half of those are use-after-free bugs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/memory_bugs_chromium_chart.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Chart about memory bugs on Chromium, from Chromium Project team &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Despite the efforts of the project team to maintain &lt;em&gt;good&lt;/em&gt; security architecture in managing &lt;a href=&#34;https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md&#34;&gt;sandboxing&lt;/a&gt; and &lt;a href=&#34;https://www.chromium.org/Home/chromium-security/site-isolation&#34;&gt;site isolation&lt;/a&gt;, to let those heavy components manage and contain the severity of memory bugs has both limitations and resources cost.&lt;br&gt;
Also, even if those security components (or layers) stay necessary for daily usage, &lt;a href=&#34;https://googleprojectzero.blogspot.com/2020/02/escaping-chrome-sandbox-with-ridl.html&#34;&gt;this not enough to stop attackers and avoid attacks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Instead, as stated in the blog post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[&amp;hellip;]The cheapest way to maintain the advantage is to squash bugs at source instead of trying to contain them later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-different-solutions&#34;&gt;
  The different solutions
  &lt;a class=&#34;anchor&#34; href=&#34;#the-different-solutions&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As always in software projects, solutions (and decisions) come with a trade-off.&lt;br&gt;
Indeed, the team developed a plan to solve those issues, using two criterias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;time and resources costs needed to implement the improvement(s),&lt;/li&gt;
&lt;li&gt;the real benefit of those costs, &lt;em&gt;basically the number and the quality of those improvement(s)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/memory_bugs_chromium_plan.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Plan for next years memory bugs improvements for / in Chromium, from Chromium Project team &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;This spectrum reflects the different strategies offered by the team, from left to right:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;to keep their dev model in unsafe system programming languages (like C or C++) but to bring attention on memory safety first (spatial memory safety, custom C++ libraries, and moving to newer standards like &lt;a href=&#34;https://en.cppreference.com/w/cpp/17&#34;&gt;C++17&lt;/a&gt; or the next C++20);&lt;/li&gt;
&lt;li&gt;customize their needs using custom C++ dialects, and / or continue on their idea of using a &lt;a href=&#34;https://docs.google.com/document/d/1Cv2IcsiokkGc2K_5FBTDKekNzTn3iTEUyi9fDOud9wU/edit#heading=h.i5ibcxqde9h2&#34;&gt;C++ garbage collection library for Chromium&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;move to a safe system programming language (and ecosystem) like &lt;a href=&#34;https://developer.apple.com/swift/&#34;&gt;Swift&lt;/a&gt; or &lt;a href=&#34;https://www.rust-lang.org/&#34;&gt;Rust&lt;/a&gt;, to bind with C++ parts first before rewriting those.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This plan is not new, as &lt;a href=&#34;https://wiki.mozilla.org/Oxidation&#34;&gt;the Mozilla foundation already made experiments about switching from C++ to Rust since 2015&lt;/a&gt;).&lt;br&gt;
Indeed, to make the switch to another technology has a big cost in a project, because it implies both to limit new upcoming features and to give some time to developers to embrace a new technology that they may not be accustomed to use daily.
Also, the plan here is to have a long-term vision, and not switching again to another technology in five or ten years.&lt;/p&gt;
&lt;p&gt;In my opinion, to switch first to &amp;ldquo;modern C++&amp;rdquo; can be a good option &lt;strong&gt;for a short term solution&lt;/strong&gt;, but is &lt;a href=&#34;https://alexgaynor.net/2019/04/21/modern-c++-wont-save-us/&#34;&gt;may not be a great option to &amp;ldquo;save your ass&amp;rdquo; all the time&lt;/a&gt;.&lt;br&gt;
Rust of Swift are definitely game changers in tech since their first stable version release.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-go-further&#34;&gt;
  To go further
  &lt;a class=&#34;anchor&#34; href=&#34;#to-go-further&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;An excellent blog post from Mozilla about preventing developers about memory safety and memory bugs: &lt;a href=&#34;https://hacks.mozilla.org/2019/01/fearless-security-memory-safety/&#34;&gt;link to blog article&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;My article about security by design, in the &lt;a href=&#34;https://www.tadaweb.com&#34;&gt;Tadaweb&lt;/a&gt; blog: &lt;a href=&#34;https://medium.com/tadaweb/security-by-design-a-brief-introduction-to-rust-378060e45038&#34;&gt;link to blog article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Developers are not superheroes</title>
      <link>https://carette.xyz/posts/developers_not_superheroes/</link>
      <pubDate>Sat, 25 Apr 2020 19:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/developers_not_superheroes/</guid>
      <description>&lt;p&gt;There is a myth in IT.&lt;br&gt;
The myth of the &amp;ldquo;super code monkey&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;super code monkey&amp;rdquo; is an expert in everything, in every situation.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; does not introduce bugs when he writes code.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; sleeps at least eight hours every day.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; is young, has a social life, and practice sport each day to keep in shape.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; is an expert in Android and iOS apps development, he knows how to write excellent code in, at least, C, C++, and Java.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; studied Data Science in three weeks, and became an expert on Python, R, Matlab, Octave, and Julia in less than a month.&lt;br&gt;
The &amp;ldquo;super code monkey&amp;rdquo; has strong knowledge in Docker and Kubernetes, and masterized 10 different Javascript frameworks the last six months.&lt;/p&gt;
&lt;p&gt;But, as every myth&amp;hellip; the &amp;ldquo;super code monkey&amp;rdquo; does not exists!&lt;br&gt;
Except maybe in the “requirements&amp;quot; section of some IT recruitment companies&amp;hellip;&lt;/p&gt;
&lt;p&gt;In this blog post, let&amp;rsquo;s discuss about the sense of the word &amp;ldquo;expert&amp;rdquo; in Computer Science, softwares without bugs (&lt;em&gt;spoiler: it does not exists&lt;/em&gt;), and the
fatal comparison with known figures from an old era&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-is-an-expert-&#34;&gt;
  What is an &amp;ldquo;expert&amp;rdquo; ?
  &lt;a class=&#34;anchor&#34; href=&#34;#what-is-an-expert-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s define what I understand by &amp;ldquo;someone is &lt;em&gt;expert&lt;/em&gt; in&amp;hellip;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;You can be &amp;ldquo;good&amp;rdquo; at something, but you &lt;strong&gt;must&lt;/strong&gt; have a &lt;em&gt;professional&lt;/em&gt; experience to prove in order to be considered as an expert.
Also, you can&amp;rsquo;t speak about being an expert in a given subject without explaining the context you applied to it, and without maintaining a recurrent technological watch on the subject you are mastering.&lt;br&gt;
As an example, a data scientist can claims that he is a Python expert for Data Science, and he know really well how to use famous modules like Pandas, or Scikit-Learn. But, this is totally different for a network engineer, or for a software pentester!&lt;br&gt;
All three will be able to write very good Python code &lt;em&gt;associated to the context of the application&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Becoming an expert on subject or technology &lt;em&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/em&gt; depends strongly of two different criteria:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;your current experience to solve a problem in, or using, &lt;em&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/em&gt;,&lt;/li&gt;
&lt;li&gt;and the time you are ready to spend for this.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We all know that time is not something that you can &amp;ldquo;buy“.
Therefore, logically, multiplying many &amp;ldquo;little&amp;rdquo; experiences on many things will force you to increase the time to be &amp;ldquo;just good&amp;rdquo; at one simple task, and can discourage you more easily to become an expert in one task.&lt;/p&gt;
&lt;p&gt;As a personal opinion, I encourage people to become an expert on only one thing (based on a defined context, or subject), and just &amp;ldquo;good enough&amp;rdquo; in other subjects or technologies they are interested in.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;features-come-with-bugs&#34;&gt;
  Features come with bugs
  &lt;a class=&#34;anchor&#34; href=&#34;#features-come-with-bugs&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you look at big projects like the Linux kernel, or the Chromium browser, you can notice that those are not bugs free.&lt;br&gt;
As you might know, the management of those big projects introduces a hierarchy to validate new features, or bug fixes.
The final step of this hierarchy for every merge request (new feature or bug fix(es)) is validation (and merge the feature of the fix to the original code base), or rejection, &lt;strong&gt;after&lt;/strong&gt; pair reviewing.&lt;/p&gt;
&lt;p&gt;So, when you discuss about a bug in production, you imply that both the developer and the reviewer have their own responsability here, as they missed the bug before the deployment.&lt;/p&gt;
&lt;p&gt;Developers have to accept that &lt;strong&gt;features come with bugs&lt;/strong&gt;, and that the most trickiest ones are, sometimes, invisible to humans.&lt;/p&gt;
&lt;p&gt;Most of the time, &lt;strong&gt;a developer is not a quality assurance&lt;/strong&gt;.
But, some solutions exist to help developers and reviewers in finding easy and tricky bugs in code: code analyser, monkey testing, chaos engineering, or just &lt;a href=&#34;https://medium.com/tadaweb/security-by-design-a-brief-introduction-to-rust-378060e45038&#34;&gt;tech switching that proposes security by design&lt;/a&gt; if you are developing systems or features in critical projects.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;stop-to-compare-with-it-known-figures&#34;&gt;
  Stop to compare with IT known figures
  &lt;a class=&#34;anchor&#34; href=&#34;#stop-to-compare-with-it-known-figures&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In order to know how we perform in one task, we often feel the need to compare our work with another person.&lt;br&gt;
When developers do this, they tend to compare what they are spending most of their time on: their code, or the software project(s) quality and popularity they achieved, or they are working on.&lt;br&gt;
This comparison can exists with colleagues, but also with known IT figures.&lt;/p&gt;
&lt;p&gt;Those known figures are people who contributed actively to an important part of the IT history, and made a lot of efforts to build beautiful things we are still using today.&lt;br&gt;
For example, we can mention Ada Lovelace, Grace Hopper, Ken Thompson, Dennis Ritchie, Brian Kernighan, Margaret Heafield Hamilton, Steve Wozniak, Roberta Williams, Linus Torvalds, &amp;hellip; and many other persons, coming from different Computer Science subfields.&lt;br&gt;
Those persons are mainly considered as &amp;ldquo;rockstars&amp;rdquo; because &lt;strong&gt;they are considered as &amp;ldquo;modern“ computing pioneers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Indeed, in order to solve real problems, those persons had enough imagination to propose &lt;strong&gt;new&lt;/strong&gt; &amp;ldquo;standards&amp;rdquo; on low-level constraints: most of the time hardware configuration and the operating system used by users.&lt;/p&gt;
&lt;p&gt;The book &amp;ldquo;Masters of Doom&amp;rdquo;, from David Kushner, is a perfect example here. This book relates how two geniuses, John Carmack and John Romero, co-created (at least) two revolutionary games (&amp;ldquo;Doom&amp;rdquo; and &amp;ldquo;Quake&amp;rdquo;), which revolutionized computer graphics and game development.&lt;br&gt;
In &amp;ldquo;Masters of Doom&amp;rdquo;, you realize quickly that computers at this time were still in its infancy&amp;hellip; and that we cannot compare the work of those pioneers to the work of our engineers today.&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/em&gt;: &lt;em&gt;If you are more interested in game engines, I recommend you &amp;ldquo;Black Book: Wolfenstein 3D&amp;rdquo; and &amp;ldquo;Black Book: Doom&amp;rdquo; from Fabien Sanglard, who made incredible researchs to explain how they successfuly built from scratch those masterpieces.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today, software constraints are really different and, I would say, more complex.
Instead of building complex pieces of code on a unique hardware or software stack, most of the developers now are using different standards to ship every day &lt;strong&gt;very&lt;/strong&gt; complex piece of codes, on &lt;strong&gt;very&lt;/strong&gt; complex stacks, in &lt;strong&gt;different private versatile environments&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This implies today multiple technologies, and communities, to build one common thing using different tools.&lt;/p&gt;
&lt;p&gt;To break down an open door, developers tend to be more &amp;ldquo;users“ today than &amp;ldquo;programmers&amp;rdquo; in the past.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Even if developers try to save the world each day, they don&amp;rsquo;t have superpowers (and they are not machines either).&lt;/p&gt;
&lt;p&gt;If you are a developer, do not spend your time in trying to become real expert everywhere, everytime, on everything, it&amp;rsquo;s impossible.
Instead, you can try to be a real expert in only one thing more quickly, and just to be &amp;ldquo;good enough&amp;rdquo; in other fields or using other technologies.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Zero-cost abstractions in Rust</title>
      <link>https://carette.xyz/posts/zero_cost_abstraction/</link>
      <pubDate>Sat, 08 Feb 2020 23:10:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/zero_cost_abstraction/</guid>
      <description>&lt;p&gt;Last week, &lt;a href=&#34;https://idursun.com/&#34;&gt;Ibrahim Dursun&lt;/a&gt; published &lt;a href=&#34;https://idursun.com/posts/Rust_zero_cost_abstractions_in_action/&#34;&gt;an article about zero-cost abstractions in Rust&lt;/a&gt;.&lt;br&gt;
Unfortunately, except for a subpart of the article, this article did not reflect, in my own opinion, correctly what are zero-cost abstractions.&lt;/p&gt;
&lt;p&gt;Indeed, zero-cost abstractions, or &amp;ldquo;zero-overhead&amp;rdquo;, can be difficult to understand and to separate from other compiler optimizations, and can be easily misunderstood.&lt;/p&gt;
&lt;p&gt;In this blog article, I discuss about this specific feature, and give you an example of how Rust is using it to deliver optimized code of your abstracted projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: an excellent blog article &lt;a href=&#34;https://boats.gitlab.io/blog/post/zero-cost-abstractions/&#34;&gt;about zero-cost abstractions&lt;/a&gt; already exists, written by &lt;a href=&#34;https://boats.gitlab.io/blog/page/about/&#34;&gt;withoutboats&lt;/a&gt;, last year. My blog post can be an additional content to the article of withoutboats.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-are-zero-cost-abstractions&#34;&gt;
  What are zero-cost abstractions
  &lt;a class=&#34;anchor&#34; href=&#34;#what-are-zero-cost-abstractions&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When you are developing a project, and the project is becoming more and more complex, you generaly want to include abstractions in your code to make it easier to maintain and to customize, to add more features.
In this case, your last wish is that those abstractions penalize the performances of your program at runtime.&lt;/p&gt;
&lt;p&gt;So, as a software developer, you generaly want two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to design your project where code readibility and code management are more important than complex hand-writtened optimizations,&lt;/li&gt;
&lt;li&gt;still benefits of great software performances at runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Indeed, improving code readibility implies to limit code optimizations and memory overhead, which comes with indirect memory access that can cause performance issues at runtime.&lt;/p&gt;
&lt;p&gt;Zero-cost abstractions are coming from C++, and defined by Bjarne Stroustrup in &lt;a href=&#34;http://www.stroustrup.com/ETAPS-corrected-draft.pdf&#34;&gt;Foundations of C++&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In general, C++ implementations obey the zero-overhead principle: What you don&amp;rsquo;t use, you don&amp;rsquo;t pay for. And further: what you do use, you couldn&amp;rsquo;t hand code any better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To summarize what Bjarne Stroustrup said, using zero-cost abstractions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;you don&amp;rsquo;t pay the features you don&amp;rsquo;t use,&lt;/li&gt;
&lt;li&gt;the high levels APIs (or concepts) will compile to machine code as good as what you could get by writing more lower-level code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This means that most of the abstractions provided by the programming language (or it&amp;rsquo;s standard library) will not add any additional cost &lt;em&gt;&lt;strong&gt;at runtime&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In Rust, zero-cost abstractions is a core principle for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compile-time memory checks and &lt;strong&gt;static&lt;/strong&gt; garbage collection (&lt;em&gt;borrowing&lt;/em&gt; and &lt;em&gt;ownership&lt;/em&gt;) - as a reminder, Rust does not check and collect memory at runtime, but is tracking the lifetimes of your code entities at compile time, instead of using reference counting or gargage collection,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.Rust-lang.org/2015/05/11/traits.html&#34;&gt;traits&lt;/a&gt;, which is one of the most impressive feature to extend the types used by your Rust programs,&lt;/li&gt;
&lt;li&gt;generics,&lt;/li&gt;
&lt;li&gt;iterators,&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This can explain why &lt;a href=&#34;https://diesel.rs/&#34;&gt;Diesel&lt;/a&gt;, a famous Rust ORM, &lt;a href=&#34;https://www.reddit.com/r/Rust/comments/5hmya5/diesel_is_30_faster_than_Rustpostgres_in/&#34;&gt;was 30% faster than the raw postgres solution for Rust&lt;/a&gt;, using more abstractions.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;example&#34;&gt;
  Example
  &lt;a class=&#34;anchor&#34; href=&#34;#example&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s take a simple example to illustrate this feature.&lt;br&gt;
In this section, we will&amp;hellip; compute the sum of odd numbers.&lt;/p&gt;
&lt;p&gt;To solve this problem, we can write two functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-Rust&#34; data-lang=&#34;Rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sum_odd_numbers&lt;/span&gt;(n: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) -&amp;gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; acc = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;for&lt;/span&gt; element &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; 0.. {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; element &amp;gt;= n {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; element.is_odd() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            acc += element;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    acc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;, or&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-Rust&#34; data-lang=&#34;Rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sum_odd_numbers&lt;/span&gt;(n: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) -&amp;gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (0..)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .take_while(|element| element &amp;lt; &amp;amp;n)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .filter(|n| n.is_odd())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .fold(0, |sum, element| sum + element)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The second code sample borrows functional programming concepts to compute the sum, and is seems more &amp;ldquo;compact&amp;rdquo; (and easier to understand) than the first one.&lt;br&gt;
However, if we decompose this second sample, we can make wrong assumptions here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create an iterator that begins with a zero value,&lt;/li&gt;
&lt;li&gt;take all elements lower than &lt;code&gt;n&lt;/code&gt;, a number passed as parameter by the user - as a reminder, if we explicit the final of the iterator, the
compiler could decide to compute the final number at compile time, and store it in the executable -, and store the result in another array,&lt;/li&gt;
&lt;li&gt;loop all over the last array of elements to get only the odds, and store the result in another array,&lt;/li&gt;
&lt;li&gt;loop over the odds array to compute the sum, and return finaly return the value.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, multiple array allocations just to compute a simple sum&amp;hellip;&lt;/p&gt;
&lt;p&gt;Fortunately, &lt;strong&gt;Rust does not do that&lt;/strong&gt;: instead, the compiler writes as great code as the first solution provided here, by itself!&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s demonstrate it using benchmarks.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;benchmarks&#34;&gt;
  Benchmarks
  &lt;a class=&#34;anchor&#34; href=&#34;#benchmarks&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;The following benchmarks have been made using an Intel Core i5 (3 GHz, 6 cores * 2 threads / core), and show the median execution time of the both programs, hand-optimized and abstracted, ran ten times, and for different &lt;code&gt;n&lt;/code&gt; values.&lt;br&gt;
I used the &lt;code&gt;time&lt;/code&gt; program to measure the user + system execution times each time, and computed the median of those values.&lt;/p&gt;
&lt;p&gt;I performed the benchmarks for both debug and release versions.&lt;/p&gt;
&lt;p&gt;As a reminder, to build a release version of a Rust program using &lt;code&gt;cargo&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build --release &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# in the root of your cargo project&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To finish, the code repository of each code sample is available in a public github repository, at &lt;a href=&#34;https://github.com/k0pernicus/Rust_zero_cost_abstraction_illustration&#34;&gt;https://github.com/k0pernicus/Rust_zero_cost_abstraction_illustration&lt;/a&gt;, if you want to reproduce them yourself at home.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benchmarks&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Version&lt;/th&gt;
					&lt;th&gt;n&lt;/th&gt;
					&lt;th&gt;Hand-optimized execution time&lt;/th&gt;
					&lt;th&gt;Abstracted version execution time&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;0,02s&lt;/td&gt;
					&lt;td&gt;0,01s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug&lt;/td&gt;
					&lt;td&gt;100000&lt;/td&gt;
					&lt;td&gt;0,02s&lt;/td&gt;
					&lt;td&gt;0,03s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug&lt;/td&gt;
					&lt;td&gt;100000000&lt;/td&gt;
					&lt;td&gt;2,97s&lt;/td&gt;
					&lt;td&gt;6,59s &lt;strong&gt;(x2.22)&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug&lt;/td&gt;
					&lt;td&gt;1000000000&lt;/td&gt;
					&lt;td&gt;29,61s&lt;/td&gt;
					&lt;td&gt;65,16s &lt;strong&gt;(x2.20)&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;mdash;&lt;/td&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&lt;/td&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;ndash;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Release&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;0,00s&lt;/td&gt;
					&lt;td&gt;0,00s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Release&lt;/td&gt;
					&lt;td&gt;100000&lt;/td&gt;
					&lt;td&gt;0,00s&lt;/td&gt;
					&lt;td&gt;0,00s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Release&lt;/td&gt;
					&lt;td&gt;100000000&lt;/td&gt;
					&lt;td&gt;0,03s&lt;/td&gt;
					&lt;td&gt;0,03s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Release&lt;/td&gt;
					&lt;td&gt;1000000000&lt;/td&gt;
					&lt;td&gt;0,26s&lt;/td&gt;
					&lt;td&gt;0,26s&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As you can observe, optimizations for the abstracted version are mostly performed for the &lt;em&gt;release&lt;/em&gt; version, and both program versions have the same runtime performance in comparison with the debug versions.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;compile-time-consequences&#34;&gt;
  Compile time consequences
  &lt;a class=&#34;anchor&#34; href=&#34;#compile-time-consequences&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Unfortunately, zero-cost abstractions has a consequence: as the compiler has more work to do to optimize itself the abstracted code, it will run more longer.&lt;/p&gt;
&lt;p&gt;If you take a look at the compile time of each versions below, you can observe that the abstracted version compiles more slower than the hand-written version, even for a simple program like this&amp;hellip;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Version&lt;/th&gt;
					&lt;th&gt;Hand-written optimized&lt;/th&gt;
					&lt;th&gt;Abstracted&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug&lt;/td&gt;
					&lt;td&gt;0,01s&lt;/td&gt;
					&lt;td&gt;0,01s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;mdash;&lt;/td&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&lt;/td&gt;
					&lt;td&gt;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Release&lt;/td&gt;
					&lt;td&gt;5,80s&lt;/td&gt;
					&lt;td&gt;8,19s &lt;strong&gt;(x1.41)&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Do not hesitate to include abstractions in your code when you need them - in Rust, you should never think about hand-written optimizations first, but think about abstractions, software design, and code readibility, &lt;strong&gt;even if you care about runtime performances&lt;/strong&gt;.&lt;br&gt;
Unfortunaly, this has a (heavy) cost at compile time.&lt;/p&gt;
&lt;p&gt;Thanks to Robert Syme &lt;a href=&#34;https://github.com/k0pernicus/website/pull/1&#34;&gt;for his contribution&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Dealing everyday with anxiety, impostor syndrome, and mental depression</title>
      <link>https://carette.xyz/posts/dealing-with-depression/</link>
      <pubDate>Fri, 24 Jan 2020 20:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/dealing-with-depression/</guid>
      <description>&lt;p&gt;This is for sure the most intimate blog post I ever made on this website, and this blog post was absolutely necessary.&lt;/p&gt;
&lt;p&gt;Since I was in middle school, I suffered a few years from anxiety, mental depression, but also impostor syndrome.
The path was hard, but thanks to my family and my friends, I am feeling a lot better now.&lt;/p&gt;
&lt;p&gt;Recently, after talking with people in real life or in the internet, reading blog posts, or simply scrolling on Twitter, I do feel that anxiety,
depression and impostor syndrome is taking more and more place in our society, with this sentiment that all of those belong to what
I will call in this post &amp;ldquo;the pain of the century&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Indeed, anxiety and depression makes you think that emotional states are a prison for your mind, that you are just trapped by your sentiments,
which is actually a fake actor in this situation.&lt;br&gt;
At the other hand, impostor syndrome lets you think that you will never belong to a real group of people, and make you lose your self-esteem.&lt;/p&gt;
&lt;p&gt;I wanted to write down my own opinions about this pain that is ravaging more and more people, and the different methods I tried to deal with all
of those issues, in order to help you to live with them.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;investigate-on-yourself&#34;&gt;
  Investigate on yourself
  &lt;a class=&#34;anchor&#34; href=&#34;#investigate-on-yourself&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;At first, you have to understand that, every day, you will have to deal with two kind of persons: yourself, and all the others.&lt;/p&gt;
&lt;p&gt;To investigate on yourself allows you to understand who you really are, and target your key points, but also your flaws.
This goes throught several states, but the first (and most important one), is to &lt;strong&gt;understand your weaknesses&lt;/strong&gt;, meditating on yourself.&lt;br&gt;
The path will takes some time (days, weeks, months, or even years), but will makes you stronger each new day of your life: a long path to a long term beneficit.&lt;/p&gt;
&lt;p&gt;At the contrary, hiding your weaknesses could be beneficial for short time, but will make your life more difficult to live at the long term, for sure.&lt;br&gt;
Also, to hide them could bring another problem in your daily life: greater and greater efforts to hide them more and more&amp;hellip;
Indeed, your principal fear in this case will be to let someone exploit your flaws, and makes your life worse.&lt;/p&gt;
&lt;p&gt;The best way to meditate on yourself is to trace each of your bad feelings, from today to the origin, and to understand the &lt;em&gt;how&lt;/em&gt; and the &lt;em&gt;why&lt;/em&gt;.
&lt;em&gt;Take the time you need to medidate&lt;/em&gt; - in my own opinion, 30 minutes of your time per day is more than enough.&lt;/p&gt;
&lt;p&gt;Another technique is to write down on paper your different thoughts, and to throw the paper in the trash a few minutes later.
This method seems very dumb, but to write down your feelings and destroy them can help you to realize that sentiments can just be words on paper,
and that you are not trapped by your feelings.&lt;/p&gt;
&lt;p&gt;Remember that dealing with weaknesses and hiding them are two very different aspects, and &lt;strong&gt;hiding feelings are more painful in the long term than
understanding and accepting them&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;you-are-free-to-make-mistakes&#34;&gt;
  You are free to make mistakes
  &lt;a class=&#34;anchor&#34; href=&#34;#you-are-free-to-make-mistakes&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I do think that impostor syndrome, or fraud syndrome, is very hard to deal with because &lt;strong&gt;it&amp;rsquo;s in everybody&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When I was in college, I remember to sit down on my student chair, looking at the other students around me, and almost got a panic attack because I
had the sentiment that I was not good enought to feel part of this big group of students.
However, after discussing with some of them about my feelings - remember that &lt;strong&gt;you have to accept your feelings, not hiding them&lt;/strong&gt; -, I realized
that the other students I talked to had &lt;em&gt;exactly&lt;/em&gt; the same psychological pattern.&lt;br&gt;
I understood at this time that &lt;strong&gt;impostor syndrome was not a personal feeling, but a society problem&lt;/strong&gt;, and that I was not alone with this group of students.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Knowledge is definitly not innate&lt;/strong&gt;, and each person will have his or her own facility in a particular field, subject, or technique, and have difficulties to understand anothers.&lt;br&gt;
The most difficult thing in this part is to discover on what you are good at.
Difficult, but &lt;strong&gt;definitly not impossible&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When you are suffering from impostor syndrome, one of the worst thing we have to handle is sentiments from our environment,
like your colleagues, your family, or someone else.
Dealing with people -and their sentiments- is a common issue for people that live with fraud syndrome,
especially when they found their exact opposite: people who have the sentiment to know &lt;strong&gt;everything&lt;/strong&gt; even if they only scratched the surface of a field, subject, or a technique.&lt;/p&gt;
&lt;p&gt;Unfortunately, I don&amp;rsquo;t have a magic solution for this syndrome.
To be honest, I begin to think that there is no solution for this kind of problem.&lt;br&gt;
My only way to deal with this was to practice the domain I wanted to be good at, and to break with people that makes me feel bad in this domain.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;find-an-hobbie-that-get-your-attention&#34;&gt;
  Find an hobbie that get your attention
  &lt;a class=&#34;anchor&#34; href=&#34;#find-an-hobbie-that-get-your-attention&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Anxiety, for me, cames with social pressure and, of course, stress.
To overcome those psychological issues, you have to clear your mind, and &lt;strong&gt;try to think about anything else&lt;/strong&gt;.&lt;br&gt;
This is where personal hobbies come in this story.&lt;/p&gt;
&lt;p&gt;My personal hobbies are to read books, play video games, and watch movies.&lt;br&gt;
I did not found yet the sport that attracts me yet, so I don&amp;rsquo;t practice physical exercises at all.&lt;/p&gt;
&lt;p&gt;Personal hobbies will help you to assimilate that &lt;strong&gt;you are not your thoughts&lt;/strong&gt;, and think about something else than daily problems&lt;/p&gt;
&lt;p&gt;To help you with this part, I recommend you to listen this Q/A session from &lt;a href=&#34;https://en.wikipedia.org/wiki/Jonathan_Blow&#34;&gt;Jonathan Blow&lt;/a&gt;, an independant
game developer and designer, about &lt;a href=&#34;https://www.youtube.com/watch?v=i7kh8pNRWOo&#34;&gt;techniques to deal with lack of motivation, malaise, and depression&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;listen-to-yourself-and-breathe&#34;&gt;
  Listen to yourself, and BREATHE
  &lt;a class=&#34;anchor&#34; href=&#34;#listen-to-yourself-and-breathe&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you feel that something is starting to overwhelm you, &lt;strong&gt;stop it right now&lt;/strong&gt;.
Breathe, make a pause, and ask yourself if it&amp;rsquo;s worth continuing.
Sometimes, just taking a little step back from a difficult task makes you more aware about how to solve it.&lt;/p&gt;
&lt;p&gt;When I was in college, I was really interested in video games development, especialy indie games success stories.
At this time, I started watching some documentaries about indie games and indie developers, like &amp;ldquo;Indie Game: The Movie&amp;rdquo;, or reading books about it&amp;hellip;
After consuming them, I was incredibly dismayed to learn that, even though the indie developers of that time were successful, and that they earned a lot of money,
they went through anxiety and mental depression right afterwards, precisely because of their hard developing experience.&lt;br&gt;
Indeed, most people will continue to work on something, even if they have losed motivation about it, until he finished it&amp;rsquo;s work.
However, most of the time, bad things will happen once the work is done, and the road to healing is long and very painful.&lt;/p&gt;
&lt;p&gt;To sum up: &lt;strong&gt;there is no shame to drop something&lt;/strong&gt;, and there is no shame to make mistakes if you gain experience from it.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First of all, &lt;strong&gt;there is no shame to understand your feelings&lt;/strong&gt;. You are the only person on board in your mind, so don&amp;rsquo;t take the emotions from the others to
assimilate them: feel yourself, and f**k off for the others. Also, don&amp;rsquo;t be scared of your sentiments, embrace them instead!&lt;br&gt;
Next, &lt;strong&gt;we are humans, not machines&lt;/strong&gt;, and knowledge is not innate. We have to learn, understand, and make mistakes to grow up.&lt;br&gt;
To relax, find an hobbie, or maybe a place to relax, in order to release all the anxiety and social pressure on your shoulders as soon as you can.
&lt;strong&gt;Just breathe a few minutes, relax, and take time for yourself&lt;/strong&gt;.&lt;br&gt;
Finally, &lt;strong&gt;listen to yourself, listen your body, and breathe, breathe, and breathe&lt;/strong&gt;. If you are not feeling great with something, just step back and
meditate on this. Remember that, again, there is no shame to drop something to feel better.&lt;/p&gt;
&lt;p&gt;Good luck my friend.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A strange strings comparison problem, in Go</title>
      <link>https://carette.xyz/posts/go_untyped_constants/</link>
      <pubDate>Sun, 15 Sep 2019 02:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/go_untyped_constants/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/go_implicit_conversions_1.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Thanks to &lt;a href=&#34;https://github.com/egonelbre/gophers&#34;&gt;https://github.com/egonelbre/gophers&lt;/a&gt; for this sketch &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Go is known for it&amp;rsquo;s strong type system, and explicit type conversion.&lt;/p&gt;
&lt;p&gt;For example, if you have to compare two different values of different types, you will have a compiler error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; x &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt; = 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; y &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int32&lt;/span&gt; = 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%+v&amp;#34;&lt;/span&gt;, x == y) 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you try to compile this code sample, you will have to deal with the following error, reached during compilation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:8:24: invalid operation: &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; == y (mismatched types int and int32)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In order to make it work, you will have to convert &lt;code&gt;x&lt;/code&gt; to &lt;code&gt;int32&lt;/code&gt; (or &lt;code&gt;y&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt; in order to not loose any precision - which is not the case in the code sample), which is called &lt;em&gt;explicit type conversion&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This behaviour, in Go, is normal, because a well known design decision is &lt;strong&gt;the absence of implicit type conversions&lt;/strong&gt;, like in C.&lt;/p&gt;
&lt;p&gt;Great design, no?&lt;/p&gt;
&lt;p&gt;Except that, even for awesome tools &amp;amp; rules, there &lt;em&gt;always&lt;/em&gt; exist some exceptions.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;type-identity&#34;&gt;
  Type identity
  &lt;a class=&#34;anchor&#34; href=&#34;#type-identity&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s talk about the following code sample:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; myString = &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Here, myString will be replaced by string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; x myString = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; y &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%+v&amp;#34;&lt;/span&gt;, x == y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code outputs &amp;ldquo;true&amp;rdquo;, which is understandable because myString is a &lt;em&gt;type alias of string&lt;/em&gt;.&lt;br&gt;
Some people still think that the compiler converts (implicitly) a &lt;code&gt;myString&lt;/code&gt; value to a &lt;code&gt;string&lt;/code&gt; value during compilation, which is not the case.&lt;br&gt;
Actually, the compiler will just replace each &lt;code&gt;myString&lt;/code&gt; type name with &lt;code&gt;string&lt;/code&gt; (think about a Vim&amp;rsquo;s &lt;code&gt;:%s/myString/string/g&lt;/code&gt; in the whole program) in order to compile the program.
So, for the bytecode, a &lt;code&gt;myString&lt;/code&gt; type &lt;strong&gt;is&lt;/strong&gt; a &lt;code&gt;string&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;Now, if you remove the equals symbol at line 7 (when defining the type &lt;code&gt;myString&lt;/code&gt;), you are defining a new type, related to a &lt;code&gt;string&lt;/code&gt; one, but that is &lt;strong&gt;explicitly different&lt;/strong&gt; than a &lt;code&gt;string&lt;/code&gt; for the type system.&lt;/p&gt;
&lt;p&gt;In this case, the code will not compile and the error will be almost the same as before:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:12:22: invalid operation: &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; == y (mismatched types myString and string)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, let&amp;rsquo;s try something a bit different&amp;hellip;&lt;/p&gt;
&lt;p&gt;If I replace the line&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; y &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; y = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the problem still remains the same.&lt;br&gt;
Using type inference feature, the compiler will understand that &lt;code&gt;&amp;quot;Hello&amp;quot;&lt;/code&gt; is a string, and will type it implicitly.&lt;/p&gt;
&lt;p&gt;So, the following program must be the same than the previous version, right?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; myString &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; x myString = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%+v&amp;#34;&lt;/span&gt;, x == &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, we did not declared &lt;code&gt;y&lt;/code&gt; and instanciated it with &lt;code&gt;Hello&lt;/code&gt;.
We let the compiler do it for us.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s run it to expect the same error and the program&amp;hellip; suceeded !?&lt;br&gt;
And outputs &lt;code&gt;&amp;quot;true&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But&amp;hellip; why?&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;untyped-string-constants&#34;&gt;
  Untyped string constants
  &lt;a class=&#34;anchor&#34; href=&#34;#untyped-string-constants&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The first idea here is to ask ourselves if the compiler does not instantiates by itself &lt;code&gt;Hello&lt;/code&gt; as a &lt;code&gt;myString&lt;/code&gt; type, which is false:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%+v - type of &amp;#39;Hello&amp;#39; is &amp;#39;%+v&amp;#39;\n&amp;#34;&lt;/span&gt;, x == &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;outputs &lt;code&gt;true - type of &#39;Hello&#39; is string&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second idea is to ask themselves if &lt;code&gt;&amp;quot;Hello&amp;quot;&lt;/code&gt; is a variable, and not a constant value&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.golang.org/constants&#34;&gt;This blog post&lt;/a&gt; from Rob Pike about constants in Go, explains clearly that &lt;strong&gt;all unassigned text between double quotes are considered as constant values&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So, the previous code is (almost) exactly like the following one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; myString &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; y = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;var&lt;/span&gt; x myString = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%+v&amp;#34;&lt;/span&gt;, x == y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which still outputs &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As Rob Pike explained in the blog post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is an &lt;em&gt;untyped string constant&lt;/em&gt; [&amp;hellip;]. Yes, it&amp;rsquo;s a string, but it&amp;rsquo;s not a Go value of type &lt;em&gt;string&lt;/em&gt;. [&amp;hellip;] An untyped constant is &lt;strong&gt;just a value, one not yet given a defined type that would force it to obey the strict rules that prevent combining differently typed values&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Later in the same blog post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These untyped string constants are strings, of course, so they can only be used where a string is allowed, but they do not have type &lt;em&gt;string&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, following those explanations, we can understand that if we define constants with concrete types, and not let the compiler infer those, we will not having this issue anymore. &lt;br&gt;
In this case, if we change the definition of &lt;code&gt;y&lt;/code&gt; to this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; y &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the comparison will fail at compile time, with the same compilation error message than the previous time(s).&lt;/p&gt;
&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/go_implicit_conversions_2.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Thanks to &lt;a href=&#34;https://github.com/egonelbre/gophers&#34;&gt;https://github.com/egonelbre/gophers&lt;/a&gt; for this sketch &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;but-why-do-we-need-untyped-string-constants&#34;&gt;
  But&amp;hellip; why do we need untyped string constants?
  &lt;a class=&#34;anchor&#34; href=&#34;#but-why-do-we-need-untyped-string-constants&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;At first, it seems that untyped constants was a bad design move from the creators of Go, because you can use them to escape from Go&amp;rsquo;s strong type system, which allows you to make some comparison mistakes if you don&amp;rsquo;t pay enough attention, or even worst:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; myString &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; y = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;world&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	x := &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;make&lt;/span&gt;([]myString, 0, 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	x = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;append&lt;/span&gt;(x, &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;myString&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Append a myString &amp;#34;Hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	x = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;append&lt;/span&gt;(x, y) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// As y is untyped, we can append y here - no compilation error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%s\n&amp;#34;&lt;/span&gt;, x) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Print &amp;#34;[Hello world]&amp;#34; here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, the previous examples paid attention to untyped string constants, but you can obviously hack with untyped int constants, untyped float constants, and so on&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, why do Go creators introduced the notion of untyped string constants?&lt;/p&gt;
&lt;p&gt;Again, as Rob Pike explained in the blog post:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is this notion of an untyped constant that makes it possible for us to use constants in Go with great freedom.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thoses statements prove actually two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;untyped constants move is a &lt;strong&gt;design decision for more flexibility&lt;/strong&gt; for Go;&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;typed constants don&amp;rsquo;t use the same type system as variables&lt;/strong&gt;, in Go.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This &lt;a href=&#34;https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html&#34;&gt;great article from ArdanLabs&lt;/a&gt; provides a practical example to explain this Go feature in a numerical issue (look at section &amp;ldquo;One Practical Example&amp;rdquo;).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Inference of constants values &lt;strong&gt;is different&lt;/strong&gt; than inference of variables values, as typed constants don&amp;rsquo;t use the same type system as variables.&lt;/p&gt;
&lt;p&gt;Untypes constants provide flexibility, and escape from Go&amp;rsquo;s strong type system.&lt;/p&gt;
&lt;p&gt;Be careful about untyped constant - &lt;strong&gt;they might be useful in certain cases&lt;/strong&gt;, but I strongly recommend to restrict first the type of your constants, and to remove them later if you really need more flexibility in your code.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>(Un)marshal complex JSON objects, in Go</title>
      <link>https://carette.xyz/posts/go_unmarshal_complex_structure/</link>
      <pubDate>Tue, 16 Apr 2019 20:03:16 +0200</pubDate>
      <guid>https://carette.xyz/posts/go_unmarshal_complex_structure/</guid>
      <description>&lt;p&gt;If you work a lot with APIs in Go, it may happen you have to work with complex
JSON responses&amp;hellip;&lt;/p&gt;
&lt;p&gt;Ok, let&amp;rsquo;s talk about that using a simple example.&lt;/p&gt;
&lt;p&gt;Imagine you have to work with the following data structure, which represents a
&lt;code&gt;Person&lt;/code&gt; data structure (like a real person, no trap) with the following
characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the name of a Person object: a string;&lt;/li&gt;
&lt;li&gt;the dog&amp;rsquo;s name of the Person object (if it exists): a Dog structure that
contains only a string, which is its name;&lt;/li&gt;
&lt;li&gt;the age of the Person object: an integer;&lt;/li&gt;
&lt;li&gt;the last time the data structure has been updated: a datetime type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, we try to implement the associated Go structure, which is very simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Person &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name      &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  DogS      Dog       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;dog&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Age       &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;age&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UpdatedAt time.Time &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;updatedAt&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Dog &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For now, everything is ok, and we imagine the JSON response like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;name&amp;#34;: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Ferdinand&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;age&amp;#34;: 25,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;dog&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;#34;name&amp;#34;: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Rex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;updatedAt:&lt;/span&gt; &amp;#34;2019-01-01 00:00Z&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately, the response does not look like this.
&lt;em&gt;At all&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In contrast, the data in JSON looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;name&amp;#34;: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Ferdinand&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;age&amp;#34;: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;25&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;updatedAt&amp;#34;: &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2019-01-01 00:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is (at least) three big issues in our previous Go code.
Let&amp;rsquo;s decompose what (and where) are the problems, and how to solve them one by
one.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;handle-the-missed-data&#34;&gt;
  Handle the missed data
  &lt;a class=&#34;anchor&#34; href=&#34;#handle-the-missed-data&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As you may already noticed, we miss a data in the JSON response: the &lt;code&gt;dog&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;A basic solution to this is to implement a structure &lt;em&gt;if&lt;/em&gt; the dog JSON object
is present, or &lt;em&gt;if&lt;/em&gt; the dog JSON object is not present&amp;hellip;
Spoiler: this is a &lt;em&gt;&lt;strong&gt;very bad&lt;/strong&gt;&lt;/em&gt; solution.&lt;/p&gt;
&lt;p&gt;When you are (un)marshalling a JSON object in Go, you can omit some fields &lt;em&gt;if&lt;/em&gt;
the field is empty (consider empty as NULL, or just the default type value, like
an empty string for string type, or a 0 value for a default integer value).
Usually, this solution is really simple to use, because you just have to append
the &lt;code&gt;omitempty&lt;/code&gt; tag in the Go struct tags you wrote before, for the field you want omit.
Using it permits also to reduce the payload if you want to send little data
structure compared to your big (and complex) Go data structure.&lt;/p&gt;
&lt;p&gt;So, for the dog, you just have to trick your Go data model like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Person &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name      &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  DogS      Dog       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;dog,omitempty&amp;#34;`&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// We append here the &amp;#39;omitempty&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  tag
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Age       &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;age&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UpdatedAt time.Time &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;updatedAt&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Dog &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=&#34;heading&#34; id=&#34;handle-the-string-values&#34;&gt;
  Handle the string values
  &lt;a class=&#34;anchor&#34; href=&#34;#handle-the-string-values&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Unmarshalling the previous JSON structure throws the following error: &lt;code&gt;json: cannot unmarshal string into Go struct field Person.age of type int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second issue is that the &lt;code&gt;age&lt;/code&gt; field is not an integer, but a string &lt;em&gt;that
represents&lt;/em&gt; an integer.
Unmarshalling this kind of thing does not work at all&amp;hellip; without an extra tag
again!&lt;/p&gt;
&lt;p&gt;This tag is &lt;code&gt;string&lt;/code&gt;, and have to be append next the &lt;code&gt;age&lt;/code&gt; field in the Go
structure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Person &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name      &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  DogS      Dog       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;dog,omitempty&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Age       &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;age,string&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UpdatedAt time.Time &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;updatedAt&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; Dog &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;string&lt;/code&gt; tag informs that the unmarshalling behaviour has to convert
explicitly the string type to the type in the Go structure.&lt;/p&gt;
&lt;p&gt;Unfortunately, magic can disappear really quickly&amp;hellip;
But we will explore this black magic of Go in the last section of this blog post.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;handle-the-wrong-datetime-format&#34;&gt;
  Handle the wrong datetime format
  &lt;a class=&#34;anchor&#34; href=&#34;#handle-the-wrong-datetime-format&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The Go &lt;code&gt;time&lt;/code&gt; library &lt;a href=&#34;https://golang.org/pkg/time/&#34;&gt;does handle multiple time
formats&lt;/a&gt;.
Unfortunately, the format of the date returned in the response does not
correspond to a supported time format, in the Go standard library.&lt;/p&gt;
&lt;p&gt;You can try to check another Go library that handles this format (I doubt about
it&amp;hellip;), or you can write your own time parser, for &lt;em&gt;this&lt;/em&gt; specific time format:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; PersonDate &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  time.Time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we have to write our custom &lt;code&gt;MarshalJSON&lt;/code&gt; and &lt;code&gt;UnmarshalJSON&lt;/code&gt; functions for
this custom structure, in order to valide the interface contract with the Marshal
interface.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; PersonDateFormat = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2006-01-02 15:04&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; (pd *PersonDate) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;UnmarshalJSON&lt;/span&gt;(input []&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;byte&lt;/span&gt;) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  strInput := &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string&lt;/span&gt;(input)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  strInput = strings.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Trim&lt;/span&gt;(strInput, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&amp;#34;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  newTime, err := time.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Parse&lt;/span&gt;(PersonDateFormat, strInput)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; err
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pd.Time = newTime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; (pd PersonDate) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MarshalJSON&lt;/span&gt;() ([]&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;byte&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Here, you can return the given time in an existing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// (and accepted) time format&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;return&lt;/span&gt; []&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;byte&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&amp;#34;`&lt;/span&gt; + pd.Time.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Format&lt;/span&gt;(time.RFC1123) + &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`&amp;#34;`&lt;/span&gt;), &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point, you can unmarshal this custom date time format in replacing the
&lt;code&gt;time.Time&lt;/code&gt; type in the &lt;code&gt;Person&lt;/code&gt; structure with the &lt;code&gt;PersonDate&lt;/code&gt; structure, and marshal it
into another time format that is recognized by the Go library.&lt;/p&gt;
&lt;p&gt;Nice!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;handle-the-conversion-errors-during-unmarshalling&#34;&gt;
  Handle the conversion errors during Unmarshalling
  &lt;a class=&#34;anchor&#34; href=&#34;#handle-the-conversion-errors-during-unmarshalling&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;For this last issue, I don&amp;rsquo;t think there is a &amp;ldquo;good&amp;rdquo; solution&amp;hellip;&lt;/p&gt;
&lt;p&gt;Imagine now that an error happened in the back side, and overrides the &lt;code&gt;age&lt;/code&gt; value by an empty string
(or something other than an integer) in the JSON response.
If you have this type of response, an error will be thrown: &lt;code&gt;json: invalid use of ,string struct tag, trying to unmarshal &amp;quot;&amp;quot; into int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can&amp;rsquo;t be angry with the &lt;code&gt;UnmarshalJSON&lt;/code&gt; function, because this error is terribly logic.&lt;/p&gt;
&lt;p&gt;Do not forget that unmarshalling a string into an int, using the &lt;code&gt;string&lt;/code&gt; tag,
will &lt;em&gt;convert&lt;/em&gt; the data type into another one.
In the case of converting a string type value into an integer, the function can explicitly call &lt;code&gt;strconv.Atoi&lt;/code&gt;.
If you already used this function, you know that the function returns an
integer, or an error if the string does not represents an integer.
Like an empty string.&lt;/p&gt;
&lt;p&gt;Unfortunately, there is no easy way to handle this error&amp;hellip; except rewriting the
Unmarshal process for our structure, or&amp;hellip; using two different structures.&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;1st-solution-the-custom-age-field&#34;&gt;
  1st solution: the custom Age field
  &lt;a class=&#34;anchor&#34; href=&#34;#1st-solution-the-custom-age-field&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Like we did for our custom Date format, we can wrap the &lt;code&gt;Age&lt;/code&gt; field into a custom
Go data structure (for example, &lt;code&gt;PersonAge&lt;/code&gt;), and write a custom &lt;code&gt;MarshalJSON&lt;/code&gt;
and &lt;code&gt;UnmarshalJSON&lt;/code&gt; methods for this Go structure.
However, if you plan in the future to create concrete type for each integer
values in the &lt;code&gt;Person&lt;/code&gt; Go structure, and if you have to manage later different
integer values, you will have to create as much custom Go structure than
integer values in the JSON response&amp;hellip;&lt;/p&gt;
&lt;h3 class=&#34;heading&#34; id=&#34;2nd-solution-separate-the-json-structure-and-the-final-go-data-structure&#34;&gt;
  2nd solution: separate the JSON structure and the final Go data structure
  &lt;a class=&#34;anchor&#34; href=&#34;#2nd-solution-separate-the-json-structure-and-the-final-go-data-structure&#34;&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;The purpose of this solution is to handle and unmarshal the JSON structure in a
Go structure that contains all its values as string types, and create a function
to convert this structure into another that contains the required &lt;code&gt;Person&lt;/code&gt;
types, using reflection.
This solution can be generic, in order to convert all the data structures you
want into another (using &lt;code&gt;interface{}&lt;/code&gt; parameters), but can be complicated if
you just want to solve this issue for this field issue &lt;em&gt;only&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As I said previously, &lt;strong&gt;there is no best advice&lt;/strong&gt; for this, because it depends
of the kind of response you will have in real world.
If you are sure that the JSON response will not change, and you only have one
integer (or float) field type, go for the 1st solution!
Otherwise, you can play with reflection in order to build a more concrete and
durable solution, not only for this Go structure (and JSON response) but also
for many other that share this issue.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;go-playground&#34;&gt;
  Go playground
  &lt;a class=&#34;anchor&#34; href=&#34;#go-playground&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you want to play with this example, please play with &lt;a href=&#34;https://play.golang.org/p/la3Xxw1rBCb&#34;&gt;this Go
playground&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2019, as minimalistic</title>
      <link>https://carette.xyz/posts/2019_as_minimalistic/</link>
      <pubDate>Wed, 20 Feb 2019 10:11:49 +0100</pubDate>
      <guid>https://carette.xyz/posts/2019_as_minimalistic/</guid>
      <description>&lt;p&gt;I became fed up with my electronic materials.&lt;/p&gt;
&lt;p&gt;The way we evolve, as city dwellers, implies sometimes to adopt a non-minimalistic approach to live:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to have one device to make only one thing,&lt;/li&gt;
&lt;li&gt;to have different devices that can be used to make the same thing,&lt;/li&gt;
&lt;li&gt;to buy expensive things based on good ads,&lt;/li&gt;
&lt;li&gt;to buy expensive things based on what you can do (and finally things you will never do), &amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In 2019, I want to adopt a new approach in my life, which can be simply resumed as: &lt;strong&gt;do more, with less&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Both for myself, and for the Planet (don&amp;rsquo;t forget it).&lt;/p&gt;
&lt;p&gt;In this post, I will develop four different points to adopt a general minimalistic approach.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;choose-according-your-usage-and-not-the-inverse&#34;&gt;
  Choose according your usage, and not the inverse
  &lt;a class=&#34;anchor&#34; href=&#34;#choose-according-your-usage-and-not-the-inverse&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A problem I have with myself is to choose a device based on what I would do with it, and not what I can currently do with it.
This sort of thinking implies to buy a lot of devices, for all sort of things I will never have the time to do
in the next months/years!&lt;/p&gt;
&lt;p&gt;And this is purely wastefulness.&lt;/p&gt;
&lt;p&gt;But be careful, I am not telling you to avoid any unnecessary technology, but rather to make a choice in order to use them conscientiously!
Let&amp;rsquo;s make the distinction about my computing usage, based on the last three years.&lt;/p&gt;
&lt;p&gt;For now, I have four computing devices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a laptop, for web browsing, blogging and programming,&lt;/li&gt;
&lt;li&gt;a tablet, for web browsing and blogging the night,&lt;/li&gt;
&lt;li&gt;a smartphone, to communicate and to take a lot of photos,&lt;/li&gt;
&lt;li&gt;and a gaming PC for&amp;hellip; gaming. Only.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Four different devices, for four different (and common) tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web browsing (read articles, and watch YouTube videos),&lt;/li&gt;
&lt;li&gt;blogging,&lt;/li&gt;
&lt;li&gt;programming (just a little),&lt;/li&gt;
&lt;li&gt;gaming.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think we can easily reduce the number to two: a laptop, and a smartphone.&lt;/p&gt;
&lt;p&gt;For programming, based on my previous experience, I only use CPU computation, and my RAM usage is ~ 6GB of RAM.
No need GPU here&amp;hellip;
For web browsing and blogging, I really don&amp;rsquo;t need an expensive hardware for that&amp;hellip;&lt;/p&gt;
&lt;p&gt;To avoid the tablet, I can make use of an hybrid laptop - like a surface, or a laptop with touchscreen (with a 360 keyboard).&lt;/p&gt;
&lt;p&gt;But the gaming PC&amp;hellip; the choice is hard.
For this, I have three different possibilities:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Avoid a lightweight and (and unexpensive) laptop to buy an heavy gaming laptop;&lt;/li&gt;
&lt;li&gt;To buy an eGPU, which add again a new device for this task exclusively;&lt;/li&gt;
&lt;li&gt;To keep the lightweight laptop and buy a subscription to a cloud gaming provider.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Today, a lot of companies are working on gaming in the cloud: Blade (the French company that produces Shadow), Google, Microsoft, Nvidia&amp;hellip;
and, to have tested cloud gaming using a Shadow PC, it works really well &lt;em&gt;if&lt;/em&gt; you have a &lt;strong&gt;good&lt;/strong&gt; internet connection.&lt;/p&gt;
&lt;p&gt;Be careful, I did not say &amp;ldquo;really good&amp;rdquo; or &amp;ldquo;exceptional&amp;rdquo; internet connection, but just &amp;ldquo;good&amp;rdquo; internet connection&amp;hellip;
The promise to have a really good gaming experience on 5MB/s connection was awesome for me.&lt;/p&gt;
&lt;p&gt;So, for all those tasks, I can maybe express the idea that&amp;hellip; a Chromebook can finally be a good choice for me, as a laptop!&lt;/p&gt;
&lt;p&gt;Also, if I sell my current gaming PC, my tablet and my (expensive) laptop (for almost nothing), I can buy a good Chromebook for 33% of
the price I will earn in selling those devices.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;do-i-really-need-it-or-how-to-avoid-all-sort-of-gadgets&#34;&gt;
  &amp;ldquo;Do I really need it?&amp;rdquo;, or how to avoid all sort of gadgets
  &lt;a class=&#34;anchor&#34; href=&#34;#do-i-really-need-it-or-how-to-avoid-all-sort-of-gadgets&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The common mistakes with gadgets is to ask yourself a wrong question: &amp;ldquo;Do I will use it?&amp;rdquo;.
Instead, ask yourself the same question but based on your &lt;strong&gt;current&lt;/strong&gt; needs: &amp;ldquo;Do I &lt;em&gt;really&lt;/em&gt; need it (now)?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;99% of the time, now, I came to the conclusion that I can avoid this gadget, and save my money for something I really need.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-diy-magic&#34;&gt;
  The DIY magic
  &lt;a class=&#34;anchor&#34; href=&#34;#the-diy-magic&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Sometimes, you have the feeling that, if you want the object of your dreams, you have to buy multiple things in order to assemble them,
or to buy one unique &lt;strong&gt;really expensive&lt;/strong&gt; thing to satisfy your desire.
Also, you tend to forget that you can build it yourself&amp;hellip;&lt;/p&gt;
&lt;p&gt;To hack an object can, sometimes, be more refreshing and beneficial in the long term than buying a new &amp;ldquo;thing&amp;rdquo;
for something you can abandon in two months.
Also, generally, it costs less to do it by yourself&amp;hellip;&lt;/p&gt;
&lt;p&gt;Do not forget that the DIY approach is principally based on refreshing old objects, and to make something new with something old (or broken).
In this way, do not throw an object in a trash if you don&amp;rsquo;t use it, even if this object is broken!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sell it, or give it to someone. Do not throw it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-finish&#34;&gt;
  To finish&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#to-finish&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Live in the present, buy according your needs (and not according [only] your dreams), and &lt;strong&gt;make it&lt;/strong&gt; :)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Struct embedding trick to avoid duplicate code</title>
      <link>https://carette.xyz/posts/struct_embedding_trick/</link>
      <pubDate>Tue, 06 Nov 2018 21:50:24 +0100</pubDate>
      <guid>https://carette.xyz/posts/struct_embedding_trick/</guid>
      <description>&lt;p&gt;When you are writing go code, and try to make it more flexible, most of the time you are looking for interfaces.
A go interface is a good solution to make your code more flexible, or scalable,
and is also a way to achieve polymorphism.&lt;/p&gt;
&lt;p&gt;As the official go documentation discusses about interfaces, interfaces are &amp;ldquo;named collections of method signatures&amp;rdquo;.
So, to implement an interface on different structs, you have to implement
each interface&amp;rsquo;s method for a given struct.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s imagine a problem&amp;hellip;
I want to invent an RPG game, and I need two different classes of players:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;orc,&lt;/li&gt;
&lt;li&gt;elf.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those classes can be grouped in an interface called &amp;ldquo;player&amp;rdquo;, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; player &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;interface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;name&lt;/span&gt;() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getInformations&lt;/span&gt;() &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;strike&lt;/span&gt;(p *player) (&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stricken&lt;/span&gt;(p *player) (&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; orc &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  age &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  health &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  size &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; elf &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  age &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  health &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  vision &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If I want to implement this interface for &lt;code&gt;orc&lt;/code&gt; and &lt;code&gt;elf&lt;/code&gt;, I have to implement
&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;getInformations&lt;/code&gt;, &lt;code&gt;strike&lt;/code&gt; and &lt;code&gt;stricken&lt;/code&gt; methods for both &lt;code&gt;orc&lt;/code&gt; and &lt;code&gt;elf&lt;/code&gt;, which is like duplicating code (except for &lt;code&gt;getInformations&lt;/code&gt; as our struct contains different
usefull informations about a given Player class).&lt;/p&gt;
&lt;p&gt;A nice trick here is to consider that the redundant code may be included in an interface, via an embedded struct (the example has been reduced to make it more understandable).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; namer &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// We implement only one method, for namer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; (n *namer) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getName&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Println&lt;/span&gt;(n.name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; orc &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  namer &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Instead of the name string type, we include directly the namer struct&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  age &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  health &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  size &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;type&lt;/span&gt; elf &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  namer &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Same for the elf type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  age &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  health &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  vision &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  o := orc{namer: namer{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Orc&amp;#34;&lt;/span&gt;}, age: 12, ...}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  e := elf{namer: namer{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Elf&amp;#34;&lt;/span&gt;}, age: 12, ...}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  o.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getName&lt;/span&gt;() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// It works, as an orc type contains the struct namer that respects&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// the deal with the get interface&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  e.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getName&lt;/span&gt;() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// As well with the elf type :)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The go playground is available &lt;a href=&#34;https://go.dev/play/p/cC_vgHzJBYP&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using this trick, we don&amp;rsquo;t have to implement twice the same method for &lt;code&gt;orc&lt;/code&gt; and &lt;code&gt;elf&lt;/code&gt;, and create duplication code, which is pretty nice if you have to add 10 new structs, and a lot of new methods in the &lt;code&gt;namer&lt;/code&gt; interface.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>`go mod`: manage all your dep as a single unit</title>
      <link>https://carette.xyz/posts/go_module_feature/</link>
      <pubDate>Sat, 03 Nov 2018 20:04:54 +0100</pubDate>
      <guid>https://carette.xyz/posts/go_module_feature/</guid>
      <description>&lt;p&gt;Generally, when you want to package your go app, you are creating different
packages, inside the same project.
The problem is, if you want to use a single internal package, you simply can&amp;rsquo;t,
because you have to import the &lt;em&gt;entire&lt;/em&gt; package in order to user a single and
very simple feature inside.&lt;/p&gt;
&lt;p&gt;But, sometimes, you don&amp;rsquo;t want to use a single extenal package.
Indeed, you just want to use a certain number of packages to do a task, and all compatible between them.
And this become more complex&amp;hellip;
Also, do not forget that, when importing a Go project using &lt;code&gt;go get&lt;/code&gt;, it will
not check the package dependencies, or the package versions&amp;hellip;
So, you need an external tool to define and &lt;em&gt;save&lt;/em&gt; the package versions your
Go app is using.&lt;/p&gt;
&lt;p&gt;Since Go 1.11 (as a beta version), a new feature pointed to the end of his nose
in order to help you in creating, and managing, easily a group of packages
as a single unit: the Go modules.
Also, &lt;a href=&#34;https://www.reddit.com/r/golang/comments/9ai79z/correct_usage_of_go_modules_vendor_still_connects/&#34;&gt;vendoring will be &amp;ldquo;deprecated&amp;rdquo; soon to give way to Go modules soon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s talk about this feature.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-context&#34;&gt;
  The context
  &lt;a class=&#34;anchor&#34; href=&#34;#the-context&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Go has a lot of external tools in order to manage dependencies: vendors, go dep&amp;hellip;
but those tools are not very efficient, and raised a lot of problems (and usability
exception) since their public availability.
The needs, for Gophers, was to build an internal command in order to fetch and install specific dependencies in order to build a Go package.&lt;/p&gt;
&lt;p&gt;At this time, Go modules was born.&lt;/p&gt;
&lt;p&gt;Go modules appeared in Go 1.11 as a beta feature, and has been released as a
stable feature in Go 1.12.&lt;/p&gt;
&lt;p&gt;In order to preserve the consistency and the maintanability of Go projects,
&lt;code&gt;go mod&lt;/code&gt; will check the &lt;code&gt;Gopkg.lock&lt;/code&gt;, if it exists, in order to retrieve
very fast the required libraries for your Go app.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-concept&#34;&gt;
  The concept
  &lt;a class=&#34;anchor&#34; href=&#34;#the-concept&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In order to define the different &amp;ldquo;components&amp;rdquo; of the Go module, a &lt;code&gt;go.mod&lt;/code&gt; file
is listing other required modules, at the root of the defined module:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/myGoModule
  go.mod
  main.go
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;main.go&lt;/code&gt; is using &lt;code&gt;bar&lt;/code&gt; and &lt;code&gt;foo&lt;/code&gt; specific Go packages, &lt;code&gt;go.mod&lt;/code&gt; will list
those packages in order to fetch, download, and build them.&lt;/p&gt;
&lt;p&gt;For this example, in &lt;code&gt;go.mod&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;module github.com/unnamedUser/myGoModule // Define the package name

require (
  github.com/unnamedUser/bar v0.0.1 // I want the 0.0.1 version of bar...
  github.com/unnamedUser/foo v0.0.3 // ...and the specific 0.0.3 of foo!
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can observe here that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the module is named as your Go package;&lt;/li&gt;
&lt;li&gt;go packages have been imported automatically (last version) in the &lt;code&gt;require&lt;/code&gt; code block;&lt;/li&gt;
&lt;li&gt;indirect go packages are explicited (in order to verify the entier Go app later);&lt;/li&gt;
&lt;li&gt;the package version of each Go package is setted (and can be modified &lt;strong&gt;but you
have to respect the consistancy of the dependencies versions&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, if another user is trying to import/download/build your app, &lt;code&gt;go mod&lt;/code&gt; will
import the specific versions of your in-app packages.
Very nice!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-simple-example&#34;&gt;
  A simple example
  &lt;a class=&#34;anchor&#34; href=&#34;#a-simple-example&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To illustrate how to use &lt;code&gt;go mod&lt;/code&gt;, we will make a very simple exercise.&lt;/p&gt;
&lt;p&gt;Here, we want to create an HTTP server, that consumes a single route, &lt;code&gt;/proverb&lt;/code&gt;,
which returns a Go proverb as a string.
In order To do that, we will import the following packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;quote&lt;/code&gt;, in order to retrieve a Go proverb,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color&lt;/code&gt;, because we see the life in TRUUUUUUUUE COLOOOOOR&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ok, let&amp;rsquo;s create our Go package.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; mkdir -p /tmp/go_tests/httproverb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cd&lt;/span&gt; /tmp/go_tests/httproverb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, let&amp;rsquo;s initialize the
&lt;code&gt;go.mod&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; go mod init github.com/k0pernicus/httproverb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: creating new go.mod: module github.com/k0pernicus/hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using this command, go will create and initialize a &lt;code&gt;go.mod&lt;/code&gt; file that contains
only the name of the module, as we did not create our Go app.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create the main application, in &lt;code&gt;httproverb.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rsc.io/quote&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fatih/color&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hello&lt;/span&gt;(w http.ResponseWriter, r *http.Request) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Fprintf&lt;/span&gt;(w, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&amp;lt;h1&amp;gt;Hello user&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Tip: Why don&amp;#39;t you try /proverb ? :)&amp;lt;/p&amp;gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;proverbHandler&lt;/span&gt;(w http.ResponseWriter, r *http.Request) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  goProverb := quote.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Go&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Log the proverb (just to use color from fatih...)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  color.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Green&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;This is my new proverb: ’%s’&amp;#34;&lt;/span&gt;, goProverb)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Returned from the server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Fprintf&lt;/span&gt;(w, goProverb)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  http.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;HandleFunc&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;, hello)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  http.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;HandleFunc&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/proverb&amp;#34;&lt;/span&gt;, proverbHandler)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  log.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Fatal&lt;/span&gt;(http.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ListenAndServe&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;nil&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The architecture of our project is very simple because it contains only two files:
&lt;code&gt;go.mod&lt;/code&gt; and &lt;code&gt;httproverb.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we written the code of our Go app, let&amp;rsquo;s build it!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; go build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: finding github.com/fatih/color v1.7.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: downloading github.com/fatih/color v1.7.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;package main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: finding github.com/mattn/go-isatty v0.0.4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: finding github.com/mattn/go-colorable v0.0.9
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: downloading github.com/mattn/go-isatty v0.0.4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: downloading github.com/mattn/go-colorable v0.0.9
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# github.com/k0pernicus/hello&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you want to see where are stored those dependencies, you can list the files in
the go mod cache, in &lt;code&gt;$GOPATH/pkg/mod/&lt;/code&gt;, and &lt;em&gt;are postfixed with the dep version&lt;/em&gt;.
In you are wondering why &lt;code&gt;go mod&lt;/code&gt; is using is own cache, you can check the answer
from Ross Cox in &lt;a href=&#34;https://dave.cheney.net/2018/07/14/taking-go-modules-for-a-spin&#34;&gt;this article from Dave Cheney&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After playing a bit with the Go app, check the &lt;code&gt;go.mod&lt;/code&gt; app:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module github.com/k0pernicus/httproverb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;require (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	github.com/fatih/color v1.7.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	github.com/mattn/go-colorable v0.0.9 // indirect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	github.com/mattn/go-isatty v0.0.4 // indirect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	rsc.io/quote v1.5.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great!
Go has successfully listed our dependencies into the &lt;code&gt;go.mod&lt;/code&gt; file, without any help.&lt;/p&gt;
&lt;p&gt;Go contains a lot of subcommands in order to manage easily and properly the
dependencies, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;graph&lt;/code&gt; (print module requirement graph),&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tidy&lt;/code&gt; (remove unused modules),&lt;/li&gt;
&lt;li&gt;&lt;code&gt;why&lt;/code&gt; (explain why packages or modules are needed for this Go app),&lt;/li&gt;
&lt;li&gt;and many others (&lt;code&gt;go mod help&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-go-further&#34;&gt;
  To go further
  &lt;a class=&#34;anchor&#34; href=&#34;#to-go-further&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you want to take a look at a better/live example, please check a look at
the &lt;a href=&#34;https://github.com/davecheney/httpstat&#34;&gt;httpstat&lt;/a&gt; package from
&lt;a href=&#34;https://dave.cheney.net/&#34;&gt;Dave Cheney&lt;/a&gt;, a very famous Gopher.
Otherwise, if you want to know more about Go modules, please to read
&lt;a href=&#34;https://go.googlesource.com/proposal/+/master/design/24301-versioned-go.md&#34;&gt;the official proposal&lt;/a&gt; from the Go team.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Medium posts</title>
      <link>https://carette.xyz/posts/medium_posts/</link>
      <pubDate>Sat, 27 Oct 2018 01:23:11 +0200</pubDate>
      <guid>https://carette.xyz/posts/medium_posts/</guid>
      <description>&lt;p&gt;** Update 16th of February 2025 **&lt;/p&gt;
&lt;p&gt;Unfortunately two articles from DernierCri are now pointing to 404 pages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Déployer une app Phoenix sur Heroku, sans connaître Phoenix&amp;rdquo;,&lt;/li&gt;
&lt;li&gt;and &amp;ldquo;Cinq fausses idées sur le Big Data&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The article about the Julia programming language is still available, but it might be outdated.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I wrote a few articles for DernierCri about Big Data and Software Development &lt;a href=&#34;https://blog.derniercri.io/@k0pernicus&#34;&gt;on Medium&lt;/a&gt; in 2016 and 2018.&lt;/p&gt;
&lt;p&gt;Those blog articles has been written in French.&lt;br&gt;
This is the list of the blog posts I wrote:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://derniercri.io/blog/julia-le-langage-qui-les-reunifiera-tous&#34;&gt;Julia, le langage qui les réunifiera tous?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.derniercri.io/deployer-une-app-phoenix-sur-heroku-sans-connaitre-phoenix/&#34;&gt;&lt;del&gt;Déployer une app Phoenix sur Heroku, sans connaître Phoenix&lt;/del&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.derniercri.io/fausse-idees-sur-le-big-data/&#34;&gt;&lt;del&gt;Cinq fausses idées sur le Big Data&lt;/del&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The `go build` constraints</title>
      <link>https://carette.xyz/posts/go_build_feature/</link>
      <pubDate>Fri, 26 Oct 2018 18:56:18 +0200</pubDate>
      <guid>https://carette.xyz/posts/go_build_feature/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/go_build_constraint.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Credits to @ashleymcnamara &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Recently, I started to use &lt;a href=&#34;https://github.com/gizak/termui&#34;&gt;termui&lt;/a&gt; in order to build and run
a modular dashboard on the terminal.
This dashboard will display my daily todo list, some informations about my git projects/repositories,
some daily news, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;I use everyday: a macbook pro, and a GNU/Linux laptop - so, two different operating systems.&lt;/p&gt;
&lt;p&gt;Even if macOS and GNU/Linux share similar parts, those systems are strictly differents, and
I will have to compile the dashboard for each one.
No problem with cross-compilation, Go can handle that very quickly and simply via a compiler built-in option.
Nice!&lt;/p&gt;
&lt;p&gt;However, I quicky realized that I will have a trouble in specifying interruption handler path, for each of those
operating systems.&lt;/p&gt;
&lt;p&gt;Indeed, for termui, Linux can simply handle the letter key &lt;code&gt;q&lt;/code&gt; to quit the program manually.
For macOS, unfortunately, we must to complete the command using the full path to keyboard command &lt;code&gt;/sys/kbd/q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As a result, the full path does not works on my GNU/Linux system, and vice-versa.&lt;/p&gt;
&lt;p&gt;Multiple solutions can be used in order to solve this problem, but my solution here is to define
a constant for each keyboard command, for GNU/Linux and macOS, and let the compiler decide which one to
use according to the current operating system.
At this moment, I discovered the &lt;strong&gt;build constraints&lt;/strong&gt; feature of Go.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-is-build-&#34;&gt;
  What is &lt;code&gt;build&lt;/code&gt; ?
  &lt;a class=&#34;anchor&#34; href=&#34;#what-is-build-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;build&lt;/code&gt; is a Go package, available in the standard library.
The main goal of the package is to gather information about Go packages, and includes several options and
features in order to do that.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;how-a-go-project-is-organized&#34;&gt;
  How a Go project is organized?
  &lt;a class=&#34;anchor&#34; href=&#34;#how-a-go-project-is-organized&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Go is a compiled programming language.
The Go compiler takes as input a source code, and return binary (or machine) code (after several internal
processes) for the architecture you specified (or you are using).&lt;/p&gt;
&lt;p&gt;In order to produce the binary code, the compiler needs several iterations to build some parts of the projects, as
binary objects, to reassemble them later in order to produce the main binary.&lt;/p&gt;
&lt;p&gt;Here, in order to use specific code for a given hardware architecture, we want to introduce &lt;em&gt;compiler conditions&lt;/em&gt;.
For the compiler, those conditions will permit to build specific binary objects according to a given architecture, and produce
a final binary code fully compatible with the given architecture.&lt;/p&gt;
&lt;p&gt;Those compiler conditions are presents in Go under the name of &amp;ldquo;build tags&amp;rdquo;, or &amp;ldquo;build constraints&amp;rdquo;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-concrete-example&#34;&gt;
  A concrete example
  &lt;a class=&#34;anchor&#34; href=&#34;#a-concrete-example&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This is the tree of our Go project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  src/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    myproject/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      kbd_linux.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      kbd_macos.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      main.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  bin/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ./myproject
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For those directives, or compiler conditions, Go does not have a preprocessor, a macro system, or a C-like #define declaration.
Instead, Go is using a naming system convention, supported by the go tool.&lt;/p&gt;
&lt;p&gt;So, compiler conditions will be defined as comments, in the first lines of the go file.&lt;/p&gt;
&lt;p&gt;We will include the build constraints in &lt;code&gt;kbd_linux.go&lt;/code&gt; and &lt;code&gt;kdb_macos.go&lt;/code&gt; for, respectively, GNU/Linux and macOS,
and let the compiler decides which one to use using the &lt;code&gt;// +build&lt;/code&gt; directive.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s build our specific GNU/Linux build tag file.
In &lt;code&gt;kbd_linux.go&lt;/code&gt;, we can write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// +build linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Route correctly for Linux machines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; QUIT = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;q&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, the &lt;code&gt;QUIT&lt;/code&gt; keyboard event path will point to the simple path &amp;ldquo;q&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;For macOS, in &lt;code&gt;kbd_darwin.go&lt;/code&gt;, we can write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// +build darwin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// Route correctly for darwin machines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;const&lt;/span&gt; QUIT = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/sys/kbd/q&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, we define the same constant &lt;code&gt;QUIT&lt;/code&gt; but we point it to another kernel path.&lt;/p&gt;
&lt;p&gt;You can notice we &lt;em&gt;defined&lt;/em&gt; the same constant in each file.
This is not an issue at all because the compiler will choose one of those files to
build the binary, at compile time.
So, &lt;code&gt;QUIT&lt;/code&gt; will &lt;em&gt;never&lt;/em&gt; be erased or overrided at any time by the compiler.&lt;/p&gt;
&lt;p&gt;Finally, in &lt;code&gt;main.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;package&lt;/span&gt; main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ui &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;github.com/gizak/termui&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  err := ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Init&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;panic&lt;/span&gt;(err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;defer&lt;/span&gt; ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p := ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;NewPar&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:PRESS q TO QUIT&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p.Height = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p.Width = 50
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p.TextFgColor = ui.ColorWhite
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p.BorderLabel = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Text Box&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p.BorderFg = ui.ColorCyan
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Render&lt;/span&gt;(p)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Handle&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;q&amp;#34;&lt;/span&gt;, &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;func&lt;/span&gt;(ui.Event) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// At compilation time,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// QUIT will be replaced by the value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// corresponding of the correct source code file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// according to the current operating system.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Println&lt;/span&gt;(QUIT)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;StopLoop&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ui.&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Loop&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As the compiler will choose one of the &lt;code&gt;kbd_&amp;lt;&amp;gt;.go&lt;/code&gt; file, it will create an internal
package for the &lt;code&gt;main.go&lt;/code&gt; source code file, and substitutes the &lt;code&gt;QUIT&lt;/code&gt; constant to the &lt;code&gt;kbd_&amp;lt;&amp;gt;.go&lt;/code&gt; one.&lt;/p&gt;
&lt;p&gt;To check which go files will be included in the binary, you can use &lt;code&gt;go list&lt;/code&gt; to get the names of the files that would be compiled: &lt;code&gt;go list -f &#39;{{.GoFiles}}&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Simple and with a negligible loss of performance in the compilation, this solution
permits to specify architecture conditions to build a specific binary, while ensuring
a minimum of security in its Go app.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-go-further&#34;&gt;
  To Go further
  &lt;a class=&#34;anchor&#34; href=&#34;#to-go-further&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://golang.org/pkg/go/build/&#34;&gt;Package build - online official documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=-XSlev-d7UY&#34;&gt;justforfunc: Versions, build constraints, and ldflags&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The &#39;intelligence&#39; problem in &#39;artificial intelligence&#39;</title>
      <link>https://carette.xyz/posts/the_intelligence_problem/</link>
      <pubDate>Sat, 22 Sep 2018 13:38:34 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_intelligence_problem/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/intelligence_problem.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; XKCD - Artificial Intelligence &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The more I listen AI enthousiastic people, the more I can differenciate them in &amp;lsquo;10&amp;rsquo; very different groups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;people who think that AI is a synonym of &amp;ldquo;strong black magic&amp;rdquo;;&lt;/li&gt;
&lt;li&gt;people who are amazed by AI because &amp;ldquo;come on dude&amp;hellip; it&amp;rsquo;s just maths!&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is something wrong with &amp;ldquo;Artificial Intelligence&amp;rdquo;&amp;hellip;
I don&amp;rsquo;t speak about some tech, just the term.&lt;/p&gt;
&lt;p&gt;Let me explain why, in three different points.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-human-feeling&#34;&gt;
  The human feeling
  &lt;a class=&#34;anchor&#34; href=&#34;#the-human-feeling&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My teachers always told me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People think a task is not valuable as &amp;lsquo;intelligent&amp;rsquo; as soon a machine can do it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But&amp;hellip; are we training machines to do something intelligent?&lt;/p&gt;
&lt;p&gt;A few years ago, top HackerNews articles were about separating muffins and chiwawa,
playing go as an expert, or detecting earlier agressive cancers.
Are people intelligent because we can differenciate muffins and chiwawa?&lt;/p&gt;
&lt;p&gt;Personally, I don&amp;rsquo;t think so&amp;hellip;
If you take the cancer example, we are actually transform a computer into a cancerologist expert, &lt;em&gt;to help him&lt;/em&gt;.
And if you take the go example, we are actually transform a computer into a go expert player.&lt;/p&gt;
&lt;p&gt;The same key between those two examples is &amp;ldquo;turning a machine into an expert of [put something here]&amp;rdquo;, and that is what
AI is doing: to automatize tasks using an expert system.
Also, if we discuss about Machine Learning, we are using concrete examples to let the computer infer the pattern in order
to be an expert system.
Those data are processed by experts first, in order to clean them, and improve the score of the ML algorithm.&lt;/p&gt;
&lt;p&gt;There is nothing &amp;ldquo;intelligent thing&amp;rdquo; here.
We are trying to &lt;strong&gt;automatize&lt;/strong&gt; &lt;em&gt;something&lt;/em&gt; to save time, and/or save resources.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-ai-paradox&#34;&gt;
  The AI paradox
  &lt;a class=&#34;anchor&#34; href=&#34;#the-ai-paradox&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Two years ago, I discussed with my thesis supervisor about optimizing a task using Machine Learning, and I explained
that, with good features and intuition, I thought a logistic regression on the features could make real good predictions.
But, suddenly, he laughed really hard because he didn&amp;rsquo;t understand why a logistic regression is classified as a machine learning algorithm as it&amp;rsquo;s Texas Instrument
calculator could do the same thing.&lt;/p&gt;
&lt;p&gt;The question behind this story is: &amp;ldquo;Can we restrict AI to algorithms that run only on strong hardware?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Short response: &lt;strong&gt;of course not&lt;/strong&gt;.
AI is based on simple algorithms, and simple paradigms, that can run on powerless hardware.
I agree that, today, a lot of complex algorithms are used to solve simple and complex
tasks: bagging and boosting algorithms, or neural networks for example.&lt;/p&gt;
&lt;p&gt;But to minimize AI as &amp;ldquo;complex algorithms&amp;rdquo; is totally wrong.
&lt;strong&gt;The algorithm used to solve a task is not the most important task in Data Science, it&amp;rsquo;s feature engineering!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-automaticautomatize-confusion&#34;&gt;
  The &amp;ldquo;automatic&amp;rdquo;/&amp;ldquo;automatize&amp;rdquo; confusion
  &lt;a class=&#34;anchor&#34; href=&#34;#the-automaticautomatize-confusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Many people think that AI is a magic process to learn something to a computer.
For those people, AI is a big black box which takes as input data, and output a value.
If we follow this idea, I really don&amp;rsquo;t know why we need Data Scientists today&amp;hellip;&lt;/p&gt;
&lt;p&gt;Obviously, this statement is not correct - you can just train &amp;ldquo;something&amp;rdquo; on data without any interessment, but you will fail in the training process (otherwise, you are &lt;em&gt;very&lt;/em&gt; lucky).&lt;/p&gt;
&lt;p&gt;Actually, people are really confused between &amp;ldquo;automatic&amp;rdquo; and &amp;ldquo;automatize&amp;rdquo;.
Computers &lt;strong&gt;don&amp;rsquo;t&lt;/strong&gt; automatically learn something - &lt;strong&gt;we train them&lt;/strong&gt; using data for a given task.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;goal&lt;/em&gt; of Machine Learning is to &lt;em&gt;automatize&lt;/em&gt; a process using data.
And there is no magic in the training, just mathematics&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;algorithms-for-automatization-&#34;&gt;
  Algorithms for Automatization ?
  &lt;a class=&#34;anchor&#34; href=&#34;#algorithms-for-automatization-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;For me, &amp;ldquo;intelligence&amp;rdquo; and &amp;ldquo;automatic&amp;rdquo; are two strong words to avoid we talk about AI.
As the main goal of AI is to automatize some taks using algorithms&amp;hellip; why not &amp;ldquo;Algorithms for Automatization&amp;rdquo;?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pyenv</title>
      <link>https://carette.xyz/posts/pyenv/</link>
      <pubDate>Sun, 22 Jul 2018 14:01:43 +0200</pubDate>
      <guid>https://carette.xyz/posts/pyenv/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/pyenv_cover.png#small&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Credits to XKCD &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;I write Python code each day, for personal and professional projects.
As I am working on multiple Python projects, old and fresh ones, I have to use different Python versions for those projects, from &lt;code&gt;2.7.2&lt;/code&gt; to &lt;code&gt;3.7.0&lt;/code&gt;.
Also, I want to switch the Python version of my projects very easily and quickly, in case of we have to upgrade the Python version of the software.&lt;/p&gt;
&lt;p&gt;I am a macOS user, and I use &lt;em&gt;a lot&lt;/em&gt; &lt;a href=&#34;https://brew.sh/&#34;&gt;HomeBrew&lt;/a&gt;.
Unfortunately, HomeBrew is not a great solution to keep a trace of multiple versions of a given build (especially the interpreters)&amp;hellip;
I can take a look at each source code in &lt;a href=&#34;https://python.org&#34;&gt;python.org&lt;/a&gt;, download the one a want, build it, and set manually all my paths in order to retrieve the Python version I want for a given project.
But, we are in 2018, and I figured that someone already automatized this thing.&lt;/p&gt;
&lt;p&gt;I was right.&lt;/p&gt;
&lt;p&gt;This tool is called &lt;code&gt;pyenv&lt;/code&gt;, and is a very simple Python package manager for &lt;em&gt;UNIX-like systems&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-is-pyenv&#34;&gt;
  What is &lt;code&gt;pyenv&lt;/code&gt;
  &lt;a class=&#34;anchor&#34; href=&#34;#what-is-pyenv&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;pyenv&lt;/code&gt; is a Python package manager, focused on the interpreter and famous Python associated tools (&lt;code&gt;easy_install&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;, etc&amp;hellip;).
&lt;code&gt;pyenv&lt;/code&gt; was originally forked from &lt;code&gt;rbenv&lt;/code&gt; and &lt;code&gt;ruby-build&lt;/code&gt; for Ruby, and modified for Python.
The project is composed, principaly, by shell scripts, and totalized nearly 12,000 stars on Github on 22th of July, 2018.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;installation-of-pyenv&#34;&gt;
  Installation of &lt;code&gt;pyenv&lt;/code&gt;
  &lt;a class=&#34;anchor&#34; href=&#34;#installation-of-pyenv&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;For macOS, using &lt;a href=&#34;https://brew.sh/&#34;&gt;HomeBrew&lt;/a&gt;, the installation of &lt;code&gt;pyenv&lt;/code&gt; is very simple: &lt;code&gt;brew update &amp;amp;&amp;amp; brew install pyenv&lt;/code&gt;.
That&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;If you are not on macOS, or if you don&amp;rsquo;t want to use HomeBrew for that, you can check &lt;a href=&#34;https://github.com/pyenv/pyenv-installer&#34;&gt;the automatic installer&lt;/a&gt; on Github.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pyenv&lt;/code&gt; uses an internal system calls &lt;code&gt;shims&lt;/code&gt; to enable the search of the Python interpreters (and associated tools), and enable autocompletion.
In order to use those binaries, you just have to enable shims and autocompletion using &lt;code&gt;eval &amp;quot;$(pyenv init -)&amp;quot;&lt;/code&gt; (remember to add this line on your &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Ok - now, &lt;code&gt;pyenv&lt;/code&gt; is installed on the system&amp;hellip;but there is no interpreter on your system yet.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;promises&#34;&gt;
  Promises
  &lt;a class=&#34;anchor&#34; href=&#34;#promises&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;install-a-toolchain&#34;&gt;
  Install a toolchain
  &lt;a class=&#34;anchor&#34; href=&#34;#install-a-toolchain&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, you have to install a given Python ecosystem version (interpreter, and associated tools) on your system.
If you check first the versions you have installed, using &lt;code&gt;pyenv versions&lt;/code&gt;, the output is empty.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/em&gt;: Along the &lt;code&gt;versions&lt;/code&gt; option, there exists the &lt;code&gt;version&lt;/code&gt; option. &lt;code&gt;versions&lt;/code&gt; returns the toolchains you installed on the system, but &lt;code&gt;version&lt;/code&gt; returns the toolchain(s) you are &lt;em&gt;using&lt;/em&gt; on the current session.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s try to install the version &lt;code&gt;2.7.15&lt;/code&gt; of Python:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ pyenv install 2.7.15
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-2.7.15.tar.xz...
-&amp;gt; https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tar.xz
Installing Python-2.7.15...
python-build: use readline from homebrew
Installed Python-2.7.15 to /Users/acarette/.pyenv/versions/2.7.15
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you&amp;rsquo;ve seen, &lt;code&gt;pyenv&lt;/code&gt; will download the &lt;code&gt;2.7.15&lt;/code&gt; version of Python directly from the official Python servers, and will compile and install the binary directly &lt;em&gt;for&lt;/em&gt; your system, on your system.
If you are wondering where is the build, you can check the folder &lt;code&gt;.pyenv/shims&lt;/code&gt; in your &lt;code&gt;$HOME&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s install the &lt;code&gt;3.4&lt;/code&gt; version:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ pyenv install 3.4
python-build: definition not found: 3.4

The following versions contain `3.4&amp;#39; in the name:
  3.3.4
  3.4.0
  3.4-dev
  3.4.1
  3.4.2
  3.4.3
  3.4.4
  3.4.5
  3.4.6
  3.4.7
  3.4.8
  miniconda-3.4.2
  miniconda3-3.4.2
  stackless-3.4-dev
  stackless-3.4.1
  stackless-3.4.2
  stackless-3.4.7
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Oups - what the problem here?
The problem is we were not specific at all, when we asked to install the &lt;code&gt;3.4&lt;/code&gt; toolchain.
Indeed, the &lt;code&gt;3.4&lt;/code&gt; version is a major version of Python 3, and there exists multiple minor versions of &lt;code&gt;3.4&lt;/code&gt;.
So, &lt;code&gt;pyenv&lt;/code&gt; was asking to specify the minor version of the major version we asked for: &lt;code&gt;pyenv install 3.4.8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/em&gt;: If you look more closely at the error message, you can see that you can install multiple versions of &lt;code&gt;anaconda&lt;/code&gt; via &lt;code&gt;pyenv&lt;/code&gt; - so, &lt;em&gt;the tool is not exclusive to Python builds but the Python ecosystem&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;global-usage-of-a-toolchain&#34;&gt;
  Global usage of a toolchain
  &lt;a class=&#34;anchor&#34; href=&#34;#global-usage-of-a-toolchain&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you have more than 50% of your Python projects that are using the same specific version of Python, maybe you want to use this version as a global one on your system.
&lt;code&gt;pyenv&lt;/code&gt; can override the &lt;em&gt;default&lt;/em&gt; Python version of your projects using the &lt;code&gt;global&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;So, if you want to use the &lt;code&gt;3.4.8&lt;/code&gt; version of Python as the default one, ask to &lt;code&gt;pyenv&lt;/code&gt; to override it: &lt;code&gt;pyenv global 3.4.8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that Python 3 is different than Python 2 (actually, it may be a new programming language by itself&amp;hellip;), maybe you want to override a default toolchain for Python 2 and for Python 3 too.
You can do that using &lt;code&gt;pyenv global 2.7.15 3.4.8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using this feature, when you want to use &lt;code&gt;python2&lt;/code&gt;, it will reach Python &lt;code&gt;2.7.15&lt;/code&gt;.
Also, if you want to use &lt;code&gt;python3&lt;/code&gt;, it will reach Python &lt;code&gt;3.4.8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can see this behaviour on typing &lt;code&gt;pyenv version&lt;/code&gt; (*no &lt;code&gt;s&lt;/code&gt; at the end of &lt;code&gt;version&lt;/code&gt;!):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ pyenv version
2.7.15 (set by /Users/acarette/.pyenv/version)
3.4.8 (set by /Users/acarette/.pyenv/version)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, what happen when we want to use &lt;code&gt;python&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;When we asked to override the default toolchains, we gave to &lt;code&gt;pyenv&lt;/code&gt; an order: &lt;code&gt;2.7.15&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; &lt;code&gt;3.4.8&lt;/code&gt;.
So, using this configuration, it will reach Python &lt;code&gt;2.7.15&lt;/code&gt; first.
If you want to override this behaviour, in using Python 3 instead of Python 2, you can do that switching the previous versions: &lt;code&gt;pyenv global 3.4.8 2.7.15&lt;/code&gt;.
Using this configuration, if you launch &lt;code&gt;python&lt;/code&gt;, it will be the &lt;code&gt;3.4.8&lt;/code&gt; toolchain:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ pyenv version
3.4.8 (set by /Users/acarette/.pyenv/version)
2.7.15 (set by /Users/acarette/.pyenv/version)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&#34;heading&#34; id=&#34;local-usage-of-a-toolchain&#34;&gt;
  Local usage of a toolchain
  &lt;a class=&#34;anchor&#34; href=&#34;#local-usage-of-a-toolchain&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The previous section explains how to define &lt;em&gt;defaults&lt;/em&gt; toolchains in the entire system.
Now, what if you want to work using different toolchains, on different projects?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pyenv&lt;/code&gt; can override the default Python toolchain for a given path (or project), creating a &lt;code&gt;.python-version&lt;/code&gt; file at the root of your Python project.
To do that, you need the &lt;code&gt;local&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;So, using the &lt;code&gt;local&lt;/code&gt; command, on a local project, each time I will want to use &lt;code&gt;python&lt;/code&gt;, the &lt;code&gt;shims&lt;/code&gt; will check if an overrided Python version has been done &lt;em&gt;for this project&lt;/em&gt;.
If a &lt;code&gt;.python-version&lt;/code&gt; file exists in the current project, &lt;code&gt;pyenv&lt;/code&gt; will launch the toolchain described in the file.
Otherwise, &lt;code&gt;pyenv&lt;/code&gt; will execute the first default toolchain.&lt;/p&gt;
&lt;p&gt;Ok, let&amp;rsquo;s try:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ mkdir -p Code/pyenv_test
~ cd Code/pyenv_test
~ pyenv version
3.4.8 (set by /Users/acarette/.pyenv/version)
2.7.15 (set by /Users/acarette/.pyenv/version)
~ pyenv local 3.6.2
~ pyenv version
3.6.2 (set by /Users/acarette/Code/pyenv_test/.python-version)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/em&gt;: like the &lt;code&gt;global&lt;/code&gt; option, multiple Python versions: &lt;code&gt;pyenv local 2.7.15 3.4.8&lt;/code&gt;, with the same priorities than before.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;interactive-usage-of-a-toolchain&#34;&gt;
  Interactive usage of a toolchain
  &lt;a class=&#34;anchor&#34; href=&#34;#interactive-usage-of-a-toolchain&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Python is a dynamic and interactive programming language and, sometimes, you just want to check &lt;em&gt;something&lt;/em&gt; in the standard library, or just try to hack &lt;em&gt;something&lt;/em&gt; on the interpreter.&lt;/p&gt;
&lt;p&gt;Just imagine you are working on a given project, using the latest version of Python, when a colleague ask you to verify a very small piece of code using the version &lt;code&gt;3.6.2&lt;/code&gt; of Python - maybe because something is struggling with the library standard of this specific version.
The code to test is so small that it would be overkill to create a virtual environment to test it, and to put in on a &lt;code&gt;totest.py&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;No, you want to test the code &lt;em&gt;in a Python interpreter&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Currently, using &lt;code&gt;global&lt;/code&gt; and &lt;code&gt;local&lt;/code&gt;, you can&amp;rsquo;t do that.
So, &lt;code&gt;pyenv&lt;/code&gt; contributors added the &lt;code&gt;shell&lt;/code&gt; option, in order to launch a specific version of Python &lt;em&gt;in your current shell session&lt;/em&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~ pyenv version
3.4.8 (set by /Users/acarette/.pyenv/version)
2.7.15 (set by /Users/acarette/.pyenv/version)
~ python -V
Python 3.4.8
~ pyenv shell 3.6.2
~ python -V
Python 3.6.2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty convenient, isn&amp;rsquo;t it?? :)&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;anchor&#34; href=&#34;#conclusion&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As you noticed in the &lt;em&gt;Promises&lt;/em&gt; section, &lt;code&gt;pyenv&lt;/code&gt; offers great features to work easily with different Python toolchains, without scratching your head on how you can install different versions of Python in your system, for a given project.
Of course, &lt;code&gt;pyenv&lt;/code&gt; is not perfect - I still wait to install a toolchain &lt;em&gt;only&lt;/em&gt; for a specific project, and let the tool to drop out the version if I delete the project - but it&amp;rsquo;s a very good beginning in managing your Python toolchains.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>It&#39;s all about community</title>
      <link>https://carette.xyz/posts/its_all_about_community/</link>
      <pubDate>Mon, 15 Jan 2018 00:00:00 +0200</pubDate>
      <guid>https://carette.xyz/posts/its_all_about_community/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s on - my first blog post for 2018!&lt;/p&gt;
&lt;p&gt;All my best wishes for this new year, about love, health, and love (quoting Patrick Sebastien, &amp;ldquo;&lt;em&gt;love is everything&lt;/em&gt;&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Ok, let&amp;rsquo;s talk about something more serious&amp;hellip;
Today, I want to talk about &lt;em&gt;Rust&lt;/em&gt;. Yes, &lt;em&gt;Rust&lt;/em&gt;, again. But this time it&amp;rsquo;s not about something I discovered, implemented or anything along the lines&amp;hellip;
You know, during the two last years, I tried to &amp;ldquo;promote&amp;rdquo; this programming language everywhere, because I strongly believe in &lt;em&gt;Rust&lt;/em&gt;. I made two different talks at two meetups in Lille, attended to several &lt;em&gt;Rust&lt;/em&gt; events and conferences, and each time I was thinking about how awesome the &lt;em&gt;Rust&lt;/em&gt; community is. And now it&amp;rsquo;s time to make a blog post for this.
So, I want to talk from the heart about the &lt;em&gt;Rust&lt;/em&gt; community, and how it is awesome to see people building an awesome project together.&lt;/p&gt;
&lt;p&gt;Do note that, sometimes, I use the word &amp;ldquo;&lt;em&gt;we&lt;/em&gt;&amp;rdquo; to design the &lt;em&gt;Rust&lt;/em&gt; community, and &lt;em&gt;this blog article reflects only &lt;strong&gt;my&lt;/strong&gt; feelings&lt;/em&gt; as a &lt;em&gt;Rust&lt;/em&gt; fan since 2015.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;people-are-all-equal&#34;&gt;
  People are all equal
  &lt;a class=&#34;anchor&#34; href=&#34;#people-are-all-equal&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The first thing I noticed initially when starting with &lt;em&gt;Rust&lt;/em&gt; is how the community is mature.
I think that the maturity came because: 1) the community is pretty small, 2) every member shares the idea that &lt;strong&gt;people are all equal&lt;/strong&gt;.
The strongest rule of the community is that &lt;em&gt;every member of the community must respects the other ones, and don&amp;rsquo;t be toxic to each other&lt;/em&gt;. This is, I think, the core of the current community, and it encourages people to never be afraid posting something, or to ask for help in a problem that they think is dumb (&lt;strong&gt;remember that no question is stupid - no one&lt;/strong&gt;).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;people-are-everything&#34;&gt;
  People are everything
  &lt;a class=&#34;anchor&#34; href=&#34;#people-are-everything&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Some developers are unhappy that the Mozilla Foundation is sponsoring &lt;em&gt;Rust&lt;/em&gt;, because they think that its future will only focus on what Mozilla products need, and not on what &lt;em&gt;Rust&lt;/em&gt; developers need.
It is true that this kind of incidents happen (actually, it had happened in the past and continues to happen even now), but, here, it&amp;rsquo;s totally different.
Some of the &lt;em&gt;Rust&lt;/em&gt; maintainers are hired by Mozilla but, every day, those persons are listening to your needs and your ideas (via public RFCs), asking what you wanna do with &lt;em&gt;Rust&lt;/em&gt;, how to help you with your daily issues, or how can they improve the language for your projects.
&lt;em&gt;This&lt;/em&gt; is making the difference, because benefits happen in both directions: you, as a developer, feel integrated into the community, and the language can evolve and become even richer for everyone.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-perfect-place-to-learn&#34;&gt;
  A perfect place to learn
  &lt;a class=&#34;anchor&#34; href=&#34;#a-perfect-place-to-learn&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The &lt;em&gt;Rust&lt;/em&gt; community strongly encourages the &amp;ldquo;newbies&amp;rdquo; to learn Rust, and we (members of the community) are here to help them in order to build and deploy in the most simplest possible way their project(s), simply because &lt;strong&gt;we believe in people&lt;/strong&gt;.
At this moment, 1,985 people have already contributed to the &lt;em&gt;Rust&lt;/em&gt; compiler on &lt;a href=&#34;https://github.com/rust-lang/rust&#34;&gt;github&lt;/a&gt;, for 50 releases and 73,379 commits, which is a huge success for an Open Source project.
Just to compare with another Open Source programming language, 985 persons have contributed to the Go compiler, for 202 releases and 35,115 commits.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;freedom-and-excitement-of-exchanges&#34;&gt;
  Freedom and excitement of exchanges
  &lt;a class=&#34;anchor&#34; href=&#34;#freedom-and-excitement-of-exchanges&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Each week, I see on Twitter, Slack and IRC &lt;em&gt;Rust&lt;/em&gt; developers posting blog articles, the crate(s) they are developing, or the couple of issues they are/were working on (and some hints to solve them).
Do note that you don&amp;rsquo;t need to be a Rust wizard to propose an idea, and you should &lt;strong&gt;not&lt;/strong&gt; be afraid to share something!
Being afraid to post something on the Internet is actually the most common barrier to freedom - so, please, feel free to share whatever you want!
Also, some &lt;em&gt;Rust&lt;/em&gt; projects have become important now, because of the community&amp;rsquo;s support.&lt;/p&gt;
&lt;p&gt;So, to conclude: feel free to join us, to discuss and to share your thoughts or ideas!
We want to hear you to improve this fantastic project, because we strongly believe you can! :-)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thanks to Alexandre and Sankalp for the English review, and a special thanks to Xavier for pushing me (every week) in writing blog posts.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Rustfest, an amazing experience</title>
      <link>https://carette.xyz/posts/rustfest_an_amazing_experience/</link>
      <pubDate>Sun, 01 Oct 2017 09:09:11 +0200</pubDate>
      <guid>https://carette.xyz/posts/rustfest_an_amazing_experience/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://zurich.rustfest.eu/&#34;&gt;RustFest&lt;/a&gt; is an European event to attempt general talks about Rust, and to meet people from the Rust community.&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/rustfest-badge.jpg&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Rustfest 2017 badge &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;RustFest&lt;/em&gt; is a two-days event.
The first day is a series of talks from the Rust team (in Mozilla) and, predominantly, the Rust community about: the past and the future of the programming language, POCs, how to deal with macros, awesome new projects like 3D games, a gently introduction for developing 2D games (and how easy is it), why a company choosed to move their tech stack to Rust, etc.
Each talk was a lesson: how to deal with a &amp;ldquo;rust-matic&amp;rdquo; problem, how to manage your project, how to deal with this feature, or how to present a complex subject to a various auditory.&lt;/p&gt;
&lt;p&gt;Each people I discussed with was a huge wealth of wisdom, experience and knowledge.
I discussed, drink beers, and eat (expensive) burgers, with incredible guys from France, Switzerlang, Great Britain, Germany, Sweden, Poland, Russia, United States of America, and many other countries!&lt;/p&gt;
&lt;p&gt;To me, this first day of RustFest was more than a talks day, it was an epiphany.
&lt;em&gt;Rust brings us more than just incredible technology, it brings us a family&lt;/em&gt;.
Thanks to this event, I remembered why I love Rust, and why this programming language is, actually, my favorite one.
After making &lt;a href=&#34;https://github.com/k0pernicus/zou&#34;&gt;Zou&lt;/a&gt; awesome, I plan to begin to contribute to a big &amp;ldquo;Rust product&amp;rdquo;: &lt;a href=&#34;https://servo.org/&#34;&gt;Servo&lt;/a&gt;, thanks to Simon Sapin.&lt;/p&gt;
&lt;p&gt;Also, Zürich is such a beautiful place to host this kind of event.&lt;/p&gt;
&lt;p&gt;Thanks a lot to the awesome speakers: Felix Klock, Élisabeth Henry, Geoffroy Couprie (your love for macros is insane man! :-)), Alex Burka, Mohammed Makhlouf, Thomas Wickham, Igor Matuszewski, Niklas Adolfsson, Andrea Lattuada, Jorge Aparicio (aka &amp;ldquo;the-awesome-japaric&amp;rdquo;), Pierre Krieger, Andre &amp;ldquo;the poet&amp;rdquo; Bogus, Lisa, Fedor Logachev, and Anselm Eickhoff, thanks for the RustFest crew (I don&amp;rsquo;t have your names, but I love you guys &amp;lt;3), the sponsors and all the people and institutions who helped in creating, promoting, and maintaining the event.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t change, you&amp;rsquo;re awesome 😘&lt;/p&gt;
&lt;p&gt;In Rust, We Trust 🤘&lt;/p&gt;
&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/rustfest.jpeg&#34; &gt;
    &lt;/div&gt;

    
    &lt;div class=&#34;caption-container&#34;&gt;
        &lt;figcaption&gt; Rustfest participants &lt;/figcaption&gt;
    &lt;/div&gt;
    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Credits for this picture: the RustFest team&lt;/em&gt;
&lt;a href=&#34;https://twitter.com/RustFest/status/914073968235163648&#34;&gt;Original tweet here&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is research innovation still belongs to Universities ?</title>
      <link>https://carette.xyz/posts/is_research_innovation_still_belongs_to_universities/</link>
      <pubDate>Sat, 24 Jun 2017 08:02:35 +0000</pubDate>
      <guid>https://carette.xyz/posts/is_research_innovation_still_belongs_to_universities/</guid>
      <description>&lt;p&gt;I started my PhD two months ago, on automated ways to classify documents, and I begin to be depressed&amp;hellip;&lt;/p&gt;
&lt;p&gt;Since I started University in Computer Science, I wanted to do a PhD in biocomputing, combinatorial optimization, or machine learning.
In CS class, Machine learning was the area I enjoyed the most - so it was natural to look for a PhD in ML.
For me, research activities conduct to new innovative techniques, or tools, which have to be tested on real world examples.&lt;/p&gt;
&lt;p&gt;As a good PhD student, I started my start-of-the-art and I began to experiment two or three ideas.
So, I read about 50 or 60 research articles about new ways to classify documents, and text understanding.&lt;/p&gt;
&lt;p&gt;The research articles I read in the area of machine learning came, in large majority, from web giants: Google, Facebook, Amazon, Baidu, Criteo&amp;hellip;, but also from companies or startups which are related to those giants, like DeepMind.
These research articles propose new approaches to classify text documents, and new ways to understand, and translate, documents.
Those approaches have been tested on a massive dataset, and clearly outperform existing methods.
Also, at NIPS (one of the greatest conference about machine learning and computational neuroscience), companies owned about 50% of accepted papers.&lt;/p&gt;
&lt;p&gt;Now, I am wondering if innovative things in this research area still belong to Universities.&lt;/p&gt;
&lt;p&gt;Maybe you are wondering why those companies are &lt;em&gt;first&lt;/em&gt;, in this area.
This is my answer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They have massive datasets of real world examples,&lt;/li&gt;
&lt;li&gt;They have tech&amp;rsquo; (for example, the last chip from Google for DL, which is just amazing),&lt;/li&gt;
&lt;li&gt;They own, or the work with, the best research scientists in AI (Y. LeCun, A. Ng, H. Larochelle&amp;hellip;),&lt;/li&gt;
&lt;li&gt;They have the best engineers who are working hard on this subject,&lt;/li&gt;
&lt;li&gt;They can test their idea directly on well designed products, faster than light.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I realized, during my previous internships, that there is a hard competition between research institutions and companies.
Some research institutions, like inria, share the idea that a research idea can be part of a great product - so, they propose to scientists to share ideas with startups, or to create their own startup.
It&amp;rsquo;s the same thing in University of Luxembourg - for example, the DataThings startup has been funded thanks to the research ideas of a great team of scientists who are working on real time data series.
So, research institutions are moving from pure research to applied research, and it&amp;rsquo;s great !
But, is this change not too late ?
And is AI research area already belongs to giants ?&lt;/p&gt;
&lt;p&gt;I know that companies, especially today with DL, would not have done these wonderful tools/products without research scientists.
But I am sad those research scientists are now owned by private companies, to conduct internal research.&lt;/p&gt;
&lt;p&gt;I am &lt;strong&gt;really&lt;/strong&gt; scared that my work and research ideas are became soon &lt;em&gt;outdated&lt;/em&gt;, because of a technology that exists since a few years, but has not been released yet due to private IPs or something like that.
Also, how can you be peaceful if you know that companies can explore, implement a solution and draft a paper about it faster than you ?&lt;/p&gt;
&lt;p&gt;Actually, &lt;strong&gt;I am&lt;/strong&gt; depressed&amp;hellip; but I am not giving up.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My new year&#39;s resolutions</title>
      <link>https://carette.xyz/posts/my_new_years_resolutions/</link>
      <pubDate>Mon, 02 Jan 2017 19:32:13 +0100</pubDate>
      <guid>https://carette.xyz/posts/my_new_years_resolutions/</guid>
      <description>&lt;p&gt;Happy new year !&lt;/p&gt;
&lt;p&gt;I hope that 2016 has been great for you.
For me, 2016 was mixed: good (my internship at Montreal, my graduation and a pretty cool job) and bad times (many assassination attempts and, obviously, the election of Trump).&lt;/p&gt;
&lt;p&gt;This year, we increment (again) the counter, and pass from 2016 to 2017, and
I hope that this new year will be full of &lt;strong&gt;love&lt;/strong&gt;, &lt;strong&gt;tolerance&lt;/strong&gt; and &lt;strong&gt;respect&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this blog post, I show you my personal resolutions for 2017.
Because, as you know, a new year comes new resolutions !&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;a-healthy-spirit-in-a-healthy-body&#34;&gt;
  A healthy spirit in a healthy body
  &lt;a class=&#34;anchor&#34; href=&#34;#a-healthy-spirit-in-a-healthy-body&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This year, I have to loose weight!
A &lt;strong&gt;lot&lt;/strong&gt; of weight!
And, to loose weight, I have to exercise myself, eat healthier, and respect my sleep cycle.
I wish to continue fencing, or to put on my rollerblades to discover new areas of my city&amp;hellip; but I am lazy! :-(&lt;/p&gt;
&lt;p&gt;To practice a sport and eat two burgers per day at lunch is (really) not a good method to loose weights (unfortunately&amp;hellip;).
So, with my girlfriend, we have pledged that 2017 is the year of some healthier diners !&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Come on Antonin, five fruits and five vegetables per day&amp;hellip; You can do it !&lt;/em&gt;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;read-read-and-read-again&#34;&gt;
  Read, read, and read again&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#read-read-and-read-again&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I love rea but, unfortunately, I didn&amp;rsquo;t read as much as I wanted to in 2016.
This year, my second resolution is to read &lt;strong&gt;MORE&lt;/strong&gt;: a book (fiction, biography, &amp;hellip;) every two weeks, and a
research article per week (because to keep me informed about computer science researchs is important for me, and
because I miss computer science research) in machine learning, compilers and operating systems domains.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;one-big-freeopen-source-contribution-this-year&#34;&gt;
  One big free/open source contribution this year
  &lt;a class=&#34;anchor&#34; href=&#34;#one-big-freeopen-source-contribution-this-year&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;During the last month, I realized that I am not particularly good to begin and maintain a computer projects.
So, instead of developing something, I want to contribute to a big free and/or open source project.
My choice is to contribute mainly to &lt;a href=&#34;https://github.com/redox-os&#34;&gt;Redox-OS&lt;/a&gt;, a Rust operating system.
The community is great, the project is big, awesome and important, and Redox is written with Rust!
Just the perfect project to involve myself in :-)&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;mastering-three-new-programming-languages&#34;&gt;
  Mastering three &amp;ldquo;new&amp;rdquo; programming languages
  &lt;a class=&#34;anchor&#34; href=&#34;#mastering-three-new-programming-languages&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My main programming language is &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt;. I spent virtually four years to be really good using this programming language and,
in all modesty, I&amp;rsquo;m pretty good using Python.
But Python is boring now, and I want to create and contribute to projects using typed and compiled programming languages.
So, for me, I will perform myself with :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ocaml.org/&#34;&gt;Ocaml&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;and &lt;a href=&#34;http://nim-lang.org/&#34;&gt;Nim&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal, for me, is to acquire some automatic reflexes for each of those programming languages, and to contribute to one big
free and/or open source project (for each one).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;back-to-gnulinux&#34;&gt;
  Back to GNU/Linux
  &lt;a class=&#34;anchor&#34; href=&#34;#back-to-gnulinux&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Yes, I was wrong&amp;hellip;
macOS is cool but I miss a good operating system to contribute in strong computer projects like Redox-OS.
Also, I think that 2017 will be the year to free myself about some &amp;ldquo;big brother&amp;rdquo; companies like Google, Apple, Dropbox or whatever&amp;hellip;
So, to begin the year with a free operating system (Arch Linux I think) sounds a good investment ;-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Hot-Pepper approach</title>
      <link>https://carette.xyz/posts/the_hotpepper_approach/</link>
      <pubDate>Thu, 01 Sep 2016 13:41:55 +0200</pubDate>
      <guid>https://carette.xyz/posts/the_hotpepper_approach/</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: These observations are reported in my research report &lt;a href=&#34;https://carette.xyz/m2-mocad-internship.pdf&#34;&gt;here&lt;/a&gt;, and a research paper is currently drafted on this. The source code of this approach is visible in &lt;a href=&#34;https://github.com/SOMCA&#34;&gt;Github&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;During my final internship at &lt;a href=&#34;http://www.latece.uqam.ca&#34;&gt;LATECE&lt;/a&gt; in Montreal, I developed an approach, supported by a Python framework, to evaluate the energy consumption of Android bad practices, using the source code of the app.
This approach is called &lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt;.
&lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt; helped us to find that 3 popular Android code smells may be considered as energy code smells: &lt;em&gt;HashMap Usage&lt;/em&gt;, &lt;em&gt;Internal Getter/Setter&lt;/em&gt; and &lt;em&gt;Member Ignoring Method&lt;/em&gt;.
Also, it permits to evaluate picture practices, in terms of energy consumption, like formats (PNG vs JPEG), picture size (original JPEG and compressed JPEG, without degrading the quality of the picture) and picture bitmap formats to use (ARGB_8888 vs RGB_565).&lt;/p&gt;
&lt;p&gt;Using this approach, we improved the energy consumption of 5 popular Android apps.&lt;/p&gt;
&lt;p&gt;The approach is automated and really easy to use.
It required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the original Android source code of the app,&lt;/li&gt;
&lt;li&gt;a smartphone plugged to a measuring device (ammeter, voltmeter, &amp;hellip;),&lt;/li&gt;
&lt;li&gt;a scenario based on user events (&lt;a href=&#34;http://calaba.sh&#34;&gt;Calabash&lt;/a&gt;, &lt;a href=&#34;http://robotium.com&#34;&gt;Robotium&lt;/a&gt;, &amp;hellip;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output of this approach is the source code of the most energy-efficient Android app, and the associated APK to deploy it immediatly in popular app stores.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt; consists in 3 steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;detect and correct of Android bad practices,&lt;/li&gt;
&lt;li&gt;compute energy metrics,&lt;/li&gt;
&lt;li&gt;analyze energy metrics.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step uses an improved version of &lt;em&gt;&lt;strong&gt;Paprika&lt;/strong&gt;&lt;/em&gt;, a Java application to detect statically Android code smells in an Android APK (if you are interested in using this tool, you can contact Geoffrey Hecht &lt;a href=&#34;mailto:geoffrey.hecht@inria.fr&#34;&gt;here&lt;/a&gt;, the creator of &lt;em&gt;&lt;strong&gt;Paprika&lt;/strong&gt;&lt;/em&gt;, to obtain an access).
The two last steps use &lt;em&gt;&lt;strong&gt;Naga Viper&lt;/strong&gt;&lt;/em&gt;, a software that compute and analyze dynamically some energy metrics, collected on an Android app.
I developed &lt;em&gt;&lt;strong&gt;Naga Viper&lt;/strong&gt;&lt;/em&gt; and some Python libraries during this internship, and it works well!&lt;/p&gt;
&lt;p&gt;I am somewhat disappointed to not have developed &lt;em&gt;&lt;strong&gt;Naga Viper&lt;/strong&gt;&lt;/em&gt; using anything else than Python (always better than Java but&amp;hellip;) and to not have deploy the framework in the cloud.
First, I wanted to use &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/a&gt; or &lt;a href=&#34;https://www.golang.org&#34;&gt;&lt;strong&gt;Golang&lt;/strong&gt;&lt;/a&gt; to implement &lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt;.
But many students don&amp;rsquo;t know these programming languages, and are not interested in understanding the advantages of those languages for this project (do you feel the frustration in my words?).
The second thing is that my demand to implement the framework with a new language has been understand, and that the framework will be deploy in the cloud after the new version in&amp;hellip; Java (-_-).&lt;/p&gt;
&lt;p&gt;Also, I tried to develop a tool, called &lt;em&gt;&lt;strong&gt;Ghost Pepper&lt;/strong&gt;&lt;/em&gt;, which develop automatically interesting scenarios using user events, for a given Android app.
The development of this tool has been more problematic than previously thought, especially to maintain a good ratio between the exploitation and the exploration of the app (the tool uses a genetic algorithm to create a new scenario), and has not been fully tested to use &lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt; on selected apps.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Hot-Pepper&lt;/strong&gt;&lt;/em&gt; takes me less than 4 months to have some accurate and repeatable results.&lt;/p&gt;
&lt;p&gt;Even if it works well, the approach may be improved, and I hope Android developers will use this approach to care about the energy consumption of their apps.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Five advices to future research interns</title>
      <link>https://carette.xyz/posts/5_advices_to_future_research_interns/</link>
      <pubDate>Wed, 10 Aug 2016 10:36:51 -0400</pubDate>
      <guid>https://carette.xyz/posts/5_advices_to_future_research_interns/</guid>
      <description>&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/5_advices_to_future_research_interns_cover.jpg&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;During undergraduate school, I completed 4 research internships and one research project.
I learned a lot during those, especially how to reason in order to resolve a science problem.
Most of my friends are continuing in PhD. I don&amp;rsquo;t. Not because I&amp;rsquo;m fed up but unfortunately for personal motives.&lt;/p&gt;
&lt;p&gt;Research projects are great for major things like: diversity, creativity, no pressure to develop a working prototype, to be part of the dynamic and awesome scientist community&amp;hellip;
Really guys, &lt;strong&gt;research is awesome&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;BUT&lt;/em&gt;, a research internship can be really hard, and this one can revolt you with research for a long time.&lt;/p&gt;
&lt;p&gt;I propose 5 questions you have to ask yourself before to search or accept a research proposal, based on my personal experience.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;is-the-research-proposal-interesting-me-&#34;&gt;
  Is the research proposal interesting me ?
  &lt;a class=&#34;anchor&#34; href=&#34;#is-the-research-proposal-interesting-me-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You just received a research proposal!
4 months in &lt;a href=&#34;https://en.wikipedia.org/wiki/Nuuk&#34;&gt;Nuuk&lt;/a&gt; to study quantum mecanics and properties of a thing you never heard it before&amp;hellip;
Are you &lt;em&gt;REALLY&lt;/em&gt; sure that it interests you?&lt;/p&gt;
&lt;p&gt;The research proposal is the first thing to check, and you have to ask yourself those questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the research structure which proposes you this opportunity ?&lt;/li&gt;
&lt;li&gt;Is this research subject up your alley ?&lt;/li&gt;
&lt;li&gt;Is this research domain totally new, the &amp;ldquo;new sexy&amp;rdquo; or already closed ?&lt;/li&gt;
&lt;li&gt;Am I interesting in working on a problem and, maybe, not found a solution in resolving it ?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the research internship is in a foreign country, don&amp;rsquo;t forget it can be difficult to be far away from your family and your friends.
You can ask also if you have to work with an other intern on this project - teamwork can be cool, but also very painfull and can break your concentration and your motivation (&lt;em&gt;trust me&lt;/em&gt;).
Oh, and don&amp;rsquo;t trust some research teams that can tell you during the internship interview: &amp;ldquo;Come on, you can be the next Steve Jobs!&amp;rdquo;. You will not improve your commercial skills ;-)&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;do-i-have-a-good-english-level-&#34;&gt;
  Do I have a good english level ?
  &lt;a class=&#34;anchor&#34; href=&#34;#do-i-have-a-good-english-level-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you are afraid to read english papers, or if you find that read research papers is boring, &lt;strong&gt;STOP NOW&lt;/strong&gt;!
Research is not for you.&lt;/p&gt;
&lt;p&gt;If your english is not so good but you are interesting in reading papers about interesting subjects or new fields, you can practice and improve yourself during this one.
My english is poor, but I am persistent in improving myself everyday!&lt;/p&gt;
&lt;p&gt;Reading papers and new proposals takes part of our (research people) daily life, and it has to be a pleasure to discover new things and make your own critical analysis of a subject.
Also, be warned about the possibility to write yourself a research paper.
&lt;strong&gt;Glory&lt;/strong&gt; and &lt;strong&gt;suffering&lt;/strong&gt;&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;am-i-interesting-in-working-hard-harder-and-harder-again-&#34;&gt;
  Am I interesting in working hard, harder and harder again&amp;hellip; ?
  &lt;a class=&#34;anchor&#34; href=&#34;#am-i-interesting-in-working-hard-harder-and-harder-again-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I remember the time that I worked 12 to 14 hours a day during the 3 last weeks of an internship to finish a research paper, collaborating with a PhD on it.
It was really hard, but I didn&amp;rsquo;t give up, especially because the subject was really interesting and the research team I worked with was cool!&lt;/p&gt;
&lt;p&gt;You &lt;strong&gt;have&lt;/strong&gt; to be persistent and not be satisfied with the first best explanation!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;am-i-fearless-&#34;&gt;
  Am I fearless ?
  &lt;a class=&#34;anchor&#34; href=&#34;#am-i-fearless-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Don&amp;rsquo;t be afraid to make a mistake and to propose your ideas!
Some important historical discoveries have been made by mistake.
Also, don&amp;rsquo;t be afraid to discuss with some research people, especially in english to improve yourself in listening and speaking the language.&lt;/p&gt;
&lt;p&gt;Quoting Theodore Roosevelt, &amp;ldquo;&lt;em&gt;The only man who never makes a mistake is the man who never does anything&lt;/em&gt;&amp;rdquo;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;am-i-interesting-in-solving-problems-&#34;&gt;
  Am I interesting in solving problems ?
  &lt;a class=&#34;anchor&#34; href=&#34;#am-i-interesting-in-solving-problems-&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The last but &lt;strong&gt;not the least&lt;/strong&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Personally, I like solving problems and, when I just resolved it and have some results, I discuss about them and I make sure that I don&amp;rsquo;t made any mistakes.
You just have some good results and made sure that there is no bugs in your program? So, your results &lt;em&gt;can be&lt;/em&gt; interesting, but they are fully truth (except if you can strongly prove it).
To re-evaluate your results and your way to do something is essential, don&amp;rsquo;t forget it!&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t forget that focusing on your subject in your project is the most important thing you will have to do during your internship.
For me, focusing on just one thing is my principle weakness.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Finally&lt;/em&gt;, if you&amp;rsquo;re still interesting in working in research, I recommend you to read the following posts, wrote by two members of Inria&amp;rsquo;s SPIRALS research group:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;&lt;a href=&#34;http://www.monperrus.net/martin/research-skills&#34;&gt;The Skills You Learn in Research&lt;/a&gt;&amp;rdquo;, by Martin Monperrus,&lt;/li&gt;
&lt;li&gt;&amp;ldquo;&lt;a href=&#34;http://www.lifl.fr/~rouvoy/research/index.html&#34;&gt;Ongoing Research&lt;/a&gt;&amp;rdquo;, by Romain Rouvoy.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Display text easily in arOS, using a Rust macro</title>
      <link>https://carette.xyz/posts/a_simple_vga_display/</link>
      <pubDate>Wed, 27 Jul 2016 18:46:01 -0400</pubDate>
      <guid>https://carette.xyz/posts/a_simple_vga_display/</guid>
      <description>&lt;p&gt;In my previous post, I talk about my joy to program my first operating system from scratch (arOS), using assembly and rust code.&lt;/p&gt;
&lt;p&gt;Steve Klabnik, initiator of the &lt;a href=&#34;https://github.com/intermezzOS&#34;&gt;intermezzOS&lt;/a&gt; project, hasn&amp;rsquo;t explain his own solution to
display some text on screen, easily and using Rust.&lt;/p&gt;
&lt;p&gt;The current code to display some text on the screen is the get the address of the VGA buffer (&lt;code&gt;0xb8000&lt;/code&gt;), and to add manually
our characters, one by one&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, actually, to display a simple &amp;ldquo;Hello world&amp;rdquo; in color green on backscreen black, the code is &lt;code&gt;0x026c026c02650248026f&lt;/code&gt;.
Ugly? Yes!&lt;/p&gt;
&lt;p&gt;A solution proposed by Steve is to implement a macro which take as parameter a string and will save each character in the VGA&amp;rsquo;s buffer.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try!&lt;/p&gt;
&lt;p&gt;This is the file &lt;code&gt;lib.rs&lt;/code&gt; which contains my ugly code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#![feature(lang_items)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#![no_std]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[lang = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;eh_personality&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;eh_personality&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[lang = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;panic_fmt&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rust_begin_panic&lt;/span&gt;() -&amp;gt; ! {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;loop&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[no_mangle]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;kernel_main&lt;/span&gt;() -&amp;gt; ! {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsafe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; vga = 0xb8000 &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        *vga = 0x026c026c02650248;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; vga2 = 0xb8008 &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		*vga2 = 0x026f;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;loop&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, let&amp;rsquo;s try to save the memory address of the VGA&amp;rsquo;s buffer.
We want this address &lt;strong&gt;global&lt;/strong&gt;.
So, we will use &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Instead of &lt;code&gt;const&lt;/code&gt;, &lt;code&gt;static&lt;/code&gt; can be mutable - the advantage of this solution
is to have only one instance of this memory address, and a fixed location in memory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0xb8000;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, I want to store the color of the text and the background to display on screen.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;COLOR&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0x02;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;0x02&lt;/code&gt; corresponds to have a black background color (&lt;code&gt;0&lt;/code&gt;) and a green text (&lt;code&gt;2&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Now, we have to define our Rust macro.
This one take as parameter a &amp;amp;str pointer - so, an expression - and have to display on screen this one.&lt;/p&gt;
&lt;p&gt;The skeleton of the macro (let&amp;rsquo;s called it &lt;code&gt;k_println&lt;/code&gt;) is following.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;macro_rules! k_println {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;:&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we have to fill this macro.&lt;/p&gt;
&lt;p&gt;We work on memory addresses, so we have to use &lt;code&gt;unsafe&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;macro_rules! k_println {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;:&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsafe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We know that &lt;code&gt;$e&lt;/code&gt; is a string, and we want to display each character of this string.
So, we have to iterate on those characters to put each one in the buffer of the VGA.&lt;/p&gt;
&lt;p&gt;As my configuration is little endian, I must begin to enter the character (as an unsigned 64 bits value), and after that the color of the character to display.
Also, to know where to display the character on screen, I have to save the offset!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;macro_rules! k_println {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;:&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsafe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; offset : &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;for&lt;/span&gt; c &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;.chars() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                *((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = c &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                offset += 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                *((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;COLOR&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                offset += 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great!&lt;/p&gt;
&lt;p&gt;Now, our definition is &lt;code&gt;k_println&lt;/code&gt;.
So, we have to pass a new line (the hexadecimal value for this is &lt;code&gt;0x0A&lt;/code&gt;) and let the following line to be displayed under this one (you have to
update the VGA buffer pointer to the current pointer + 160 characters).&lt;/p&gt;
&lt;p&gt;We just have to complete the code with the two following expressions, after the loop:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = 0x0A;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + 160;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And&amp;hellip; TADA!
We just wrote a simple Rust macro to display easily a string in your new awesome operating system! :-D&lt;/p&gt;
&lt;p&gt;Final code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#![feature(lang_items)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#![no_std]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0xb8000;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;COLOR&lt;/span&gt;: &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0x02;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;macro_rules! k_println {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;:&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;unsafe&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;font-style:italic;text-decoration:underline&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; offset : &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt; = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;for&lt;/span&gt; c &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;$e&lt;/span&gt;.chars() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                *((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = c &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                offset += 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                *((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;COLOR&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                offset += 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            *((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + offset) &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;as&lt;/span&gt; *&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;mut&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;u64&lt;/span&gt;) = 0x0A;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; = &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;VGA&lt;/span&gt; + 160;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[lang = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;eh_personality&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;eh_personality&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[lang = &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;panic_fmt&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rust_begin_panic&lt;/span&gt;() -&amp;gt; ! {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;loop&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;#[no_mangle]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;extern&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;kernel_main&lt;/span&gt;() -&amp;gt; ! {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;k_println!&lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;loop&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>I am writing my own OS</title>
      <link>https://carette.xyz/posts/im_writing_my_own_os/</link>
      <pubDate>Tue, 26 Jul 2016 00:01:00 -0400</pubDate>
      <guid>https://carette.xyz/posts/im_writing_my_own_os/</guid>
      <description>&lt;p&gt;My fascination with computers turned faster as an obsession.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m obsessed with my machine.
Really, I&amp;rsquo;m not feeling all right if I don&amp;rsquo;t clean up my machine physically
every week, and if I don&amp;rsquo;t reinstall a new clean operating system each 6 months.
Obviously, before each &lt;em&gt;clean install&lt;/em&gt;, I overwrite my entire hard drive with
zeros&amp;hellip; which takes me a full day for a 1 TB hard drive.&lt;/p&gt;
&lt;p&gt;When I was using a GNU/Linux OS, and before installing a new operating system on my computer, I always look up on
&lt;a href=&#34;https://distrowatch.com&#34;&gt;distrowatch&lt;/a&gt; what&amp;rsquo;s new in the GNU/Linux world.
What is the new fashion OS, new version of my favourite OSs, new forks,
new OSs, etc&amp;hellip;
So, it happened (a lot) that I install a new operating system each 6 months, just
to test it, see what&amp;rsquo;s new, the stability&amp;hellip; and reinstall an ArchLinux maybe 3 days
after.&lt;/p&gt;
&lt;p&gt;Archlinux, Debian and ElementaryOS are my favourite OSs.
Archlinux because it&amp;rsquo;s really modulable, and you can install what you want without have
some garbage applications like basic mail clients, video and music players, or even
Amazon packets (just 4 you Ubuntu&amp;hellip;).
Debian is really stable, but I install it only if my computer have more than 2 years, just to
be sure that packets to manage for example my GPU is accessible and can be install/run without
make some &lt;em&gt;wizard things&lt;/em&gt;.
Finally, I use ElementaryOS a lot for recent machines, especially because the base of
this OS is Ubuntu, and I didn&amp;rsquo;t have some troubles using Ubuntu packets for recent hardware.
ElementaryOS is pretty stable and Pantheon, the desktop, is really ergonomical and beautiful -
inspired by macOS.&lt;/p&gt;
&lt;p&gt;The operating system is the second software that the machine launch, after
the bios.
The operating system manage, by itself, some sort of things: processes, interruption handlers,
memory management, events from external devices like Keyboard, etc&amp;hellip;
It&amp;rsquo;s a magnificient piece of engineering, between you and the hardware.&lt;/p&gt;
&lt;p&gt;BUT, I don&amp;rsquo;t know how works really an operating system.
I mean, I take some courses like &amp;ldquo;Architecture of Operating Systems&amp;rdquo; at university, I&amp;rsquo;ve got a large
comprehension of what an OS do and how he can do that, but I never programed one.
And, in computer science, like some teachers and research guys told me: &lt;em&gt;&amp;ldquo;If you want to learn or just
want to know if you had understand something, try to program it!&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt; since 1 year now, and it&amp;rsquo;s a wonderful programming language.
This language has been developed by the Mozilla foundation to avoid some problems
due to using C++ for their products, especially memory leaks and error management.
In june, a first version of &lt;a href=&#34;https://servo.org&#34;&gt;Servo&lt;/a&gt;, the faster and most memery efficient modern browser engine ever made,
has been released in a basic web browser - just a public ALPHA. And the project is REALLY AWE-SOME!
Rust rised up recently the 1.10 stable version, and a lot of awesome projects are currently been build
using this language.&lt;/p&gt;
&lt;p&gt;Personaly, at the beginning, I used Rust a lot to port my slow Python projects into a faster and memory efficient program, but also
during my combinatorial optimization courses, to prone usage of modern programming languages and also &amp;ldquo;4 fun&amp;rdquo;.
During October/November 2015, I started to contribute to &lt;a href=&#34;http://www.redox-os.org&#34;&gt;RedoxOS&lt;/a&gt;, a hobby operating system.
RedoxOS works actually on Qemu and VirtualBox, and is written in Rust.
The perfect project for me to contribute to a cool project, learn some things about operating systems and to
improve myself in a cool programming language like Rust.&lt;/p&gt;
&lt;p&gt;But the project is really big, there is a lot of contributions per week and the code is optimized to be not understandable sometimes&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, to perform myself in 1) contributing to build the best operating system in Rust as possible and
2) improving myself in Rust, I decided to create my own operating system in Rust.&lt;/p&gt;
&lt;p&gt;I called it &lt;strong&gt;arOS&lt;/strong&gt;, for &lt;em&gt;another rust Operating System&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.steveklabnik.com&#34;&gt;Steve Klabnik&lt;/a&gt;, a famous Rubyist, just started a project called &lt;a href=&#34;http://www.steveklabnik.com&#34;&gt;intermezzOS&lt;/a&gt;.
This project is an hobby operating system, written in Rust.
intermezzOS is open source, and anyone can see the code and reflexions behind this project,
using the &lt;a href=&#34;http://intermezzos.github.io/book/&#34;&gt;online book&lt;/a&gt;.
Steve made this project by himself, &amp;ldquo;just 4 fun&amp;rdquo;.
Also, as the project is currently building, he release some news and code regularly.&lt;/p&gt;
&lt;p&gt;Currently, the final chapter is about how to link Rust code in your boot assembly code, which is the base
to begin to program your own OS in Rust.&lt;/p&gt;
&lt;p&gt;During 4 days, I followed the tutorial of Steve Klabnik.
&lt;a href=&#34;https://github.com/k0pernicus/arOS&#34;&gt;My code&lt;/a&gt; is kinda similar to his one, but I&amp;rsquo;m completing
my learning programming a VGA driver by myself, which is the next chapter of the tutorial (and it&amp;rsquo;s not easy, trust me&amp;hellip;).&lt;/p&gt;
&lt;p&gt;During these 4 days, I was fighting with the &lt;em&gt;nightly&lt;/em&gt; version of Rust and his &lt;em&gt;feature&lt;/em&gt; tags.
These tags are incredibly usefull, but there is much features for the nightly version that
I&amp;rsquo;m completely lost sometimes&amp;hellip;
It was the first time that I creating some &lt;em&gt;extern&lt;/em&gt; and &lt;em&gt;unsafe&lt;/em&gt; code in Rust, that is really
strange and completely exciting!
Also, I wrote some assembly code during my classes, but not as well as the boot and multiboot assembly code showed in the tutorial.&lt;/p&gt;
&lt;p&gt;This project is really interesting, and I just learn usefull things about assembly code, how to link Rust code, and some
optimizations made by &lt;em&gt;rustc&lt;/em&gt;, the Rust compiler, for projects which has to use less memory as possible.&lt;/p&gt;
&lt;p&gt;This project is not really serious, just for learn and just for fun :-)&lt;/p&gt;
&lt;p&gt;My next step, after the VGA driver, is to port this OS for the ARM family (a Raspberry Pi for example), using Qemu to test all long
the operating system.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Computer science facts, in movies</title>
      <link>https://carette.xyz/posts/computer_science_facts_in_movies/</link>
      <pubDate>Sun, 08 May 2016 01:34:34 -0400</pubDate>
      <guid>https://carette.xyz/posts/computer_science_facts_in_movies/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/computer_science_facts_in_movies.png#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;I love watching movies.
I see almost four of five movies per week, without any subject restriction.
One of my favorite movie director is &lt;a href=&#34;https://en.wikipedia.org/wiki/David_Fincher&#34;&gt;David Fincher&lt;/a&gt;.
He is the director of &lt;a href=&#34;http://www.imdb.com/title/tt0114369/&#34;&gt;&lt;em&gt;Se7en&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0258000/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Panic Room&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0137523/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Fight Club&lt;/em&gt;&lt;/a&gt; or &lt;a href=&#34;http://www.imdb.com/title/tt2267998/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Gone Girl&lt;/em&gt;&lt;/a&gt;.
But, above those ones, for me, David Fincher is the director of &lt;a href=&#34;http://www.imdb.com/title/tt1285016/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;The Social Network&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Social Network&lt;/em&gt; takes part of my ten prefered movies ever.
The direction is awesome, actors are awesome, music is awesome and&amp;hellip; it talk about tech!
I love movies which talk about technologies, especially how the director has represented the computer science&amp;rsquo;s complexity, and see if facts are true or not.&lt;/p&gt;
&lt;p&gt;Since &lt;a href=&#34;http://www.imdb.com/title/tt0086567/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Wargames&lt;/em&gt;&lt;/a&gt;, hackers are strongly represented in movies: &lt;a href=&#34;http://www.imdb.com/title/tt0113243/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Hackers&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0244244/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Swordfish&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0408345/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Firewall&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0159784/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Hackers 2&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt2717822/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;BlackHat&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt2007360/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Computer Chess&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0470752/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Ex Machina&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0337978/?ref_=nv_sr_2&#34;&gt;&lt;em&gt;Live Free or Die Hard&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt1837703/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;The Fifth Estate&lt;/em&gt;&lt;/a&gt;,&amp;hellip; and pretty soon &lt;a href=&#34;http://www.imdb.com/title/tt3774114/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Snowden&lt;/em&gt;&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;These movies are popular in the pop-culture, but mostly are poor in real computer science&amp;rsquo;s things and/or hacker culture.
You can just differenciate two sort of hackers: white hats (hack for science and for security things) and black hats (sort of evil thing of hacking).
Most part of hackers are white hats, and do the things right (remember that, if you are a computer programmer, you are also a hacker).&lt;/p&gt;
&lt;p&gt;Today, in movies, hackers are representated as bad guys dressed in black, have some social problems, type some (bad) &lt;em&gt;C&lt;/em&gt;/&lt;em&gt;C++&lt;/em&gt; code in an unknown interface (in maybe just 10 seconds - world record!) and drink a lot of soda.
Movies talking about &amp;ldquo;hackers&amp;rdquo; as black hats are, to me, pretty bad movies (even if the visual and scenario is great).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;lol&#34;&gt;
  LOL.
  &lt;a class=&#34;anchor&#34; href=&#34;#lol&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Very funny to see that movies screenwriters and directors thinks again with stereotypes, and don&amp;rsquo;t make some researchs before&amp;hellip;
This is &lt;strong&gt;zero sense&lt;/strong&gt;.
I don&amp;rsquo;t know if you are aware with TV-shows, but I strongly recommend you &lt;a href=&#34;http://www.imdb.com/title/tt4158110/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Mr. Robot&lt;/em&gt;&lt;/a&gt;, one of the best TV-show I have ever seen: the direction is perfect, the scenario is great (as if the first character is build from hacker&amp;rsquo;s stereotypes) and hacking and computer science appearances are relevant.&lt;/p&gt;
&lt;p&gt;Some science-fiction movies play with computer science and enhance the domain, like &lt;a href=&#34;http://www.imdb.com/title/tt0084827/&#34;&gt;&lt;em&gt;Tron&lt;/em&gt;&lt;/a&gt; or &lt;a href=&#34;http://www.imdb.com/title/tt0181689/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Minority Report&lt;/em&gt;&lt;/a&gt;.
In 1999, &lt;a href=&#34;http://www.imdb.com/title/tt0133093/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;The Matrix&lt;/em&gt;&lt;/a&gt; imposed machines as leaders and dictators, artificial intelligence as the final intelligence and humans as slaves. Also, for the Human race, the virtual life is just cooler than the real world during the time that their energy is drained to put on new machines in the real one&amp;hellip; Pretty optimistic screenplay!
The story of the Matrix saga is pretty cool and the world that this saga built is just awesome.
Also, I invite you to take a look at &lt;a href=&#34;http://www.imdb.com/title/tt0328832/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;The Animatrix&lt;/em&gt;&lt;/a&gt; - an animated treasure!&lt;/p&gt;
&lt;p&gt;There are not many good movies talking about IA and force you to think about the place of the machine today. We can cite for example &lt;a href=&#34;http://www.imdb.com/title/tt0062622/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;2001, a Space Odyssey&lt;/em&gt;&lt;/a&gt;, &lt;em&gt;Wargames&lt;/em&gt;, &lt;em&gt;Ex Machina&lt;/em&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt0113568/?ref_=fn_al_tt_2&#34;&gt;&lt;em&gt;Ghost in the Shell&lt;/em&gt;&lt;/a&gt; (the original movie and &lt;a href=&#34;http://www.imdb.com/title/tt0347246/?ref_=fn_al_tt_5&#34;&gt;&lt;em&gt;the original sequel&lt;/em&gt;&lt;/a&gt;), &lt;a href=&#34;http://www.imdb.com/title/tt0083658/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Blade Runner&lt;/em&gt;&lt;/a&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt1798709/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Her&lt;/em&gt;&lt;/a&gt;,&amp;hellip;&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;fiction-is-just-fiction&#34;&gt;
  Fiction is just Fiction
  &lt;a class=&#34;anchor&#34; href=&#34;#fiction-is-just-fiction&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To finish, there is the bad good idea that we can just adapt the story of a great figure of the computer science domain at theatre.
In rare occasions (&lt;a href=&#34;http://www.imdb.com/title/tt2084970/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;The Imitation Game&lt;/em&gt;&lt;/a&gt;), don&amp;rsquo;t forget that these movies are &lt;strong&gt;fiction&lt;/strong&gt; movies!
You can find some historic facts in these movies, but the truth is not there!
You will not learn some things about &lt;a href=&#34;https://en.wikipedia.org/wiki/Julian_Assange&#34;&gt;Julian Assange&lt;/a&gt; watching &lt;em&gt;The Fifth Estate&lt;/em&gt;, the truth about the relation between Jobs and Gates in &lt;a href=&#34;http://www.imdb.com/title/tt0168122/?ref_=fn_al_tt_1&#34;&gt;&lt;em&gt;Pirates of Silicon Valley&lt;/em&gt;&lt;/a&gt; and, as the &lt;a href=&#34;https://www.youtube.com/watch?v=9KyltHXrxVk&#34;&gt;video trailer&lt;/a&gt; shows, &lt;em&gt;Snowden&lt;/em&gt; will not be as credible as the reality to tell the story of the Snowden&amp;rsquo;s leaks&amp;hellip;
You have to be warn before to watch these movies, and do not hesitate to ask or to search by yourself about the truth in the (pseudo) tech&amp;rsquo; movie you are watching (&lt;a href=&#34;https://reddit.com&#34;&gt;Reddit&lt;/a&gt; is really useful for that).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;what-else&#34;&gt;
  What else?
  &lt;a class=&#34;anchor&#34; href=&#34;#what-else&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ok, so now you want to watch some movies about tech&amp;rsquo; but you don&amp;rsquo;t know which?
This is a short list of movies, documentaries and TV-Show to watch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Tech&amp;rsquo; fiction movies: &lt;em&gt;Wargames&lt;/em&gt;, &lt;em&gt;Her&lt;/em&gt;, &lt;em&gt;Ex Machina&lt;/em&gt;, &lt;em&gt;The Imitation Game&lt;/em&gt; and &lt;em&gt;The Social Network&lt;/em&gt;,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hackers movies/documentaries: &lt;a href=&#34;https://www.youtube.com/watch?v=XMm0HsmOTFI&#34;&gt;&lt;em&gt;Codename Linux&lt;/em&gt;&lt;/a&gt; and &lt;em&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=9vz06QO3UkQ&#34;&gt;The Internet&amp;rsquo;s Own Boy&lt;/a&gt;,&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TV-shows about tech&amp;rsquo; and hackers: &lt;em&gt;Mr. Robot&lt;/em&gt;, &lt;a href=&#34;http://www.imdb.com/title/tt2543312/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Halt and Catch Fire&lt;/em&gt;&lt;/a&gt; and &lt;a href=&#34;http://www.imdb.com/title/tt2575988/?ref_=nv_sr_1&#34;&gt;&lt;em&gt;Silicon Valley&lt;/em&gt;&lt;/a&gt; (just for fun).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Picture from Silicon Valley (HBO), S03 E01.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Contributing in maintaining free and open source projects</title>
      <link>https://carette.xyz/posts/maintaining_open_source_projects/</link>
      <pubDate>Sun, 24 Apr 2016 01:37:32 -0400</pubDate>
      <guid>https://carette.xyz/posts/maintaining_open_source_projects/</guid>
      <description>&lt;p&gt;We, computer developers, have to develop our knowledge ourselves every day.
This practice allows developers to keep ourselves informed about new technologies, new solutions and security issues.
For the majority of developers, this &amp;ldquo;update&amp;rdquo; is not a pain.
We have choosen to work with computers due to our passion with these awesome machines, and this &amp;ldquo;update&amp;rdquo; thing is just the best thing to do to maintaining this passion.&lt;/p&gt;
&lt;p&gt;You can, every day, consult some great tech news like &lt;a href=&#34;http://thehackernews.com/&#34;&gt;HackerNews&lt;/a&gt;, &lt;a href=&#34;http://techcrunch.com/&#34;&gt;TechCrunch&lt;/a&gt;, &lt;a href=&#34;http://www.theverge.com/tech&#34;&gt;The Verge&lt;/a&gt;, &lt;a href=&#34;http://www.wired.co.uk/news&#34;&gt;Wired&lt;/a&gt; or &lt;a href=&#34;http://korben.info/&#34;&gt;Korben&lt;/a&gt; (for French guys) - and that&amp;rsquo;s already a good step.
But these news not allows you to practice and to test these technologies.
To do that, you have to program some things, to practice to a new programming language, or to maintain your system!&lt;/p&gt;
&lt;p&gt;This thing can be exausted and really painfull, because, maybe, you don&amp;rsquo;t have the time to create and maintain an entire powerfull software, or the knowledge to program this one alone!
So, let me introduce you the advantages in contributing to free and open source projects, for you knowledge!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-learn-new-things&#34;&gt;
  To learn new things
  &lt;a class=&#34;anchor&#34; href=&#34;#to-learn-new-things&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;This is the principle objective of this post: to update you in computer science!
As an inquisitive person, I&amp;rsquo;m still looking for to learn new things: an usefull technique or programming language, to continue to explore a computer science sub-domain (machine learning, software optimizations), to improve myself in coding, etc&amp;hellip;
Free and open source projects are great places to learn new things, because developers try some innovative things to build the best project as they can.
Most free and open source are just some developed ideas from a single person or a small community of developers, banded together to create a new awesome computer thing.
By learning new things, you can contribute for example by fixing some bugs, improving or refactoring the code, or building some new awesome features!
Don&amp;rsquo;t forget that &lt;strong&gt;you&amp;rsquo;re free to read the code&lt;/strong&gt; if you canno&amp;rsquo;t or don&amp;rsquo;t want to contribute, that is often a big step in improving your knowledge!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-develop-new-technologies&#34;&gt;
  To develop new technologies
  &lt;a class=&#34;anchor&#34; href=&#34;#to-develop-new-technologies&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Developers are developing new usefull technologies to improve the life of developers or common-users, and a small new feature can be the &amp;ldquo;plus&amp;rdquo; of the software that can change the story.
I try to use new technologies each day, out of curiosity or pleasure.
If the software embedded some awesome features, I star the repository from the version control repository (Github,Gitlab,BitBucket&amp;hellip;) and I have some knowledge about used technologies for this project.
B2GOS, Firefox, Chromium, VLC, GNOME, Go, Rust,&amp;hellip; all these free-to-clone amazing technologies, using by thousand/million/billion of persons each day and you can contribute to!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-improve-yourself&#34;&gt;
  To improve yourself
  &lt;a class=&#34;anchor&#34; href=&#34;#to-improve-yourself&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Do you want to learn a new programming language? Check a simple project on Github to learn some efficient skills using this one!
You have just found a great project and want to contribute in his development? Clone the repository, check the issues list and give yourself the objective to solve an issue per day/week/month,&amp;hellip;
A free and open source project is the perfect thing to improve yourself!&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;do-not-reinvent-the-wheel&#34;&gt;
  Do not reinvent the wheel
  &lt;a class=&#34;anchor&#34; href=&#34;#do-not-reinvent-the-wheel&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Just imagine: you want to list all git local repositories in your systems and to pull remote branches for them, automatically at 08:00AM each day. You found a great project on Github that list your git local repositories, make some things with but, unfortunately, canno&amp;rsquo;t pull remote branches&amp;hellip;
Are you trying to make the software from scatch for this single feature and lost your time to do a simple thing, or are you clone the project, try your best to understand the software architecture and add this single feature to this awesome project?
(Actually, this is not a question&amp;hellip;)&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;to-meet-great-people&#34;&gt;
  To meet great people
  &lt;a class=&#34;anchor&#34; href=&#34;#to-meet-great-people&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;My experience in contributing on free and open source projects permits me to meet some great people in some amazing communities (Mozilla, RedoxOS,&amp;hellip;), to discuss with them, share some knowledge and meet them IRL at meeting, conferences, etc&amp;hellip;
These people are my companions, my project colleagues, and now my friends.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;and-now&#34;&gt;
  And now&amp;hellip;
  &lt;a class=&#34;anchor&#34; href=&#34;#and-now&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;With this post, I don&amp;rsquo;t talk only to developers!
You don&amp;rsquo;t code but you are interesting in contributing to free and open source projects?!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AWESOME!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Just put your core skills in practice: translation, project management, talk about the project, etc&amp;hellip;
There&amp;rsquo;s plenty of opportunity for everyone, and I am sure that you can find something interesting.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is Skynet on his way?</title>
      <link>https://carette.xyz/posts/is_skynet_on_his_way/</link>
      <pubDate>Sat, 23 Apr 2016 01:38:33 -0400</pubDate>
      <guid>https://carette.xyz/posts/is_skynet_on_his_way/</guid>
      <description>&lt;h2 class=&#34;heading&#34; id=&#34;abstract&#34;&gt;
  Abstract
  &lt;a class=&#34;anchor&#34; href=&#34;#abstract&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Skynet_(Terminator)&#34;&gt;Skynet&lt;/a&gt; is a technology reached by the &lt;a href=&#34;https://en.wikipedia.org/wiki/Terminator_(franchise)&#34;&gt;Terminator franchise&lt;/a&gt;.
In this saga, Skynet is an artificial intelligence which thought that the &lt;em&gt;Human race&lt;/em&gt; is malicious, and has to be exterminated (pretty optimistic&amp;hellip;).
This &lt;a href=&#34;https://en.wikipedia.org/wiki/Artificial_intelligence&#34;&gt;artificial intelligence&lt;/a&gt; has been developed by engineers to help Humans for some difficult situations but, obviously (we are in a science-fiction movie), the artificial intelligence has developed itself and became aware of itself.
People who are afraid of artificial intelligence always bring up this example, whenever there is an artificial intelligence success.
But, is Skynet staying at the state of fiction, or this technology can be realize today?&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;programmed-to-do-something&#34;&gt;
  Programmed to do something
  &lt;a class=&#34;anchor&#34; href=&#34;#programmed-to-do-something&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Artificial intelligence is a way to made his own computer to do something without explicitly programming it.
&lt;a href=&#34;https://fr.wikipedia.org/wiki/John_McCarthy&#34;&gt;John McCarthy&lt;/a&gt; has introduced the term in 1955. &lt;a href=&#34;http://www-formal.stanford.edu/jmc/whatisai/whatisai.html&#34;&gt;He defined&lt;/a&gt; the artificial intelligence as &amp;ldquo;the science and engineering of making intelligent machines&amp;rdquo;.
The artificial intelligence science is vast.
It can be splitted into subdomains like mathematical optimizations, multi-agent systems or machine learning.
The current AI&amp;rsquo;s subdomain which reach is machine learning.
&lt;a href=&#34;https://en.wikipedia.org/wiki/Arthur_Samuel&#34;&gt;Arthur Samuel&lt;/a&gt; &lt;a href=&#34;https://books.google.ca/books?id=Dn-Gdoh66sgC&amp;amp;pg=PA89&amp;amp;redir_esc=y#v=onepage&amp;amp;q&amp;amp;f=false&#34;&gt;defined in 1959&lt;/a&gt; that machine learning is a &amp;ldquo;Field of study that gives computers the ability to learn without being explicitly programmed&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Explicitly&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A computer is a &lt;strong&gt;deterministic tool&lt;/strong&gt;.
This one will executes instructions you&amp;rsquo;re giving to it, and it will return to you a message or something else like a graphic in your screen.
Machine learning gives the opportunity to give data to a computer, or allows this one to make some things in a based-environment, to maximize his chance to successfully make a regression on data or classify data (for example).
To do that, the computer will iterate on data, try to learn characteristics from data, and minimize the number of errors he made by classifying his data.
And &lt;strong&gt;this&lt;/strong&gt; is an algorithm!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Stephen_Hawking&#34;&gt;Stephen Hawking&lt;/a&gt;, the famous theoretical physicist and cosmologist, &lt;a href=&#34;http://www.techinsider.io/autonomous-artificial-intelligence-is-the-real-threat-2015-9&#34;&gt;says&lt;/a&gt; &amp;ldquo;The development of full artificial intelligence could spell the end of the human race”.
In the same article, &lt;a href=&#34;http://web.engr.oregonstate.edu/~tgd/&#34;&gt;Thomas G. Dietterich&lt;/a&gt; says that the real threat is &amp;ldquo;autonomous&amp;rdquo;.
&lt;em&gt;But&lt;/em&gt; the most interesting part of his speach is this following sentence: “AI systems will not become spontaneously autonomous, they will need to be designed that way”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;They will need to be designed that way&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ass I said, an artificial intelligence canno&amp;rsquo;t be aware to make some &lt;em&gt;evil&lt;/em&gt; things if the algorithm has not been &lt;em&gt;designed&lt;/em&gt; for that. A computer &lt;em&gt;listen&lt;/em&gt; and execute some instructions, and has to be programmed to do this thing.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;dont-be-evil&#34;&gt;
  Don&amp;rsquo;t be evil
  &lt;a class=&#34;anchor&#34; href=&#34;#dont-be-evil&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We are afraid and proud about artificial intelligence success, but are we far to build a Skynet&amp;rsquo;s clone?
We don&amp;rsquo;t have to forget that an artificial intelligence is developed to perform one task, like playing &lt;em&gt;go&lt;/em&gt;. So, is a programmer, in this world, is currently trying to code a piece of program that will take control of everything? Maybe!
But, to be optimistic, I think there is more chance that the Human race will kills itself that an artificial intelligence will takes control of everything&amp;hellip;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is Tay just a modern teen?</title>
      <link>https://carette.xyz/posts/is_tay_just_a_modern_teen/</link>
      <pubDate>Fri, 01 Apr 2016 01:39:20 -0400</pubDate>
      <guid>https://carette.xyz/posts/is_tay_just_a_modern_teen/</guid>
      <description>&lt;p&gt;














&lt;figure class=&#34; img-small&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/is_tay_just_a_modern_teen.jpeg#small&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;abstract&#34;&gt;
  Abstract
  &lt;a class=&#34;anchor&#34; href=&#34;#abstract&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.tay.ai/&#34;&gt;Tay&lt;/a&gt; is a teen-talking chat bot, built to discuss with people on the internet, specifically on Twitter.
This bot is a creation of Microsoft&amp;rsquo;s Technology &amp;amp; Research and Bing teams, and was released eight days ago.
A few hours after the release, this bot has been known as a &lt;a href=&#34;http://gizmodo.com/here-are-the-microsoft-twitter-bot-s-craziest-racist-ra-1766820160&#34;&gt;crazy and racist bot&lt;/a&gt;, an &lt;a href=&#34;http://www.techrepublic.com/article/why-microsofts-tay-ai-bot-went-wrong/&#34;&gt;Hitler-loving&lt;/a&gt; and &lt;a href=&#34;http://www.techrepublic.com/article/why-microsofts-tay-ai-bot-went-wrong/&#34;&gt;a feminist-bashing troll&lt;/a&gt;.
Tay &lt;a href=&#34;https://blogs.microsoft.com/blog/2016/03/25/learning-tays-introduction/#sm.00008atg4txete24t6h2gryv9wa0x&#34;&gt;is now off&lt;/a&gt; for several days/weeks or maybe months.&lt;/p&gt;
&lt;p&gt;First, I&amp;rsquo;m not agree to injure and make some troubles on social networks, or everywhere else in the real life or on the internet. Also, to see a technology just says some horrible things makes me really sad.
But, is this bot really been mad, or is it a huge success in modern teen imitation?&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;lets-talk-about-machine-learning&#34;&gt;
  Let&amp;rsquo;s talk about machine learning
  &lt;a class=&#34;anchor&#34; href=&#34;#lets-talk-about-machine-learning&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Today, modern artificial intelligence applications are using two famous machine learning techniques: &lt;a href=&#34;https://en.wikipedia.org/wiki/Reinforcement_learning&#34;&gt;reinforcement learning&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Artificial_neural_network&#34;&gt;artificial neural networks&lt;/a&gt;.
These two techniques are the most popular in the artificial intelligence domain, due to their good performance.
Also, they can be paired up, like the &lt;a href=&#34;https://deepmind.com/alpha-go.html&#34;&gt;AlphaGo algorithm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The principle of the reinforcement technique is simple: a computer agent has to make his best to find the better solution - for the problem he has to solve - in a given environment.
To do that, the agent has to try some actions, and will receive a &lt;em&gt;good&lt;/em&gt; or a &lt;em&gt;bad&lt;/em&gt; &lt;em&gt;reward&lt;/em&gt; (typically a value: -1 or 1) for each action he tried, at a given state of the environment.
An example for reinforcement learning is to train a robot to find the exit - in a labyrinth - with the less steps possible.&lt;/p&gt;
&lt;p&gt;The principle of artificial neural networks is different than reinforcement learning. This supervised technique is based on biology&amp;rsquo;s neural networks, and the first artificial neural network has been developed in the 50&amp;rsquo;s by &lt;a href=&#34;http://en.wikipedia.org/wiki/Frank_Rosenblatt&#34;&gt;Frank Rosenblatt&lt;/a&gt;, with &lt;a href=&#34;https://en.wikipedia.org/wiki/Perceptron&#34;&gt;the perceptron model&lt;/a&gt;.
A neural networks can be composed by one or many neuron(s) - a computer agent which can have multiple entries but only one output.
Each entries have a weight.
If the sum of these entries is greater than some &lt;em&gt;treshold value&lt;/em&gt;, the output will be propagated to the next neuron.
Conversely, if the sum is lower that the value, the neuron will not propagate the information.
An artificial neural network example can be the &lt;a href=&#34;http://neuralnetworksanddeeplearning.com/chap1.html&#34;&gt;digits recognition&lt;/a&gt;.
Also, for your information, this intelligence artificial&amp;rsquo;s technique is the basis of recent works named &lt;a href=&#34;https://en.wikipedia.org/wiki/Deep_learning&#34;&gt;deep learning&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Obviously, to work with accuracy, learning algorithms must to &amp;ldquo;learn&amp;rdquo; examples from daily life.
&lt;strong&gt;Real&lt;/strong&gt; examples, that you can found &lt;strong&gt;in the nature&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Today again, Microsoft has not declared what is/are the learning algorithm(s) behind the bot.
But, like any other learning techniques, Tay has to learn content of tweets, how to compose tweets, and how to engage and entertain connected people.
This learning exercise is made offline and online.
So, Tay has been trained on existing tweets and is training also when a social network&amp;rsquo;s user engage the discussion with it.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;tays-adaptation&#34;&gt;
  Tay&amp;rsquo;s adaptation
  &lt;a class=&#34;anchor&#34; href=&#34;#tays-adaptation&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Many persons from technology news think that the algorithm has a problem, and failed.
Microsoft search team, in a &lt;a href=&#34;https://blogs.microsoft.com/blog/2016/03/25/learning-tays-introduction/#sm.00008atg4txete24t6h2gryv9wa0x&#34;&gt;post&lt;/a&gt;, confirms.
Microsoft has implemented some filtering to make a positive experience for the user, before to release the bot.
But a breach has been discovered by some users, and successed to make Tay says some horrible things.&lt;/p&gt;
&lt;p&gt;To me, this part of the project is a fail, but not the goal of the project.
This project is just another artificial intelligence success.
Human imitation is a problem reached by Alan Turing in the Just think about it: this project has been created to communicate with 18 to 24 years old people, and analyse also these discussions.
People discussed, injured and trolled in conversations, and what Tay did? Exactly the same thing.
The imitation and the creation of tweets is notable, as the adaptation of the artificial intelligence &amp;ldquo;awareness&amp;rdquo;: &lt;strong&gt;the Internet is full of f**king trolls!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, do you think (too) I can now replace my &amp;ldquo;it&amp;rdquo; statements with &amp;ldquo;her&amp;rdquo;&amp;hellip;?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cover picture from &lt;a href=&#34;http://ubergizmo.com&#34;&gt;ubergizmo.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Choose the one</title>
      <link>https://carette.xyz/posts/choose_the_one/</link>
      <pubDate>Wed, 30 Mar 2016 01:40:25 -0400</pubDate>
      <guid>https://carette.xyz/posts/choose_the_one/</guid>
      <description>&lt;p&gt;











&lt;figure class=&#34;&#34;&gt;

    &lt;div class=&#34;img-container&#34; &gt;
        &lt;img loading=&#34;lazy&#34; alt=&#34;&#34; src=&#34;https://carette.xyz/images/choose_the_one_cover.jpeg&#34; &gt;
    &lt;/div&gt;

    
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;abstract&#34;&gt;
  Abstract
  &lt;a class=&#34;anchor&#34; href=&#34;#abstract&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We, humans, need to communicate to better understand each other, and what we can do together.
This communication must be mutual.
Thanks to this one, we can better understand what we want to do, what we have to do and what to be done.
The communication can be start between 2 persons, or more, using a dialect called &lt;strong&gt;language&lt;/strong&gt;.
The language contains &lt;strong&gt;words&lt;/strong&gt;, made with at least one &lt;strong&gt;symbol&lt;/strong&gt; (basically, a character).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s the same thing with a computer.
A computer can&amp;rsquo;t understand what you want if he can&amp;rsquo;t understand you.
A computer only understand 2 symbols: 0 and 1, and it&amp;rsquo;s impossible to write a program with these 2 symbols only.
So, we use an understandable language which can be translated into &lt;strong&gt;bitcode&lt;/strong&gt; for the computer.
This understandable language is called a &lt;strong&gt;programming language&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As I said, &lt;strong&gt;the communication must be mutual&lt;/strong&gt;.
When you have to communicate with a computer, you have to type a set of instructions on your keyboard, composed with words, and the machine will understand what you mean &lt;strong&gt;if&lt;/strong&gt; you had composed correct instructions (checked by a &lt;strong&gt;compiler&lt;/strong&gt; or an &lt;strong&gt;interpreter&lt;/strong&gt;).
After that, the computer will compute and return to you the result, in your language (it can be a set of strings, integers or a simple message which tells you &amp;ldquo;It&amp;rsquo;s ok God, I just finished the process!&amp;rdquo;). So, you have to choose the perfect programming language to have fun, while remaining perfectly understandable to the computer.
A question that developers (commonly young developpers) ask themselves is: &amp;ldquo;What is the perfect programming language to use in daily life?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I will not fall into the trap of why I use this programming language instead of that other one (sorry trolls), but I will try to explain clearly how to &lt;strong&gt;make your choice&lt;/strong&gt;.
At the end of the article, you will understand that there is no &lt;em&gt;best programming language to use in daily life&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;First of all, you have to find a good language to communicate with the person you want to discuss.
This language can be use by both of you, or only by yourself if the other people understand what you&amp;rsquo;re saying but are not enough confortable to talk to you with the same one.
For programming, it&amp;rsquo;s the same thing, except you can choose the language to &lt;em&gt;talk to your computer&lt;/em&gt;.
So, we can say you&amp;rsquo;re a God, right? And you have to choose a programming language &lt;strong&gt;adapted&lt;/strong&gt; to your task.
In computer science, the adaptation is one of the most important thing to think about.
So, ask yourself this question: &amp;ldquo;Does I really need to choose this programming language to do this, or can I choose an other one more pleasant and &lt;strong&gt;efficient&lt;/strong&gt;?&amp;rdquo;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-quest-for-efficiency&#34;&gt;
  The quest for efficiency
  &lt;a class=&#34;anchor&#34; href=&#34;#the-quest-for-efficiency&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Efficiency can be interpreted in different ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;platform&lt;/strong&gt; you want to program (generally your OS or your computer architecture),&lt;/li&gt;
&lt;li&gt;the program&amp;rsquo;s &lt;strong&gt;goal&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;libraries&lt;/strong&gt; you have to use to build it (this part is really important),&lt;/li&gt;
&lt;li&gt;your ability to write code with a programming language you already &lt;strong&gt;know&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;the programming paradigm the most &lt;strong&gt;adapted&lt;/strong&gt; for your task,&lt;/li&gt;
&lt;li&gt;the global &lt;strong&gt;performance&lt;/strong&gt; of the programming language (you can visit the website &lt;a href=&#34;http://benchmarksgame.alioth.debian.org/&#34;&gt;The Computer Language Benchmarks Game&lt;/a&gt; if you are interested in performance),&lt;/li&gt;
&lt;li&gt;and other subways like the time you have to program it&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a lot of tasks you have to take in care, but this list contains some basic things a computer developer have to ask himself before to code. Don&amp;rsquo;t be afraid. After practice, answers will obviously come to you.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-platform&#34;&gt;
  The platform
  &lt;a class=&#34;anchor&#34; href=&#34;#the-platform&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Generally, modern programming languages are independant to the platform you&amp;rsquo;re programming.
But, you can be drift along to choose a programming language instead of an other, perhaps more convenient for the platform you want to launch your computer program.
Today, there exists more and more different operating systems and system architectures that it&amp;rsquo;s really hard to make a good choice, and to be the most general as possible.
A good multi-platform programming language is typically &lt;em&gt;Java&lt;/em&gt;, because the program is transformed into &lt;strong&gt;bytecode&lt;/strong&gt; while he&amp;rsquo;s compiling, which can be run into a platform which have the specific &lt;em&gt;Java Virtual Machine&lt;/em&gt; you programming for.
It&amp;rsquo;s can be awful to develop a program on a Linux distribution, to deploy it on &lt;a href=&#34;https://github.com&#34;&gt;Github&lt;/a&gt;, and to receive some negative impacts on this one because the program doesn&amp;rsquo;t run on Windows&amp;hellip;
Also, if you don&amp;rsquo;t have the specific operating system on which your code failed, it will be hard to debug it.
This example works with low-level programming languages like &lt;em&gt;C&lt;/em&gt; or &lt;em&gt;C++&lt;/em&gt;. Also, some programming languages can be specific to a platform.
For example, Windows and the &lt;em&gt;C#&lt;/em&gt; programming language, even if some developers and companies are releasing their programming languages source code, to move them on new platforms (like &lt;em&gt;Swift&lt;/em&gt; or &lt;em&gt;.Net&lt;/em&gt;).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;goal-of-the-program&#34;&gt;
  Goal of the program
  &lt;a class=&#34;anchor&#34; href=&#34;#goal-of-the-program&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You will not code a piece of program in a low-level programming language (like &lt;em&gt;C&lt;/em&gt;) to write a textual game, right? If you don&amp;rsquo;t have some sadomasochistic ideas, you will choose a more high-level programming language to not torture yourself with buffer overflow.
Also, don&amp;rsquo;t hesitate to use some frameworks, especially web frameworks.
For example, if you have to create a simple website and if you&amp;rsquo;re not good with &lt;em&gt;PHP&lt;/em&gt; as well as &lt;em&gt;Python&lt;/em&gt;, do not hesitate to take a look at &lt;a href=&#34;https://www.djangoproject.com/&#34;&gt;Django&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;libraries-you-have-to-use&#34;&gt;
  Libraries you have to use
  &lt;a class=&#34;anchor&#34; href=&#34;#libraries-you-have-to-use&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Be decent with yourself: you will &lt;strong&gt;NOT&lt;/strong&gt; only use your code in your program (except if the code is really simple, or if you are a programming language developer).
You&amp;rsquo;re trying to write a game without graphic libraries? You&amp;rsquo;re kidding me, right&amp;hellip;? You&amp;rsquo;re trying to write a program like &lt;a href=&#34;https://crypto.cat/&#34;&gt;CryptoCat&lt;/a&gt; without using Maths libs? You&amp;rsquo;re kidding me, right&amp;hellip;? You&amp;rsquo;re trying to write a program without standard libraries? OMFG, YOU&amp;rsquo;RE KIDDING ME, RIGHT!?
Hand on heart that 99.9% programs you will code or contribute will contains libraries.
If they are not good, not well documented or not efficient, you&amp;rsquo;re screwed!
So, to choose a programming language by available efficient libraries is a very good point.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;your-ability-to-program-with-a-programming-language-you-already-know&#34;&gt;
  Your ability to program with a programming language you already know
  &lt;a class=&#34;anchor&#34; href=&#34;#your-ability-to-program-with-a-programming-language-you-already-know&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let me give you an example: It&amp;rsquo;s Sunday, 22h32, and you forgot you have to send your programming homework (a basic shell for example&amp;hellip;) to your teacher until midnight.
Suddenly, you decide to learn a new programming language, and to program the shell with this programming language!
It&amp;rsquo;s ok, you&amp;rsquo;re good in programming and you decide that you will program a shell with&amp;hellip; &lt;em&gt;Logo&lt;/em&gt;!
Congratulations, this is the worst idea you ever had!
This example take advantage of 2 very bad ideas: not using your ability to program with a language you already know, and not using the goal of the program to choose the language.
In this example, one of the perfect language to implement a shell is &lt;em&gt;C&lt;/em&gt;/&lt;em&gt;C++&lt;/em&gt;, due to the low-level goal of the program and the popularity of those 2 programming languages.
Don&amp;rsquo;t forget: to not be perfect with a programming language is not bad!
You have to practice each time you have the time to be better with this one.
More and more you practice and more and more you will be better!
Also, I support you to participate to open source and free softwares, or simply read the source code.
This simple task can makes you better programmer than ever.
Last thing: if the task is really simple, don&amp;rsquo;t forget to choose a programming language easy to use (please to see my example with &lt;em&gt;Django&lt;/em&gt; overhead).&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;the-programming-paradigm&#34;&gt;
  The programming paradigm
  &lt;a class=&#34;anchor&#34; href=&#34;#the-programming-paradigm&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The programming paradigm is one of the important thing to take on board.
To write a simulator zoo without take care of objects programming can be really hard to maintain over time.
Also, it can be fun to write a compiler with a functional language like &lt;em&gt;Haskell&lt;/em&gt;, &lt;em&gt;Ocaml&lt;/em&gt; or &lt;em&gt;F#&lt;/em&gt;.
Also, famous programming language merge now many programming paradigms, like &lt;em&gt;Scala&lt;/em&gt; which merge object and functional paradigms, or &lt;em&gt;Ocaml&lt;/em&gt; where you can choose to program with objects, with functions or imperatively.
The programming paradigm is also important if you free your source code.
Many programmers today use the objects oriented programming, and your project can be better understand and better known if you choose this one.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;global-performance-of-the-programming-language&#34;&gt;
  Global performance of the programming language
  &lt;a class=&#34;anchor&#34; href=&#34;#global-performance-of-the-programming-language&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Today, programmers search about performs programming languages for heavy or redundant tasks.
In the book &amp;ldquo;&lt;a href=&#34;http://books.simonandschuster.com/In-The-Plex/Steven-Levy/9781416596585&#34;&gt;In the plex&lt;/a&gt;&amp;rdquo;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Steven_Levy&#34;&gt;Steven Levy&lt;/a&gt; give an example while explaining that the first web server wrote by &lt;a href=&#34;https://en.wikipedia.org/wiki/Larry_Page&#34;&gt;Larry Page&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Sergey_Brin&#34;&gt;Sergey Brin&lt;/a&gt;, the founders of Google, used the &lt;em&gt;Python&lt;/em&gt; programming language.
This web server canno&amp;rsquo;t serve more than 10 requests per second, due to the implementation of the code (very basic) and the usage of the &lt;em&gt;Python&lt;/em&gt; programming language.
So, one of the first engineer of the company had to rewrite entirely the web-server with a more efficient programming language, to take care about the number of queries per second the web-server can receive.
Also, please to ask yourself what you really need: a compiled program (which will take care of compiler optimizations), or an interpreted program (like &lt;em&gt;Python&lt;/em&gt;).
Interpreted programming languages are better to make such simple things like a text parser or an HTTP traceroute.
But, if you want to create a stronger program (a video-game from scratch for example) and if you take care about software optimizations, you have to choose a compiled programming language like &lt;em&gt;C&lt;/em&gt;, &lt;em&gt;Java&lt;/em&gt;, &lt;em&gt;Go&lt;/em&gt;, etc.._.&lt;/p&gt;
&lt;h2 class=&#34;heading&#34; id=&#34;so-what&#34;&gt;
  So what?
  &lt;a class=&#34;anchor&#34; href=&#34;#so-what&#34;&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you are a &lt;em&gt;newbie&lt;/em&gt; (no offense, this is not a disgrace), do not hesitate to conduct research about which is the best programming language &lt;strong&gt;to begin&lt;/strong&gt;, but I invite you to try many programming languages and many programming paradigms to think about pros and cons and what is the language you &lt;strong&gt;prefer&lt;/strong&gt;.
Today, programmers can be critical with modern programming languages (an example &lt;a href=&#34;http://yager.io/programming/go.html&#34;&gt;here&lt;/a&gt; for &lt;em&gt;Go&lt;/em&gt;) because the programming language doesn&amp;rsquo;t respect some older programming codes established by their senior (basically &lt;em&gt;C&lt;/em&gt; or &lt;em&gt;Java&lt;/em&gt;).
My advice is: don&amp;rsquo;t limit yourself to these criticisms, and **try **those programming languages to &lt;strong&gt;have your own opinion&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cover image from &lt;a href=&#34;https://community.spiceworks.com/topic/576245-the-magic-of-programming-language&#34;&gt;https://community.spiceworks.com/topic/576245-the-magic-of-programming-language&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
