<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Laurent Franceschetti</title>
    <description>The latest articles on DEV Community by Laurent Franceschetti (@fralau).</description>
    <link>https://dev.to/fralau</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3640471%2F245cbe9d-0d35-4baa-8bc8-0812f111583b.jpeg</url>
      <title>DEV Community: Laurent Franceschetti</title>
      <link>https://dev.to/fralau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fralau"/>
    <language>en</language>
    <item>
      <title>Is Mathematics Invented or Discovered? This Answer Might Surprise You</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Tue, 14 Apr 2026 08:47:55 +0000</pubDate>
      <link>https://dev.to/fralau/is-mathematics-invented-or-discovered-this-answer-that-might-surprise-you-246j</link>
      <guid>https://dev.to/fralau/is-mathematics-invented-or-discovered-this-answer-that-might-surprise-you-246j</guid>
      <description>&lt;p&gt;&lt;strong&gt;Is mathematics invented or discovered&lt;/strong&gt;? I will share an insight about one of the oldest philosophical riddles of mathematics. And the answer might surprise you. &lt;/p&gt;

&lt;p&gt;Whichever side you were on, it's good news and bad news at the same time: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Invented" is the winner&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;"Invented" is probably not what you thought it was.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a matter of fact, it is nothing new. It is simply a rephrasing of principles you might already have known, either consciously or unconsciously.&lt;/p&gt;

&lt;p&gt;The answer to the riddle is simply that the question contains a hidden ambiguity. And as you probably know, if your definition of a symbol is &lt;em&gt;ambiguous&lt;/em&gt; (i.e. you use one symbol with two meanings, or one symbol as the alias of another), you might get two results: either a stop in error (contradiction), or an infinite loop (undecidability).&lt;/p&gt;

&lt;p&gt;With ambiguous definitions, you cannot process that proposition "Is mathematics invented or discovered", because it would be mathematically undecidable.&lt;/p&gt;

&lt;p&gt;Of course, someone will object, that's a a philosophical question, outside of mathematics, so it's a lost cause...&lt;/p&gt;

&lt;p&gt;And yet, we might find a somewhat sensible way to reason &lt;em&gt;mathematically&lt;/em&gt; about this philosophical question &lt;em&gt;about mathematics&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To solve this issue we need to disambiguate: we need to &lt;strong&gt;split a few things in our mind&lt;/strong&gt;. Here is a rough avenue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt; (and this is implicit in the statement of the question), we must posit a duality between the &lt;strong&gt;mind&lt;/strong&gt; and &lt;strong&gt;reality&lt;/strong&gt;. Let's consider them as two universes, or two sets: the &lt;strong&gt;Subjective&lt;/strong&gt; (internal universe), and &lt;strong&gt;Objective&lt;/strong&gt; (external universe). The Subjective universe contains ideas, the Objective universe contains things. In physics the elements of the Objective universe are called &lt;em&gt;bodies&lt;/em&gt;, and we agree (more or less) that they are composed of particles.&lt;/p&gt;

&lt;p&gt;In the Objective universe, &lt;strong&gt;discovery&lt;/strong&gt; is the fact of getting to know, consciously, that something is objectively there. It could be an object, or a law. To &lt;strong&gt;discover&lt;/strong&gt; means "to remove the veil from something"&lt;/p&gt;

&lt;p&gt;In the Subjective universe, you can generate &lt;em&gt;any&lt;/em&gt; idea you want, and this is the act of &lt;strong&gt;creation&lt;/strong&gt;. The Objective (physical) universe does not afford such freedom; it seems to operate under certain stable laws, that cannot changed on a whim. The Law of Gravity is to be obeyed, and Mother Nature makes a better job at exerting general surveillance and ruthlessly enforcing it, than the best secret police force in a totalitarian state. What you can do in defiance, is only two things: to &lt;strong&gt;perceive&lt;/strong&gt; what is there, and to &lt;strong&gt;act&lt;/strong&gt; in an effort to make things go your way, within the Law.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mathematics is symbol processing&lt;/strong&gt;, so where does it belong to? To the Subjective universe. Of course the paper, the pen, the computer, the blackboard, printed page or monitor to visualize results are real: they belong to the (Objective set). They are three-dimensional, you can feel them. But the &lt;strong&gt;concepts&lt;/strong&gt; of Mathematics? You cannot touch them, you cannot feel them, you cannot perceive them. The only way you can perceive them, is by &lt;em&gt;creating&lt;/em&gt; them first. In your mind. It is both odd and interesting that you can communicate about them to another person; but only to a person who has &lt;em&gt;created&lt;/em&gt; them first. In their mind. You use &lt;em&gt;reality&lt;/em&gt; to communicate about Mathematics (voice, paper, etc.).&lt;/p&gt;

&lt;p&gt;Mathematics uses &lt;strong&gt;symbols&lt;/strong&gt; as its raw material: they are ideas, elements of the Subjective universe, but with a very special, interesting property. Indeed, what is a &lt;strong&gt;symbol&lt;/strong&gt;, such as the letter A, the digit 1, or an emoji, etc.? It is common knowledge that it has both form and meaning. We can state this in the following way: it is a pair of elements, one in the Objective universe (a form), and one in the Subjective universe (an idea). The technical term that embodies this duality is &lt;strong&gt;ideogram&lt;/strong&gt;: literally, &lt;em&gt;an idea (&lt;code&gt;ideo-&lt;/code&gt;) materialized as a mark&lt;/em&gt; (&lt;code&gt;-gram&lt;/code&gt;). It's quite simple: think of these pairs (idea, object) as stitches between two surfaces (the Objective and the Subjective). The idea part of the symbol has a "ghost" in the objective universe, and the physical part of the symbol has a "ghost" in the objective universe. You can conceive the symbol is a stitch between the two parts; or say that the idea and the thing are a stable reflection of each other.&lt;/p&gt;

&lt;p&gt;What is &lt;strong&gt;reasoning&lt;/strong&gt;, in a mathematical sense? It is clearly an operation of the Subjective universe. If you look carefully at it, it is transformation of symbols, thanks to general &lt;strong&gt;rules&lt;/strong&gt; that are stable, as well as &lt;strong&gt;constraints&lt;/strong&gt; you chose to apply to your specific problem. It is the rules and constraints that allow reasoning. Reasoning in the mathematical sense, should run somewhat parallel to the evolution of the Objective universe, to be useful. By being useful, we mean &lt;em&gt;solving problems&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Everybody knows&lt;/em&gt;, that mathematics is about &lt;strong&gt;solving problems&lt;/strong&gt;. A problem is reflected in the subjective universe; but ultimately is in the objective universe, &lt;em&gt;otherwise it wouldn't be a problem&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;If you you use arithmetics to count units of sheep or quantities of grain, it has some use, only to the degree that it allows you to predict, or decide about, the physical (objective) universe. Perhaps, the detour might be very circuitous; but in the end, it will have to have a &lt;em&gt;reflection&lt;/em&gt; in the physical universe. Even the most abstract theory, such as topology (the study of relation between objects) is useful to the degree that it solves problems in the objective universe. And solving problems is necessary for survival, in plants, animals and human beings. &lt;/p&gt;

&lt;p&gt;A good metaphor of the two-universe idea is: *&lt;em&gt;Mathematics is a superb map-maker (Subjective), but it never walks the terrain (Objective) *&lt;/em&gt;. A map gives you the places of trees, houses, streets. But they are &lt;em&gt;symbols&lt;/em&gt; for trees, houses, streets. The map has no idea of what they are; it cannot experience them, feel them, know them. Yes, one might argue, but what if you enriched the map? Add pictures, temperatures, humidity, etc. You would have just enriched your symbols, and it's still symbols. You could go to infinity, it would just be symbols, reducible to 0s and 1s. Symbols. Always symbols. That's all it is and will be. Always and forever.&lt;/p&gt;

&lt;p&gt;The map makes sense only thanks to the little stitches. The coordinates must point to an actual location in the Objective universe. The temperature measurements must corresponds to particles in motion, the humidity to the presence of water molecules, etc.&lt;/p&gt;

&lt;p&gt;You could say that the map is a physical object actually since it needs to be on paper or a screen to be perceived. Or, is it? No it's just little blobs of color (call them dots, or pixels, if you wish). It is &lt;em&gt;you&lt;/em&gt;, thanks to your symbolic processing engine of the mind, who are (consciously or unconsciously) &lt;em&gt;parsing&lt;/em&gt; those patterns of dots, isolating them into symbols, and arranging them in a data structure. You can &lt;em&gt;delegate&lt;/em&gt; that process, partly, to a machine, but that's still the same process.&lt;/p&gt;

&lt;p&gt;All right, then what about &lt;strong&gt;reasoning&lt;/strong&gt;? It is the act of observing and, with symbolic reasoning, arriving a &lt;em&gt;new&lt;/em&gt;, useful conclusion about reality, to solve problems in order to survive. The subtle thing about reasoning is that it required a mathematical process, i.e. in involved the manipulation of these stitched ideas called "symbols". So in order to arrive at a useful, problem-solving conclusion, you had to make sure that the stitches of your symbols were still attached to their counterparts in the physical universe.&lt;/p&gt;

&lt;p&gt;In mathematical terms, you had achieved a first &lt;em&gt;transform&lt;/em&gt; from the Objective universe to the Subjective Universe, and then a second &lt;em&gt;transform&lt;/em&gt; from the Subjective univers to the Objective one. In the simple example, you had four sheep in one place, and three in another. You did not have to put them all together physically in one place and count them. You could transform the problem in 4 + 3 = 7, then do a transform and no realize that you have seven sheep in the physical universe.&lt;/p&gt;

&lt;p&gt;Perhaps you might have understood my point just with the above, but let's add one more concept: &lt;strong&gt;convergent evolution&lt;/strong&gt;, a process that evidently applies to all living beings, including human beings. What is it? &lt;strong&gt;Convergent evolution, is the rule that two living beings (tree, animals) even completely unrelated genetically, culturally, etc., attempting to solve a similar problem will eventually tend to similar, optimal solutions.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;A clear example is that completely unrelated animals, separated by millions of years (or possibly galaxies) will arrive at similar forms, in they find themselves in similar conditions. An example is &lt;em&gt;carcinogenesis&lt;/em&gt; where "crab-like" creatures repeatedly evolve in shallow coastal waters. That's because that body-plan is fairly optimal for those conditions. Another example is the striking similarity of shape between sharks and dolphins; the reason has to do with hydrodynamics (the forces involved in an aquatic environment) and ultimately the geometry of the objective, tridimensional universe.&lt;/p&gt;

&lt;p&gt;And geometry is the hint here. Mathematics will converge toward laws of the physical universe (or accurately it will be able to project them on laws of the physical universe), because of the fundamental axiom that it must solve problems of the physical universe. That's &lt;strong&gt;convergent evolution&lt;/strong&gt;, which is simply that the space of optimal solutions is finite, within a stated set of constraints. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mathematics is a subjective space of possible problem‑solving structures,with problems originating in the objective universe.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That means that mathematics is undoubtedly &lt;strong&gt;created&lt;/strong&gt;; that much is obvious. But is &lt;strong&gt;constrained&lt;/strong&gt; by the stitches of its symboles with the objective universe, which must continue to hold. Hence the rules and constraints that it evolves are led to go into a certain direction, toward certain optimal decisions, which have some relation with the laws of the physical universe.&lt;/p&gt;

&lt;p&gt;That explains why mathematics &lt;em&gt;can&lt;/em&gt; support experimental sciences by confirming measurements and predicting them. That's why mathematical &lt;em&gt;creations&lt;/em&gt; sometimes lead to actual &lt;em&gt;discoveries&lt;/em&gt; in the objective universe.&lt;/p&gt;

&lt;p&gt;The answer is extremely simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Mathematics&lt;/strong&gt; is created and always created; but not in any way because it carries with it symbols of the object universe. That's why it leads to &lt;strong&gt;discoveries&lt;/strong&gt; in the objective universe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that is the process that is defined &lt;strong&gt;invention&lt;/strong&gt;. Invention is not pure creation, and it is not pure discovery.&lt;/p&gt;

&lt;p&gt;It comes from Latin &lt;em&gt;in-&lt;/em&gt; "toward", and &lt;em&gt;-venire&lt;/em&gt; "to come". That's not pure, imaginative creation. That's following a map, to arrive at the destination. And all journeys in Mathematics eventually lead to the objective universe.&lt;/p&gt;

&lt;p&gt;The answer is: Mathematics is _both: creation and discovery; and connecting the two with mathematical reasoning is called &lt;strong&gt;invention&lt;/strong&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Solving the venv headache with a small utility?</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Mon, 30 Mar 2026 14:41:33 +0000</pubDate>
      <link>https://dev.to/fralau/solving-the-venv-headache-19fc</link>
      <guid>https://dev.to/fralau/solving-the-venv-headache-19fc</guid>
      <description>&lt;p&gt;Python’s virtual environments (venvs) are great — until you actually try to &lt;em&gt;use&lt;/em&gt; them.&lt;/p&gt;

&lt;p&gt;Every project has its own &lt;code&gt;.venv&lt;/code&gt;, but the moment you move around your filesystem, you’re stuck manually running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…over and over, in every project, forever.&lt;/p&gt;

&lt;p&gt;You have to activate the venv in every shell where you are. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WHY? The flaw is structural: using environment variables for activating the &lt;code&gt;venv&lt;/code&gt; was a design error. The reason is that it's impossible for a program to modify the shell environment it was launched from. There is no way around that...&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Many tools, like &lt;code&gt;git&lt;/code&gt; had already solved this problem decades ago, without environment variables: they automatically discover the nearest repository by walking upward through parent directories.&lt;/p&gt;

&lt;p&gt;So why not do the same for Python?&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 &lt;code&gt;venv&lt;/code&gt;: Find the nearest &lt;code&gt;.venv&lt;/code&gt; automatically and activate it
&lt;/h2&gt;

&lt;p&gt;Drop this into your &lt;code&gt;.zshrc&lt;/code&gt; or &lt;code&gt;.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# Activate the Python virtual environment&lt;/span&gt;
&lt;span class="c"&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# venv: search upward for the nearest .venv directory and activate it&lt;/span&gt;
venv&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Start from the current working directory&lt;/span&gt;
    &lt;span class="nb"&gt;local dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# Walk upward until we reach the filesystem root&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

        &lt;span class="c"&gt;# If this directory contains a .venv folder, we found the environment&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.venv"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;

            &lt;span class="c"&gt;# If this venv is already active, do nothing&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.venv"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                return &lt;/span&gt;0
            &lt;span class="k"&gt;fi

            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Activating venv at &lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.venv"&lt;/span&gt;

            &lt;span class="c"&gt;# Use 'source' so activation happens in the *current* shell&lt;/span&gt;
            &lt;span class="c"&gt;# (a script cannot do this — only a function can)&lt;/span&gt;
            &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.venv/bin/activate"&lt;/span&gt;

            &lt;span class="k"&gt;return &lt;/span&gt;0
        &lt;span class="k"&gt;fi&lt;/span&gt;

        &lt;span class="c"&gt;# Move one directory up and continue searching&lt;/span&gt;
        &lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;done&lt;/span&gt;

    &lt;span class="c"&gt;# If we reached the root without finding a .venv, deactivate if one is active&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deactivating venv at &lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        deactivate
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"(No .venv found in this directory or any parent.)"&lt;/span&gt;
    &lt;span class="k"&gt;fi

    return &lt;/span&gt;1
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It’s &lt;strong&gt;structural&lt;/strong&gt;: it walks up the directory tree, just like Git does.&lt;/li&gt;
&lt;li&gt;It's a shell &lt;strong&gt;function&lt;/strong&gt; so it runs in the current shell so it can modify the current process' environment; and for that it can use &lt;code&gt;source&lt;/code&gt; as an escape hatch.&lt;/li&gt;
&lt;li&gt;It’s &lt;strong&gt;predictable&lt;/strong&gt;: it only activates when you ask it to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives you a clean, deterministic workflow. Just type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No matter where you are inside the project, the right environment activates.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧹 Optional: Add a &lt;code&gt;devenv&lt;/code&gt; to deactivate
&lt;/h2&gt;

&lt;p&gt;If you want symmetry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devenv&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    deactivate 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No active venv."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Final thoughts
&lt;/h2&gt;

&lt;p&gt;Python’s tooling ecosystem is full of “activation rituals” that hide what’s really happening. This tiny function cuts through all of that and gives you a simple, structural rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Activate the nearest &lt;code&gt;.venv&lt;/code&gt; — nothing more, nothing less.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s small, sharp, and honest. Exactly the kind of tool the shell excels at.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>productivity</category>
      <category>python</category>
      <category>tooling</category>
    </item>
    <item>
      <title>YAMLpp is renamed to Protein</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Mon, 12 Jan 2026 14:33:08 +0000</pubDate>
      <link>https://dev.to/fralau/yamlpp-is-renamed-to-protein-605</link>
      <guid>https://dev.to/fralau/yamlpp-is-renamed-to-protein-605</guid>
      <description>&lt;p&gt;The &lt;strong&gt;YAMLpp language&lt;/strong&gt; (&lt;a href="https://dev.to/fralau/yamlpp-an-devops-project-is-making-a-big-leap-forward-54b7"&gt;introduced in that article&lt;/a&gt;) evolved a lot, particularly with the introduction of imported modules, and it deserved a better name to describe what it could do for project developers or people involved in system administration or deployment.&lt;/p&gt;

&lt;p&gt;Nowadays, a lot of tools ara &lt;strong&gt;data-driven&lt;/strong&gt;. You describe the result you want, and the system figures out how to produce it.&lt;/p&gt;

&lt;p&gt;The original name &lt;strong&gt;YAMLpp&lt;/strong&gt; was a reference to its basic syntax (it is YAML-compliant) and it initially produced YAML.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;&lt;a href="https://yamlpp.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Protein&lt;/a&gt;&lt;/strong&gt; is so much more than that. It is a &lt;strong&gt;data composer&lt;/strong&gt; and a &lt;strong&gt;templating tool&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;data composer&lt;/strong&gt; can be seen as similar to a typographical composer: you start from a small set of data, and you use that too to &lt;em&gt;compose&lt;/em&gt; your data (arrange them in space) in the same way as you would lay out a small set of a letters on a page, to form a text. You can output formally correct data structures (typically in YAML or JSON), or store them in files, for later use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;templating tool&lt;/strong&gt;: you can also use the embedded templating engine (Jinja), to produce output files, typically in HTML format; or produce Javascript snippets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Protein is simply regular YAML, with commands called &lt;strong&gt;constructs&lt;/strong&gt; (which are simply keys starting with a dot, such as &lt;code&gt;.do&lt;/code&gt;, &lt;code&gt;.foreach&lt;/code&gt;, etc.). Protein is essentially a tree builder and transformer.&lt;/p&gt;

&lt;p&gt;The result is surprisingly effective, typically for web development: in a few lines of code (it's YAML) you describe what YAML or JSON you want to produce, as well as HTML, Javascript, etc.&lt;/p&gt;

&lt;p&gt;You don't have to worry about boiler plate any more, or about repeating the same data across different files; Protein helps you producing them from one single source (or a set of source files).&lt;/p&gt;

&lt;p&gt;Protein has functions with their own scope as well as modules. The "magic" is done through the Jinja templating engine, which can produce new YAML structures.&lt;/p&gt;

&lt;p&gt;Furthermore, you can define your own functions to be used in Jinja (developed in Python). Hence you can use Protein for what it does best (composing and templating), and delegate complicated and delicate calculations to Python. You get the best of both worlds.&lt;/p&gt;

&lt;p&gt;Protein is installable as a Python package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;protein-lang
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Protein:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://yamlpp.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fralau/protein" rel="noopener noreferrer"&gt;Git repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/protein/" rel="noopener noreferrer"&gt;Pypi repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>sysop</category>
      <category>json</category>
    </item>
    <item>
      <title>🚀 YAMLpp: An DevOps Project is Making a Big Leap Forward</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Fri, 19 Dec 2025 14:28:14 +0000</pubDate>
      <link>https://dev.to/fralau/yamlpp-an-devops-project-is-making-a-big-leap-forward-54b7</link>
      <guid>https://dev.to/fralau/yamlpp-an-devops-project-is-making-a-big-leap-forward-54b7</guid>
      <description>&lt;p&gt;If you’ve ever worked with YAML at scale, you’ve probably hit the same wall: YAML is great for configuration, but it’s &lt;em&gt;static&lt;/em&gt;. Too static. Real‑world systems need dynamic behavior — templating, reuse, conditional logic, environment‑dependent values, and the ability to generate multiple YAML outputs from a single source of truth.&lt;/p&gt;

&lt;p&gt;A few weeks ago, YAMLpp was introduced as a macro language for dynamic, self‑generating YAML. It extended YAML with variables, conditionals, loops, imports, and even Python integration. It was a promising idea… but the implementation was early, experimental, and not yet ready for broader adoption.&lt;/p&gt;

&lt;p&gt;That has changed.&lt;/p&gt;

&lt;p&gt;Today, YAMLpp has quietly taken a major step forward, toward being a fully feature language.&lt;br&gt;
Here’s what’s new.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ A more robust execution model
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;YAMLpp’s macro engine manipulates the YAML tree itself, not just text&lt;/strong&gt;. This is powerful, but it also means the interpreter must be extremely disciplined.&lt;/p&gt;

&lt;p&gt;Recent improvements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better separation between parsing, evaluation, and emission
&lt;/li&gt;
&lt;li&gt;More explicit handling of Jinja expressions
&lt;/li&gt;
&lt;li&gt;Cleaner error messages
&lt;/li&gt;
&lt;li&gt;More deterministic behavior across Python versions&lt;/li&gt;
&lt;li&gt;Extensive testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the kind of progress that makes YAMLpp feel less like a prototype and more like a &lt;strong&gt;language you want to trust in production&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Documentation that reflects reality
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://yamlpp.readthedocs.io" rel="noopener noreferrer"&gt;ReadTheDocs site&lt;/a&gt; has been updated to match the current state of the project. The original &lt;a href="https://dev.to/fralau/yamlpp-is-dynamicself-generating-yaml-2cb8"&gt;DEV.to article&lt;/a&gt; introduced the vision; the docs now show how to actually use YAMLpp today.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear examples
&lt;/li&gt;
&lt;li&gt;Updated syntax
&lt;/li&gt;
&lt;li&gt;A more accurate description of the macro language
&lt;/li&gt;
&lt;li&gt;A better explanation of how YAMLpp transforms YAML trees
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Ability to read databases
&lt;/h2&gt;

&lt;p&gt;You can know load values no only from JSON, YAML or TOML files, but also from relational databases.&lt;/p&gt;

&lt;p&gt;This can be done with the &lt;code&gt;.def_sql&lt;/code&gt;, &lt;code&gt;.exec_sql&lt;/code&gt;, and &lt;code&gt;.load_sql&lt;/code&gt; constructs.&lt;/p&gt;

&lt;p&gt;See explanation on &lt;a href="https://yamlpp.readthedocs.io/en/latest/reference/#loading-from-sql-tables" rel="noopener noreferrer"&gt;documentation page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Exporting files
&lt;/h2&gt;

&lt;p&gt;You can now instruct your script to export files (not only in YAML, but also JSON or TOML), with the &lt;code&gt;.export&lt;/code&gt; construct.&lt;/p&gt;

&lt;p&gt;See explanation on &lt;a href="http://127.0.0.1:8000/reference/#export" rel="noopener noreferrer"&gt;documentation page&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  🎯 Why this matters
&lt;/h1&gt;

&lt;p&gt;YAML is everywhere — Kubernetes, Docker, CI pipelines, IaC, cloud deployments, microservices, ML workflows. But YAML itself hasn’t evolved.&lt;/p&gt;

&lt;p&gt;YAMLpp is one of the few projects trying to push YAML forward without breaking compatibility. It respects YAML’s strengths while giving it the dynamic capabilities modern systems need.&lt;/p&gt;

&lt;p&gt;If you’ve ever wished YAML could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reuse values
&lt;/li&gt;
&lt;li&gt;generate multiple files
&lt;/li&gt;
&lt;li&gt;adapt to environments
&lt;/li&gt;
&lt;li&gt;include logic
&lt;/li&gt;
&lt;li&gt;import other YAML files
&lt;/li&gt;
&lt;li&gt;integrate with Python
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…YAMLpp is worth watching again.&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ Want to explore?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/fralau/yamlpp" rel="noopener noreferrer"&gt;https://github.com/fralau/yamlpp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://yamlpp.readthedocs.io" rel="noopener noreferrer"&gt;https://yamlpp.readthedocs.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pypi: &lt;a href="https://pypi.org/project/yamlpp-lang/" rel="noopener noreferrer"&gt;https://pypi.org/project/yamlpp-lang/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Original DEV.to intro: &lt;a href="https://dev.to/fralau/yamlpp-is-dynamicself-generating-yaml-2cb8"&gt;https://dev.to/fralau/yamlpp-is-dynamicself-generating-yaml-2cb8&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is still small, but the ideas are big — and the recent progress shows that YAMLpp is entering a new, more mature phase.&lt;/p&gt;

&lt;p&gt;If you’re interested in dynamic configuration, DSLs, or YAML tooling, now is a great time to take another look.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tooling</category>
      <category>kubernetes</category>
      <category>json</category>
    </item>
    <item>
      <title>Are Blockchains Behaving Like Beehives?</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Wed, 10 Dec 2025 10:58:45 +0000</pubDate>
      <link>https://dev.to/fralau/are-blockchains-behaving-like-beehives-3ha5</link>
      <guid>https://dev.to/fralau/are-blockchains-behaving-like-beehives-3ha5</guid>
      <description>&lt;p&gt;I would like to submit a thought that people interested in blockchain and crypto would understand better than others.&lt;/p&gt;

&lt;p&gt;Did you know 🐝 𝗧𝗵𝗲 𝗕𝗲𝗲𝗵𝗶𝘃𝗲 𝗣𝗮𝗿𝗮𝗱𝗼𝘅 𝗼𝗳 𝗕𝗹𝗼𝗰𝗸𝗰𝗵𝗮𝗶𝗻 𝗖𝗼𝗺𝗺𝘂𝗻𝗶𝘁𝗶𝗲𝘀? All large blockchain communities, despite being born with decentralized rules, will always result in centralization.&lt;/p&gt;

&lt;p&gt;𝗕𝗹𝗼𝗰𝗸𝗰𝗵𝗮𝗶𝗻 𝗰𝗼𝗺𝗺𝘂𝗻𝗶𝘁𝗶𝗲𝘀 𝗮𝗿𝗲 𝗹𝗶𝗸𝗲 𝗯𝗲𝗲𝗵𝗶𝘃𝗲𝘀: decentralized by design, yet centralization emerges as they scale.&lt;/p&gt;

&lt;p&gt;That's a property embedded in the rules of nature.&lt;/p&gt;

&lt;p&gt;In nature, thousands of bees coordinate in a decentralized way, through elementary self-contained algorithms and simple communication protocols — foraging, cleaning, defending. But one queen becomes the reproductive center. If she dies, the hive looks alive for a while, yet the survival chain is broken and collapse is inevitable.&lt;/p&gt;

&lt;p&gt;Blockchain mirrors the structure of a beehive:&lt;/p&gt;

&lt;p&gt;𝗪𝗼𝗿𝗸𝗲𝗿𝘀 = everyday participants transacting on‑chain.&lt;br&gt;
𝗦𝗼𝗹𝗱𝗶𝗲𝗿𝘀 = validators and consensus enforcers.&lt;br&gt;
𝗗𝗿𝗼𝗻𝗲𝘀 = miners and liquidity providers.&lt;br&gt;
𝗤𝘂𝗲𝗲𝗻𝘀 = custodians, issuers, foundations reproducing credibility and continuity.&lt;/p&gt;

&lt;p&gt;Unlike in nature, blockchain hives often tolerate 𝗺𝘂𝗹𝘁𝗶𝗽𝗹𝗲 𝗾𝘂𝗲𝗲𝗻𝘀 — exchanges, stablecoin issuers, foundations — fragmenting the swarm into overlapping sub-colonies. This poly‑queen structure is both the 𝗶𝗻𝘁𝗿𝗶𝗻𝘀𝗶𝗰 𝘀𝘁𝗿𝗲𝗻𝗴𝘁𝗵 𝗮𝗻𝗱 𝘄𝗲𝗮𝗸𝗻𝗲𝘀𝘀 of the ecosystem.&lt;/p&gt;

&lt;p&gt;The 𝗦𝘁𝗿𝗲𝗻𝗴𝘁𝗵: decentralization at the core of the system creates resilience. &lt;br&gt;
The 𝗪𝗲𝗮𝗸𝗻𝗲𝘀𝘀: continuity depends on central “queens.” If a 𝗾𝘂𝗲𝗲𝗻 𝗱𝗶𝗲𝘀 — for example, an 𝗲𝘅𝗰𝗵𝗮𝗻𝗴𝗲 𝗴𝗼𝗲𝘀 𝗯𝗮𝗻𝗸𝗿𝘂𝗽𝘁 — its part of the ecosystem dies.&lt;/p&gt;

&lt;p&gt;In fact, the death (bankruptcy) of a queen could destabilize others, in a domino effect and lead to the 𝗰𝗼𝗹𝗹𝗮𝗽𝘀𝗲 𝗼𝗳 𝘁𝗵𝗲 𝗯𝗲𝗲𝗵𝗶𝘃𝗲, propagated by panic; in finance this is called the &lt;a href="https://www.ecb.europa.eu/press/financial-stability-publications/fsr/focus/2007/pdf/ecb~ccda416def.fsrbox200712_19.pdf" rel="noopener noreferrer"&gt;𝗛𝗲𝗿𝘀𝘁𝗮𝘁𝘁 𝗥𝗶𝘀𝗸&lt;/a&gt; -- from the name of a German bank, in 1970s, whose bankruptcy nearly collapsed the national banking system, because of the late settlement of transactions.&lt;/p&gt;

&lt;p&gt;In the Bitcoin ecosystem in particular, the Herstatt Risk should be seriously considered, because it is an existential risk -- admittedly, it would not kill the blockchain itself, but it could seriously hurt the market value of Bitcoin... making the currency less desirable; and in the extreme, it could make that currency pointless. &lt;/p&gt;

&lt;p&gt;Exchanges can take measures to protect themselves against the Herstatt Risk, using the blockchain to settle their mutual debts. However, it can be shown that there will always be a residual risk. And it requires, also, that the community becomes aware of the Herstatt Risk.&lt;/p&gt;

&lt;p&gt;👉 The 𝗕𝗲𝗲𝗵𝗶𝘃𝗲 𝗣𝗮𝗿𝗮𝗱𝗼𝘅: decentralized by design, but centralization inevitably emerges with scale. And with centralization comes the concept of 𝗱𝗲𝗮𝘁𝗵, which is a mechanism rooted in nature, which is necessary to any ecosystem. So part of the game for any blockchain community, is to find strategies avoiding the risk of death for the whole colony.&lt;/p&gt;

&lt;p&gt;What do you think? Do you see how exchanges could be affected by the Herstatt risk?&lt;/p&gt;

&lt;p&gt;(Article adapted from a &lt;a href="https://www.linkedin.com/posts/lfranceschetti_did-you-know-%F0%9D%97%A7%F0%9D%97%B5%F0%9D%97%B2-%F0%9D%97%95%F0%9D%97%B2%F0%9D%97%B2%F0%9D%97%B5%F0%9D%97%B6%F0%9D%98%83%F0%9D%97%B2-%F0%9D%97%A3%F0%9D%97%AE%F0%9D%97%BF%F0%9D%97%AE%F0%9D%97%B1%F0%9D%97%BC%F0%9D%98%85-activity-7404039739940655104-bRcf" rel="noopener noreferrer"&gt;post on Linkedin&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>bitcoin</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>YAMLpp is dynamic,self-generating YAML</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Tue, 02 Dec 2025 11:15:36 +0000</pubDate>
      <link>https://dev.to/fralau/yamlpp-is-dynamicself-generating-yaml-2cb8</link>
      <guid>https://dev.to/fralau/yamlpp-is-dynamicself-generating-yaml-2cb8</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://yaml.org/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt;&lt;/strong&gt; is a great file format, used for writing configuration files; and more and more, as a foundation for Domain Specific Languages (DSLs), such as script files for Github workflows, Docker or Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make YAML dynamic?
&lt;/h2&gt;

&lt;p&gt;We have all, however, suffered from a frustration: &lt;strong&gt;YAML is fundamentally a static file format&lt;/strong&gt;. How can we make it dynamic? &lt;/p&gt;

&lt;p&gt;It starts with the fact that some string, like &lt;code&gt;http://dev.company.local&lt;/code&gt; appears several times across the files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://dev.company.local&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;documentation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://dev.company.local/docs&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the day that address changes, what do we do?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Do a &lt;strong&gt;search/replace&lt;/strong&gt; in the config files? Nah... &lt;em&gt;this is brittle and things will get worse before they get better&lt;/em&gt;. &lt;/li&gt;
&lt;li&gt;Define constant values with &lt;a href="https://support.atlassian.com/bitbucket-cloud/docs/yaml-anchors/" rel="noopener noreferrer"&gt;anchors&lt;/a&gt; (&lt;code&gt;&amp;amp;&lt;/code&gt;), and then use aliases (&lt;code&gt;*&lt;/code&gt;) to refer to them in the rest of the YAML file.   This is a really neat feature, which gives YAML an advantage over formats: now you can put your constants on the top of the file. Anchors don't need to be strings or numbers (&lt;code&gt;foo&lt;/code&gt;, or &lt;code&gt;5&lt;/code&gt;), but can also be maps or sequences (&lt;code&gt;{foo: 5, bar: 6}&lt;/code&gt;, or &lt;code&gt;[foo, bar, baz]&lt;/code&gt;). However it doesn't solve many cases where &lt;em&gt;it's more complicated than a simple change of code snippet&lt;/em&gt;. A "small" change of parameter (from &lt;code&gt;dev&lt;/code&gt; to &lt;code&gt;test&lt;/code&gt; and from &lt;code&gt;test&lt;/code&gt; to &lt;code&gt;live&lt;/code&gt;) leads to significant changes in the YAML tree.&lt;/li&gt;
&lt;li&gt;All right, then solve it with a little bit of &lt;strong&gt;templating&lt;/strong&gt;, using Jinja (Python) or the Go native engine. Solved! ...Really? Everything is fine for a while, and then &lt;em&gt;the workflow crashes because some corner case broke the YAML syntax&lt;/em&gt;. And we start fiddling-fiddling with spaces and escaping and newlines... and after 5 or 10 abort-debug-rerun cycles, the delivery is running late.&lt;/li&gt;
&lt;li&gt;OK, what we can do now? Use a &lt;strong&gt;preprocessing language&lt;/strong&gt; guaranteed to produce valid syntax, like &lt;a href="https://jsonnet.org/" rel="noopener noreferrer"&gt;Jsonnet&lt;/a&gt; for json? That wil work, for sure. However, you have now a &lt;em&gt;friction&lt;/em&gt; problem: it's new language with its own syntax and file format, which requires implementing its own toolchain (Jsonnet is not json, so editor add-ons, parsers, interpreters, libraries, etc.) and you will need to drive the team through the learning curve of that language with its own syntax and semantic. Will you implement a serious project... or will you have a coffee break at that point, and keep doing things the same old way?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enter YAMLpp
&lt;/h2&gt;

&lt;p&gt;Faced with that &lt;strong&gt;problem&lt;/strong&gt;, I decided that it needed a &lt;strong&gt;straightforward solution&lt;/strong&gt;, which required basically only &lt;em&gt;one&lt;/em&gt; utility (a pre-processor) to convert files into static YAML, and would change nothing else anywhere.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;&lt;a href="https://yamlpp.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;YAMLpp&lt;/a&gt;&lt;/strong&gt; (&lt;em&gt;YAML Pre-Processor&lt;/em&gt;). It is a language that makes YAML dynamic, but &lt;em&gt;it is itself YAML&lt;/em&gt;. So you can use your current editor which does your color highlighting, syntax checking, and so on.&lt;/p&gt;

&lt;p&gt;Let's start with a Hello World example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;.context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;World"&lt;/span&gt;

&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't think there is a lot to explain here. &lt;code&gt;.context&lt;/code&gt; is called a &lt;strong&gt;construct&lt;/strong&gt;, because it 'constructs' (builds) a YAML sub-tree or does something useful; in this case it defines a variable &lt;code&gt;name&lt;/code&gt; and leaves no trace.&lt;/p&gt;

&lt;p&gt;All constructs start with a &lt;code&gt;.&lt;/code&gt; (a dot). In YAMLpp, &lt;code&gt;.context&lt;/code&gt; is known as a &lt;strong&gt;keyword&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then &lt;code&gt;message&lt;/code&gt; contains a string that will be interpolated using the &lt;code&gt;name&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Here is the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see, the node &lt;code&gt;.context&lt;/code&gt; disappeared. That's a rule for all YAMLpp constructs: they disappear and never make it to the target file.&lt;/p&gt;

&lt;h2&gt;
  
  
  YAMLpp is a metaprogramming tool
&lt;/h2&gt;

&lt;p&gt;It goes much further than that. &lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;macro language&lt;/strong&gt; written in YAML, the same language as the target language YAML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;.context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;.if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;.cond&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(platform,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}})"&lt;/span&gt;
    &lt;span class="na"&gt;.then&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod.machine.local&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;
    &lt;span class="na"&gt;.else&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;
      &lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev.machine.local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev.machine.local&lt;/span&gt;
   &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.if&lt;/code&gt; construct is &lt;strong&gt;expanded&lt;/strong&gt;: &lt;code&gt;.if&lt;/code&gt;, &lt;code&gt;.cond&lt;/code&gt;, &lt;code&gt;.then&lt;/code&gt; and &lt;code&gt;.else&lt;/code&gt; keywords will disappear, and only the intended final YAML nodes will remain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For anyone who had anything to do with LISP or one its offspring languages, you know that a language that generates itself through macros, is a huge deal, because it opens the doors to &lt;em&gt;meta-programming&lt;/em&gt;.&lt;/strong&gt; In essence, are able to create your own &lt;strong&gt;Domain-Specific Language&lt;/strong&gt; (DSL), for configuration or scripting.&lt;/p&gt;

&lt;p&gt;For the others for whom this might sound a little too abstract: what you write in &lt;a href="https://yamlpp.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;YAMLpp&lt;/a&gt; is still YAML, but allows you to manipulate your target YAML tree in any way you please. You are now able to express &lt;strong&gt;high-level concepts&lt;/strong&gt; in your config file or script in a way that is meaningful to &lt;em&gt;you&lt;/em&gt; and your team (expressive, shorter, non-repetitive), which will be &lt;strong&gt;expanded&lt;/strong&gt; into a form (YAML) that the machine will be able to test/interpret correctly and that everyone else will understand -- because its part of the standard specification. &lt;br&gt;
So now, YAML can be either dynamic (when it contains YAMLpp keywords) or static (without them). But regardless, it is still valid YAML.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where do I go from there?
&lt;/h2&gt;

&lt;p&gt;A working prototype was developed in Python and it already has its test suite (with pytest). &lt;/p&gt;

&lt;p&gt;To install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;yamlpp-lang
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You just need one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yamlpp input.yaml &lt;span class="nt"&gt;-o&lt;/span&gt; output.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information see the &lt;a href="https://github.com/fralau/yamlpp" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; and the &lt;a href="https://yamlpp.readthedocs.io/" rel="noopener noreferrer"&gt;documentation on ReadTheDocs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also look at a &lt;a href="https://yamlpp.readthedocs.io/en/latest/guide/" rel="noopener noreferrer"&gt;webpage containing two realistic use cases, one for Kubernetes and one for Docker&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Anyone had personal experience learning Go from a previous experience with Python? Apart from the obvious differences (compilation, static typing, composition instead of inheritance,etc.), what was most significant?</title>
      <dc:creator>Laurent Franceschetti</dc:creator>
      <pubDate>Tue, 02 Dec 2025 07:16:17 +0000</pubDate>
      <link>https://dev.to/fralau/anyone-had-personal-experience-learning-go-from-a-previous-experience-with-python-apart-from-the-2pff</link>
      <guid>https://dev.to/fralau/anyone-had-personal-experience-learning-go-from-a-previous-experience-with-python-apart-from-the-2pff</guid>
      <description></description>
    </item>
  </channel>
</rss>
