<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://crosson.org/blog/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://crosson.org/blog/blog/" rel="alternate" type="text/html" /><updated>2025-05-10T10:47:27+02:00</updated><id>https://crosson.org/blog/blog/feed.xml</id><title type="html">comPmoc blog</title><subtitle>comPmoc is a technical blog about computer science, programming practices, coding experiments, ... mainly focused on my current favorites techs. But this is also a way for me to learn &amp; share !</subtitle><entry><title type="html">The rules for good code snippets</title><link href="https://crosson.org/blog/blog/2025/05/09/the-rules-for-good-code-examples.html" rel="alternate" type="text/html" title="The rules for good code snippets" /><published>2025-05-09T12:00:00+02:00</published><updated>2025-05-09T12:00:00+02:00</updated><id>https://crosson.org/blog/blog/2025/05/09/the-rules-for-good-code-examples</id><content type="html" xml:base="https://crosson.org/blog/blog/2025/05/09/the-rules-for-good-code-examples.html"><![CDATA[<h1 id="the-rules-for-good-code-snippets"><a href="https://github.com/dacr/the-rules-for-good-code-examples">The rules for good code snippets</a></h1>

<p>Code snippets are essential; each snippet is most of the time
designed to focus on a particular feature/characteristic of a
programming language, a library, a framework or a behavior.
They help us to quickly test, experiment and remember how bigger
projects or at least some parts of them are working. They can even
be used as quick proofs of concept.</p>

<p>Learning or remembering is much quicker when you have at your disposal
your own set of snippets. This set of snippets is a <strong>knowledge asset</strong>,
we must become aware of its value for us but also from a project team or
company point of view. Any newcomer on a project will have a faster learning
curve if he/she has access to a set of snippets that capture the essence
of the project.</p>

<p>Nowadays, with all the progress made on Artificial Intelligence, this 
asset is even becoming more and more important as it can be used for
model training or fine-tuning purposes!</p>

<p><img src="/blog/assets/cem-keywords-2.png" alt="" /></p>

<p>With some simple rules and a little discipline, you can make your snippets quite easy
to manage and share. Let’s <a href="#simple-rules-for-good-code-snippets">review those rules</a>
and how I’m <a href="#experience-returns">following them with dedicated software</a> in a second step.</p>

<h2 id="simple-rules-for-good-code-snippets">Simple rules for good code snippets</h2>

<ul>
  <li><a href="#one-purpose-rule"><strong>One purpose rule</strong></a></li>
  <li><a href="#one-file-rule"><strong>One file rule</strong></a></li>
  <li><a href="#easy-to-run-rule"><strong>Easy-to-run rule</strong></a></li>
  <li><a href="#self-describing-rule"><strong>Self-describing rule</strong></a></li>
  <li><a href="#security-and-confidentiality-rule"><strong>Security and confidentiality rule</strong></a></li>
  <li><a href="#manageable-and-shareable-rule"><strong>Manageable and shareable rule</strong></a></li>
</ul>

<p>When writing source code snippets, try to take into account the maximum
number of those rules to implement the best possible snippets.</p>

<h3 id="one-purpose-rule">One purpose rule</h3>

<p><strong>A good code snippet has one purpose</strong>, such as learning something, writing a quick proof of concept,
automating a task, keeping the overall design principles of a project,
testing some programming language feature, …</p>

<p>The underlying goal is to speed up the reminding process. If you come back several months, years on
a given snippet, you’ll be able to quickly understand what it does and how it works.</p>

<p>A NIX regex snippet: The purpose is to quickly illustrate how regex works in the NIX language</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span>
  <span class="nv">results</span> <span class="o">=</span> <span class="kr">builtins</span><span class="o">.</span><span class="nv">split</span> <span class="s2">"&lt;([^&gt;]+)&gt;"</span> <span class="s2">"John Doe &lt;john.doe@example.com&gt;"</span><span class="p">;</span>
<span class="kn">in</span> <span class="kn">with</span> <span class="kr">builtins</span><span class="p">;</span> <span class="p">{</span>
  <span class="nv">first_matching_1</span> <span class="o">=</span> <span class="p">(</span><span class="nv">head</span> <span class="p">(</span><span class="nv">head</span> <span class="p">(</span><span class="nv">tail</span> <span class="nv">results</span><span class="p">)))</span> <span class="p">;</span>
  <span class="nv">first_matching_2</span> <span class="o">=</span> <span class="p">(</span><span class="nv">elemAt</span> <span class="nv">results</span> <span class="mi">1</span><span class="p">)</span> <span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="one-file-rule">One file rule</h3>

<p><strong>A good code snippet is just one file</strong>. A single file with a meaningful directory tree and naming
helps a lot to keep the complexity under control as well as it enhances the developer experience once
the snippet has been shared. The directory tree can be used to group snippets by topic, by language,
by technology stack, … while the filename synthesizes their purpose.</p>

<p>A bash snippet stored in a file named <code class="language-plaintext highlighter-rouge">bash-date-iso8601-formatted.sh</code>,
just from the filename we know it is about how to generate iso8601 dates
from the bash shell:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">date</span> <span class="nt">-Is</span>   <span class="c"># not GMT</span>
<span class="nb">date</span> <span class="nt">-u</span> +<span class="s2">"%Y-%m-%dT%H:%M:%SZ"</span>
<span class="nb">date</span> <span class="nt">-u</span> +<span class="s2">"%Y-%m-%dT%H:%M:%S.%3NZ"</span>
</code></pre></div></div>

<h3 id="easy-to-run-rule">Easy-to-run rule</h3>

<p><strong>A good code snippet is easy to run</strong>, typically from the command line as a script or
within a Read-Eval-Print-Loop (REPL) session. It also means you will have to provide
all the necessary information to run it. When available the REPL is great to
interactively design or test your snippet.</p>

<p>A Scala snippet executed from a REPL session which illustrates how to use the <a href="https://github.com/datafaker-net/datafaker">java data faker</a> library:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ scala-cli --dep com.github.javafaker:javafaker:1.0.2
Welcome to Scala 3.6.4 (23.0.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala&gt; val faker = new com.github.javafaker.Faker()
     |
     | val appName = faker.app.name
     | val author = faker.name.name
     | val email = faker.internet.emailAddress
     | val company = faker.company.name
     | val companyURL = faker.company.url
     | val country = faker.country.name
     |
     | println(s"""'$appName' an application By $author / $email""")
     | println(s"""'$company' / $country/ $companyURL""")
'Namfix' an application By Tamala Jacobi / joie.sporer@yahoo.com
'Hansen-Yost' / Turkmenistan/ www.macejkovicblickandblanda.co
</code></pre></div></div>

<p>The same snippet made executable from the command line:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./data-fake.sc
'Gembucket' an application By Thad Deckow II / londa.quitzon@hotmail.com
'Goodwin, Cremin and Koss' / Israel/ www.watersgerholdandnicolas.com

$ cat data-fake.sc
#!/usr/bin/env scala-cli
//&gt; using scala "3.6.4"
//&gt; using dep "com.github.javafaker:javafaker:1.0.2"
val faker = new com.github.javafaker.Faker()
val appName = faker.app.name
val author = faker.name.name
val email = faker.internet.emailAddress
val company = faker.company.name
val companyURL = faker.company.url
val country = faker.country.name
println(s"""'$appName' an application By $author / $email""")
println(s"""'$company' / $country/ $companyURL""")

</code></pre></div></div>

<p>The previously shown snippet shows that there is some contextual information provided to
make it easy to run :</p>
<ul>
  <li><strong>required execution runtime</strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">scala-cli</code> is the runtime to use</li>
    </ul>
  </li>
  <li><strong>needed software dependencies</strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">scala 3.6.4</code> is used (and automatically downloaded)</li>
      <li><code class="language-plaintext highlighter-rouge">com.github.javafaker:javafaker:1.0.2</code> is resolved and downloaded (automatically from maven central)</li>
    </ul>
  </li>
</ul>

<p>As just shown, the best developer experience is achieved when you use a technology stack which
is able to <strong>resolve and load dependencies at runtime</strong>. Then you will have
just one file for everything. This is the case at least for :</p>
<ul>
  <li>Scala : <a href="https://scala-cli.virtuslab.org/">scala-cli</a> with the <code class="language-plaintext highlighter-rouge">//&gt;</code> special comment syntax</li>
  <li>Rust : <a href="https://rust-script.org/">rust-script</a> with the <code class="language-plaintext highlighter-rouge">// cargo-deps :</code> or <code class="language-plaintext highlighter-rouge">//!</code> special comment syntaxes</li>
  <li>Java : <a href="https://www.jbang.dev/">jbang</a> with the <code class="language-plaintext highlighter-rouge">//DEP</code> special comment syntax</li>
</ul>

<p>You can also use a <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a> to make your snippet directly executable
while giving to the reader the information about how it is executed.</p>

<h3 id="self-describing-rule">Self-describing rule</h3>

<p><strong>A good code snippet describes by itself what it does</strong>. When it makes sense, design your snippet
to make its execution self-describing. This is quite simple if you <strong>use a unit test framework</strong>
as most of them can generate a report on standard output.</p>

<p>A Scala snippet execution showing the behavior of the <a href="https://github.com/lihaoyi/upickle">upickle</a> library:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Run starting. Expected test count is: 6
JsonUpickleCookBook:
upickle
- should deserialize json array strings (36 milliseconds)
- should deserialize scala case classes ? (7 milliseconds)
- should deserialize scala case classes with optional field? default value is supported (3 milliseconds)
- should deserialize scala case classes with optional field? (3 milliseconds)
- should deserialize scala list (0 milliseconds)
- should provide an AST (13 milliseconds)
Run completed in 194 milliseconds.
Total number of tests run: 6
Suites: completed 1, aborted 0
Tests: succeeded 6, failed 0, canceled 0, ignored 0, pending 0
All tests passed.
</code></pre></div></div>

<p>So when executed, the output describes exactly what it does, and even more, as this is
unit tests based, it will fail until you gave the right implementation!
Or until you’ve understood what’s going on ;)</p>

<h3 id="security-and-confidentiality-rule">Security and confidentiality rule</h3>

<p><strong>A good code snippet takes care of security and confidentiality</strong>. It should not contain any
sensitive information, and should not be able to access any sensitive information.</p>

<p>Some good practices related to security and confidentiality :</p>
<ul>
  <li><strong>No secrets</strong> (tokens, passwords, passphrases, cryptographic keys, …)
    <ul>
      <li>Use environment variables to inject secrets if needed</li>
    </ul>
  </li>
  <li><strong>No sensible data</strong> (IP addresses, usernames, internal URL, …)
    <ul>
      <li>Use environment variables to inject sensible data</li>
    </ul>
  </li>
  <li><strong>No sensible code</strong> in snippets you plan to share
    <ul>
      <li>Stay as generic as possible</li>
      <li>Consider shared snippets as learning materials or basic tools</li>
    </ul>
  </li>
  <li>Always keep in mind <strong>trademarks, copyrights, licenses</strong>
    <ul>
      <li>Really take care with copy/paste content from anywhere</li>
      <li>Avoid the use of internal AI assistant if you plan to share the snippet</li>
    </ul>
  </li>
</ul>

<p>Scala snippet which uses an environment variable to inject a secret :</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//...</span>
<span class="nf">envOrNone</span><span class="o">(</span><span class="s">"RANDOM_ORG_API_KEY"</span><span class="o">)</span> <span class="k">match</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">None</span>      <span class="k">=&gt;</span> <span class="nf">println</span><span class="o">(</span><span class="s">"Signup to random.org, create an api key or reuse an existing one - https://api.random.org/dashboard"</span><span class="o">)</span>
  <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">key</span><span class="o">)</span> <span class="k">=&gt;</span>
    <span class="nf">println</span><span class="o">(</span><span class="nf">generate</span><span class="o">(</span><span class="n">key</span><span class="o">,</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">49</span><span class="o">).</span><span class="py">sorted</span><span class="o">.</span><span class="py">mkString</span><span class="o">(</span><span class="s">","</span><span class="o">))</span>
    <span class="nf">println</span><span class="o">(</span><span class="nf">generate</span><span class="o">(</span><span class="n">key</span><span class="o">,</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">10</span><span class="o">).</span><span class="py">sorted</span><span class="o">.</span><span class="py">mkString</span><span class="o">(</span><span class="s">","</span><span class="o">))</span>
<span class="o">}</span>
<span class="c1">//...</span>
</code></pre></div></div>

<h3 id="manageable-and-shareable-rule">Manageable and shareable rule</h3>

<p><strong>A good code snippet comes with meta-data</strong> typically used to identify it uniquely, 
to describe how to share it, to add license information, description keywords, …</p>

<p>Why? Because once you or your team have written hundreds of snippets, you’ll quickly need to
industrialize their life cycle. You’ll need to find solutions for :</p>
<ul>
  <li>how to search through your snippets?</li>
  <li>how to share them? Publicly or internally?</li>
  <li>how to check their execution status?</li>
  <li>how to manage change history?</li>
  <li>how to let people react over them?</li>
  <li>…</li>
</ul>

<p>In relation to the <a href="#one-file-rule">one-file rule</a> the right approach is to add meta-data
as comments directly in the header of the snippet file. It enables resilience and simplicity.</p>

<p>Snippet meta-data header example, coming from my chosen approach :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// summary : take a look into models zoo
// keywords : djl, machine-learning, tutorial, detection, ai, zoo, @testable
// publish : gist
// authors : David Crosson
// license : Apache License Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
// id : f6b25f1c-2d29-4cdb-a030-f7dbb3b94e96
// created-on : 2022-03-09T18:41:39+01:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
</code></pre></div></div>

<p>Once you’ve achieved this, you will discover that you are currently building a knowledge base,
 which can be automatically processed by dedicated software.</p>

<p>Let’s take a look at my experience returns and the dedicated software I’m using to achieve all of this.</p>

<h2 id="experience-returns">Experience returns</h2>

<p>I wrote my first “good” snippet back in 2018 (<a href="https://gist.github.com/dacr/50b74b837008af547fd44e00f9d47944">Fully asynchronous http client call with JSON response using akka-http</a>
and now 7 years later, I’ve a data set made of almost 1300 snippets (almost 1000 are publishable).</p>
<ul>
  <li>All my personal snippets are stored in a private GIT repository</li>
  <li>All my team snippets are stored in a shared GIT repository</li>
  <li>Almost everything is managed by a dedicated software called <a href="https://github.com/dacr/code-examples-manager">code-examples-manager</a> :
    <ul>
      <li>publishes/synchronizes on <a href="https://gist.github.com/dacr">GitHub gists</a> and <a href="https://gitlab.com/users/crosson.david/snippets">Gitlab snippets</a></li>
      <li>generates and synchronizes a summary of <a href="https://gist.github.com/dacr/c071a7b7d3de633281cbe84a34be47f1">the published snippets knowledge base</a></li>
      <li>executes all executable snippets to check their states and if some maintenance is needed</li>
      <li>check global snippets coherency and report various statistics</li>
    </ul>
  </li>
  <li>A tool coded as a snippet (<a href="https://gist.github.com/dacr/f25da8222b2ac644c3195c5982b7367e">cem-tool.sc</a>) is used to feed an opensearch search engine
    <ul>
      <li>Dashboard with various statistics,</li>
      <li>Snippets execution trends, …</li>
    </ul>
  </li>
  <li>Stable set of meta-data keywords, see <a href="https://github.com/dacr/code-examples-manager">code-examples-manager</a> for more information</li>
  <li>Such a discipline over the years unlocks me various opportunities
    <ul>
      <li>Elasticsearch/opensearch training with a part based on this dataset :)</li>
      <li>Various AI-related experiments again with this dataset :)</li>
    </ul>
  </li>
  <li>I’ve started with what I initially called code examples, now it can be anything, so I use the ‘snippet’ terminology
    <ul>
      <li>snippets as documentation,</li>
      <li>snippets as configuration files,</li>
      <li>snippets as dedicated dataset (csv content for example),</li>
      <li>…</li>
    </ul>
  </li>
  <li>My state of mind
    <ul>
      <li>I’m happy to share my snippets</li>
      <li>I use them every day as they are fully integrated in my daily work</li>
      <li>Time to add more AI use cases with them</li>
    </ul>
  </li>
</ul>

<p><img src="/blog/assets/cem-dashboard.png" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[The rules for good code snippets]]></summary></entry><entry><title type="html">EDD : Example Driven Development</title><link href="https://crosson.org/blog/blog/2021/05/24/edd.html" rel="alternate" type="text/html" title="EDD : Example Driven Development" /><published>2021-05-24T16:00:00+02:00</published><updated>2021-05-24T16:00:00+02:00</updated><id>https://crosson.org/blog/blog/2021/05/24/edd</id><content type="html" xml:base="https://crosson.org/blog/blog/2021/05/24/edd.html"><![CDATA[<p>For comments, <a href="https://twitter.com/crodav/status/1396853815924645891">Use this tweeter post</a></p>

<p>In fact, you are probably already doing Example Driven Development (EDD)
without being aware of it ! This last week-end I realized I was designing
software using this approach.</p>

<p>Example Driven Development is simply write code examples which are independent with progressive complexity 
while having one objective in mind (the software you want to write) :</p>
<ol>
  <li><strong>Write generic examples</strong> to
    <ul>
      <li>Improve your knowledge of the programming language you have chosen</li>
      <li>Learn how to use the API you expect to use</li>
    </ul>
  </li>
  <li><strong>Write experimental examples</strong> to validate your choices
    <ul>
      <li>Try a single simple feature as an example</li>
      <li>Check performance behavior, easy of use</li>
    </ul>
  </li>
  <li><strong>Write proof of concepts as code examples</strong> to
    <ul>
      <li>Iterate and fail fast</li>
      <li>As soon as an example looks good, keep it and start a new better one</li>
      <li>OF COURSE USE THEM in real world situations</li>
    </ul>
  </li>
  <li>Then with complexity increase, <strong>create a true software project</strong> with its dedicated GIT repository
    <ul>
      <li>Switch Test Driven Development (TDD) approach</li>
      <li>but you will still continue to use EDD, believe me ;)</li>
    </ul>
  </li>
</ol>

<p>Example Driven Development requires some rules and in fact while writing those
words, I realized I’ve already described them in “<a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html">The rules for good code examples</a>”
article :</p>
<ul>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#one-purpose-rule">One purpose</a></li>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#limited-size-rule">Limited size</a></li>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#runnable-rule">Runnable</a></li>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#exploratory-compatible-rule">Exploratory compatible</a></li>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#self-describing-rule">Self-describing</a></li>
  <li><a href="https://crosson.org/blog/2021/01/01/the-rules-for-good-code-examples.html#manageable-and-shareable-rule">manageable and shareable</a></li>
</ul>

<p>The only differences is that you’ll write a set of code examples, with progressive
complexity increase, for your current software objective. This set is your EDD living
code examples for your current software objective.</p>

<p>Even better, I followed the EDD without naming it while I was writing my <a href="https://github.com/dacr/code-examples-manager">code-examples-manager (CEM) software</a>.
I’ve of course archived all the steps, which perfectly illustrate the EDD principles and the associated intellectual approach :</p>
<ul>
  <li><strong>2019-05</strong> - <a href="https://gist.github.com/dacr/c071a7b7d3de633281cbe84a34be47f1#cemcem-design-steps">5 examples</a> to prepare myself and learn Github API</li>
  <li><strong>2019-06</strong> - <a href="https://gist.github.com/dacr/88966cba361061be20d50534711a6c2a">CEM PoC#1</a> proof of concept as code example (in production for my own usage)</li>
  <li><strong>2019-07</strong> - <a href="https://gist.github.com/dacr/c525e743825ef10afe1e6bc72737554b">CEM PoC#2</a> proof of concept as code example (in production for my own usage)</li>
  <li><strong>2019-08</strong> - CEM Switch to a real world project : <a href="https://github.com/dacr/code-examples-manager">created the github project</a></li>
  <li><strong>2019-09</strong> - CEM in production for my own usage</li>
  <li><strong>2020-07</strong> - CEM First public release, feature complete, of course still in production for my own usage</li>
  <li><strong>2021-04</strong> - Learning ZIO, wrote more than <a href="https://gist.github.com/dacr/c071a7b7d3de633281cbe84a34be47f1#zio">40 examples written and maintained</a></li>
  <li><strong>2021-05</strong> - CEM Full refactoring - pure functional -  My first <a href="https://zio.dev/">ZIO</a> app ! It has replaced the old implementation.</li>
  <li><strong>2021-05</strong> - <a href="https://gist.github.com/dacr/c071a7b7d3de633281cbe84a34be47f1#cemelk">search engine code examples</a> to prepare an elasticsearch based search engine for the published code examples</li>
  <li><strong>2021-12</strong> - <a href="https://gist.github.com/dacr/f25da8222b2ac644c3195c5982b7367e">CEM Search &amp; Execution Engine POC</a></li>
</ul>

<p>By practicing it, I can now say that EDD is perfect for individual software development, but not only
I’m convinced it is also suitable for at least small coding teams, may be a subject for a next article
as soon as I’ll have enough data and/or feedbacks.</p>

<p>That’s all Folks.</p>

<p>For comments, <a href="https://twitter.com/crodav/status/1396853815924645891">Use this tweeter post</a></p>]]></content><author><name></name></author><summary type="html"><![CDATA[For comments, Use this tweeter post]]></summary></entry><entry><title type="html">FASTER integration and deployment with coursier</title><link href="https://crosson.org/blog/blog/2021/01/23/coursier-to-start-app.html" rel="alternate" type="text/html" title="FASTER integration and deployment with coursier" /><published>2021-01-23T15:00:00+01:00</published><updated>2021-01-23T15:00:00+01:00</updated><id>https://crosson.org/blog/blog/2021/01/23/coursier-to-start-app</id><content type="html" xml:base="https://crosson.org/blog/blog/2021/01/23/coursier-to-start-app.html"><![CDATA[<p>For comments, <a href="https://twitter.com/crodav/status/1353036393585504258">Use this tweeter post</a></p>

<p><a href="https://get-coursier.io/">Coursier</a> is not only an artifact fetch tool and library, it
can also be used to start a service or an application (<strong>JVM based</strong>) in quite an
efficient way, by just downloading the minimal set of the required
files while reusing those which have already been downloaded and
cached on your host, or on a shared space.</p>

<p>Consider this simple application <a href="https://github.com/dacr/web-echo">web-echo</a> which implements
a simple REST API, the size of the published 1.0.0 artifact
on <a href="https://mvnrepository.com/artifact/fr.janalyse/web-echo_2.13/1.0.0">maven-central</a> is only 118KB, it is small because
its required dependencies just need to be declared instead of being
provided.</p>

<p>Let’s put everything in perspective for <a href="https://mvnrepository.com/artifact/fr.janalyse/web-echo_2.13/1.0.0">web-echo 1.0.0</a> :</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">118 KB</code> if published on maven central as a “library”</li>
  <li><code class="language-plaintext highlighter-rouge">29685 KB</code> if published somewhere using a classic packaging
    <ul>
      <li>this is because of all its required dependencies which
are part of the packaging</li>
    </ul>
  </li>
</ul>

<p><strong>This is a 25000% size tax on each deployment for a legacy packaging.</strong></p>

<p>When first started coursier will of course download everything :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cs launch fr.janalyse::web-echo:1.0.0
</code></pre></div></div>
<p>(Execute <code class="language-plaintext highlighter-rouge">curl http://localhost:8080/info</code> to get a response.)</p>

<p>But for all others deployments where only the code has been changed, it
will just download the main artifact, and for a small bug release fix
it will still be less than 120KB.</p>

<p>Try it with <a href="https://mvnrepository.com/artifact/fr.janalyse/web-echo_2.13/1.0.1">web-echo 1.0.1</a> :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cs launch fr.janalyse::web-echo:1.0.1
</code></pre></div></div>
<p>(<em>just 119K have been downloaded and this web service starts in ~800ms</em>)</p>

<p>So using such approach to integrate or deploy something will save you
a lot of space and network bandwidth while making your CI/CD pipelines
quite faster.</p>

<p>I’m more and more convinced that using dedicated docker image for a
service or an application is not a good idea because of all the overhead
it implies. Instead using a generic or custom-made coursier docker image,
with a good management of the cached artifacts file system will bring
a lot of advantages.</p>

<p>In fact using such approach allows you to decouple the code artifact
from how it is executed, in fact just describe how to run it instead of
provide everything to execute it. In the case of <a href="https://github.com/dacr/web-echo">web-echo</a>, this is
quite simple, the binary artifact already contains a <code class="language-plaintext highlighter-rouge">META-INF/MANIFEST.MF</code>
which give the code main entry point, and maven central knows its
dependencies as well as it can provide them for coursier.</p>

<p>Through <a href="https://get-coursier.io/docs/cli-launch">coursier launch options</a> and
environment variables you have everything needed to customize your application
as you wish :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export WEB_ECHO_LISTEN_PORT=8888
export WEB_ECHO_PREFIX=truc
cs launch --java-opt -Xms50m --java-opt -Xmx50m fr.janalyse::web-echo:1.0.1 
</code></pre></div></div>
<p>Test it using : <code class="language-plaintext highlighter-rouge">curl http://127.0.0.1:8888/truc/info</code></p>

<p>That’s all Folks.</p>

<p>For comments, <a href="https://twitter.com/crodav/status/1353036393585504258">Use this tweeter post</a></p>

<p>Some other related topic links :</p>
<ul>
  <li><a href="https://medium.com/97-things/slimfast-maven-plugin-hubspots-approach-to-avoiding-fat-jars-22a33544a165">The Case Against Fat JARs</a></li>
  <li><a href="https://product.hubspot.com/blog/the-fault-in-our-jars-why-we-stopped-building-fat-jars">The Fault in Our JARs: Why We Stopped Building Fat JARs</a></li>
  <li><a href="https://github.com/HubSpot/SlimFast">SlimFast</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[For comments, Use this tweeter post]]></summary></entry><entry><title type="html">The rules for good code examples</title><link href="https://crosson.org/blog/blog/2021/01/01/the-rules-for-good-code-examples.html" rel="alternate" type="text/html" title="The rules for good code examples" /><published>2021-01-01T11:00:00+01:00</published><updated>2021-01-01T11:00:00+01:00</updated><id>https://crosson.org/blog/blog/2021/01/01/the-rules-for-good-code-examples</id><content type="html" xml:base="https://crosson.org/blog/blog/2021/01/01/the-rules-for-good-code-examples.html"><![CDATA[<p>For comments, <a href="https://twitter.com/crodav/status/1320442386561015809">use this tweeter post</a></p>

<h1 id="the-rules-for-good-code-examples"><a href="https://github.com/dacr/the-rules-for-good-code-examples">The rules for good code examples</a></h1>

<p>Code examples are very important, each example is most of the time
designed to focus on a particular feature/characteristic of a
programming language, a library or a framework.
They help us to quickly test, experiment and remember how bigger
project or at least some parts of them are working.</p>

<p>Learning or remembering is much quicker when you have at your disposal
your own set of examples. This set of examples is a <strong>knowledge asset</strong>,
we must become aware of its value for us but also from a project team
point of view.</p>

<p>Being aware of this knowledge asset means that you should establish
and follow some simple rules which will help you or your project team to
valorize this asset.</p>

<h2 id="simple-rules-for-good-code-examples">Simple rules for good code examples</h2>

<ul>
  <li><a href="#one-purpose-rule"><strong>One purpose</strong></a></li>
  <li><a href="#limited-size-rule"><strong>Limited size</strong></a></li>
  <li><a href="#runnable-rule"><strong>Runnable</strong></a></li>
  <li><a href="#exploratory-compatible-rule"><strong>Exploratory compatible</strong></a></li>
  <li><a href="#self-describing-rule"><strong>Self-describing</strong></a></li>
  <li><a href="#manageable-and-shareable-rule"><strong>manageable and shareable</strong></a></li>
</ul>

<p>When writing source code examples, try to take into account the maximum
number of those rules in order to implement the best possible examples.</p>

<h3 id="one-purpose-rule">One purpose rule</h3>

<p><strong>A good code example has one purpose</strong> such as learning the basics of a
programming language (the typical <code class="language-plaintext highlighter-rouge">println("Hello world")</code> example) or
experimenting/testing a library or framework.</p>

<p>It can also be used to illustrate how you can achieve one feature, for example
<code class="language-plaintext highlighter-rouge">date -u +"%Y-%m-%dT%H:%M:%S.%3NZ"</code> is a linux date command usage example
which prints a date/time in the ISO8601 standard date format.</p>

<h3 id="limited-size-rule">Limited size rule</h3>

<p><strong>1 example in 1 single file</strong> (when possible) helps to limit the overall
example size as well as it simplifies greatly the sharing.</p>

<p>Try to keep each source code example as short as possible, if over the
time one example becomes larger and larger, try to split it into several
examples, it may also mean you need to drop the example format and switch
to a dedicated project organization.</p>

<p>A good approach is to always start small through a source code example.
When you want to enhance/refactor your initial example and probably add
some complexities, create a copy of your example and make your changes,
it is very important to keep your first iterations as they will retain
the simplest aspects of what was your successive intentions.</p>

<h3 id="runnable-rule">Runnable rule</h3>

<p><strong>Your example self-contains all information required to run it</strong>, so
it means that <strong>it must provide</strong> the following information :</p>
<ul>
  <li>what are the <strong>runtime prerequisites</strong> such as python, jshell, ammonite, bash, julia,…
    <ul>
      <li>while giving precise release information if required such as python-3, java-15</li>
    </ul>
  </li>
  <li>what are its required <strong>software dependencies</strong>
    <ul>
      <li>linux packages required to run this bash script example</li>
      <li>python modules to install before trying to run the example</li>
      <li>maven/classpath required artifacts</li>
    </ul>
  </li>
</ul>

<p>The minimum thing to do is to add comments in your example which list the
required runtime and dependencies information. You can also use a <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>
to make your example directly executable while giving to the example reader the
information about how it is executed.</p>

<p>It is also important that your example <em>prints</em> something, for a function, add
some usage example with visible results.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">):</span>
  <span class="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">1+2=</span><span class="sh">'</span><span class="o">+</span><span class="nf">str</span><span class="p">(</span><span class="nf">add</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)))</span>
</code></pre></div></div>

<p>A very good developer experience is achieved when you use the <a href="https://ammonite.io/">ammonite</a>
REPL as it is able to load software dependencies at runtime !</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#!/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">env</span> <span class="n">amm</span>
<span class="k">import</span> <span class="nn">$ivy.</span><span class="n">`com.lihaoyi::requests:0.6.5`</span>
<span class="nv">requests</span><span class="o">.</span><span class="py">get</span><span class="o">(</span><span class="s">"https://httpbin.org/get"</span><span class="o">).</span><span class="py">lines</span><span class="o">().</span><span class="py">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</code></pre></div></div>
<p>In this small example, the runtime context is given by the shebang, and the dependencies requirements
is directly given by the executed import instruction.</p>

<h3 id="exploratory-compatible-rule">Exploratory compatible rule</h3>

<p>When a read-eval-print-loop (REPL) is available in your example context, organize your example
in a way that it is <strong>easy to copy/paste the example in a REPL session</strong> for interactive
exploratory live experiments.</p>

<p>For one-liner example this is trivial, with longer examples it may add some constraints
depending of your technological choices, so while writing your example, use a REPL session
interactivly to check how it behaves and also to help you enhance your code example.</p>

<p>For example for python don’t forget to add an empty line after each function definition ;) And for
ammonite, it may require either to add some braces within you example or to copy/paste within braces
to avoid any issue.</p>

<h3 id="self-describing-rule">Self-describing rule</h3>

<p>When it makes sense, design your example to make its execution self-describing, this is quite simple
when you <strong>use a unit test framework</strong> as most of them can generate a report. If you use <em>specification</em>
oriented unit tests, it becomes trivial as you can see in the following example output :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>split
- should be able to split in 2 parts using the last dot thanks to zero-width positive lookahead regexp
- should be able to split on characters while preserving those characters
regexp
- should allow partial matching
- should be possible to use named arguments
</code></pre></div></div>

<p>Which is generated by the following example script, a runnable example with flat specification
output brought by the <a href="https://www.scalatest.org/">scalatest</a> unit test framework :</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#!/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">env</span> <span class="n">amm</span>
<span class="k">import</span> <span class="nn">$ivy.</span><span class="n">`org.scalatest::scalatest:3.2.2`</span>
<span class="k">import</span> <span class="nn">org.scalatest._</span><span class="o">,</span> <span class="nv">flatspec</span><span class="o">.</span><span class="py">_</span><span class="o">,</span>  <span class="nv">matchers</span><span class="o">.</span><span class="py">_</span><span class="o">,</span>  <span class="nv">OptionValues</span><span class="o">.</span><span class="py">_</span>
<span class="k">import</span> <span class="nn">java.util.Locale</span>
<span class="k">object</span> <span class="nc">StringOperations</span> <span class="k">extends</span> <span class="nc">AnyFlatSpec</span> <span class="k">with</span> <span class="nv">should</span><span class="o">.</span><span class="py">Matchers</span> <span class="o">{</span>
  <span class="s">"split"</span> <span class="n">should</span> <span class="s">"be able to split in 2 parts using the last dot thanks to zero-width positive lookahead regexp"</span> <span class="n">in</span> <span class="o">{</span>
    <span class="k">val</span> <span class="nv">aType</span><span class="o">=</span><span class="s">"ab.cd.de"</span>
    <span class="k">val</span> <span class="nv">Array</span><span class="o">(</span><span class="n">aPackage</span><span class="o">,</span> <span class="n">aClassName</span><span class="o">)</span> <span class="k">=</span> <span class="nv">aType</span><span class="o">.</span><span class="py">split</span><span class="o">(</span><span class="s">"[.](?=[^.]*$)"</span><span class="o">,</span> <span class="mi">2</span><span class="o">)</span>
    <span class="n">aPackage</span> <span class="n">shouldBe</span> <span class="s">"ab.cd"</span>
    <span class="n">aClassName</span> <span class="n">shouldBe</span> <span class="s">"de"</span>
  <span class="o">}</span>

  <span class="n">it</span> <span class="n">should</span> <span class="s">"be able to split on characters while preserving those characters"</span> <span class="n">in</span> <span class="o">{</span>
    <span class="k">val</span> <span class="nv">in</span> <span class="k">=</span> <span class="s">"abc. truc? blah, blu."</span>
    <span class="nv">in</span><span class="o">.</span><span class="py">split</span><span class="o">(</span><span class="s">"""\s*(?&lt;=[?.,])\s*"""</span><span class="o">).</span><span class="py">toList</span> <span class="n">shouldBe</span> <span class="nc">List</span><span class="o">(</span><span class="s">"abc."</span><span class="o">,</span> <span class="s">"truc?"</span><span class="o">,</span> <span class="s">"blah,"</span><span class="o">,</span> <span class="s">"blu."</span><span class="o">)</span>
  <span class="o">}</span>
  <span class="s">"regexp"</span> <span class="n">should</span> <span class="s">"allow partial matching"</span> <span class="n">in</span> <span class="o">{</span>
    <span class="k">val</span> <span class="nv">MyRE</span><span class="o">=</span><span class="s">"TO(.*)TA"</span><span class="o">.</span><span class="py">r</span><span class="o">.</span><span class="py">unanchored</span>
    <span class="s">"xxTOTUTAxx"</span> <span class="k">match</span> <span class="o">{</span>
      <span class="k">case</span> <span class="nc">MyRE</span><span class="o">(</span><span class="n">inside</span><span class="o">)</span><span class="k">=&gt;</span> <span class="n">inside</span> <span class="n">shouldBe</span> <span class="s">"TU"</span>
      <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="n">fail</span>
    <span class="o">}</span>
  <span class="o">}</span>
  <span class="n">it</span> <span class="n">should</span> <span class="s">"be possible to use named arguments"</span> <span class="n">in</span> <span class="o">{</span>
    <span class="k">val</span> <span class="nv">MyRE</span><span class="o">=</span><span class="s">"TO(?&lt;in&gt;.*)TA"</span><span class="o">.</span><span class="py">r</span>
    <span class="k">val</span> <span class="nv">sample</span> <span class="k">=</span> <span class="s">"TOTUTA"</span>
    <span class="nv">MyRE</span><span class="o">.</span><span class="py">findFirstMatchIn</span><span class="o">(</span><span class="n">sample</span><span class="o">).</span><span class="py">map</span><span class="o">(</span><span class="nv">_</span><span class="o">.</span><span class="py">group</span><span class="o">(</span><span class="s">"in"</span><span class="o">)).</span><span class="py">value</span> <span class="n">shouldBe</span> <span class="s">"TU"</span>
  <span class="o">}</span>
<span class="o">}</span>
<span class="nv">StringOperations</span><span class="o">.</span><span class="py">execute</span><span class="o">()</span>
</code></pre></div></div>
<p>This example comes from <a href="https://gist.github.com/dacr/3b592b9f9ed0b88a7236503f075b8f89">a bigger one</a> I maintain whose purpose is a sheet cheat about advanced operations on strings.</p>

<p><strong>So when executed, the output describes exactly what it does, and even more, as this is unit tests based it will
fail until you give the right implementation ! Or until you’ve understood what’s going on ;)</strong></p>

<h3 id="manageable-and-shareable-rule">Manageable and shareable rule</h3>

<p>Once you’ve written dozens of examples, you’ll quickly need to industrialize their life cycle. It will mean :</p>
<ul>
  <li>how to deal with maintenance ?</li>
  <li>how to share them ? Publicly or internally ?</li>
  <li>how to let people react over them ?</li>
  <li>how to manage their change history ?</li>
  <li>how to write them from your perspective or from the team one ?</li>
  <li>how to search through your examples ?</li>
</ul>

<p>All of these require some good practices, and tooling. Among the good practices one of the most important one is
to insert within each of your example some meta-data in order to give more insights about it. You can add several meta-data
fields such as a short description, a keywords list, some licensing information, … which will greatly help your
examples life-cycle management.</p>

<p>In fact this is quite easy thanks to this simple recipe :</p>
<ul>
  <li>GIT repository to store all your examples
    <ul>
      <li>store your examples or your team collective examples inside a GIT repository</li>
      <li>this repository can be kept private or limited to given set of people</li>
    </ul>
  </li>
  <li><a href="https://gitlab.com/explore/snippets">Gitlab snippets</a>/<a href="https://gist.github.com/">Github gists</a> solutions to share small code example, as they
    <ul>
      <li>give an easy way to publish and share any numbers of examples</li>
      <li>provide user interactions for each example (comments, starring, …)</li>
      <li>provide a search engine</li>
      <li>store the history of all examples changes</li>
    </ul>
  </li>
  <li>And it becomes even easier by using the <a href="https://github.com/dacr/code-examples-manager">code-examples-manager</a> project
    <ul>
      <li>it automates everything, and becomes mandatory as soon as you have dozens of examples.</li>
      <li>Take a look to my publicly <a href="https://gist.github.com/dacr/c071a7b7d3de633281cbe84a34be47f1">shared examples knowledge bases</a>
to have a good idea of what it does.</li>
    </ul>
  </li>
</ul>

<p>For comments, <a href="https://twitter.com/crodav/status/1320442386561015809">use this tweeter post</a></p>

<p><img src="/blog/assets/cem-keywords.png" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[For comments, use this tweeter post]]></summary></entry><entry><title type="html">A good code example ?</title><link href="https://crosson.org/blog/blog/2020/10/10/example-in-article.html" rel="alternate" type="text/html" title="A good code example ?" /><published>2020-10-10T18:00:00+02:00</published><updated>2020-10-10T18:00:00+02:00</updated><id>https://crosson.org/blog/blog/2020/10/10/example-in-article</id><content type="html" xml:base="https://crosson.org/blog/blog/2020/10/10/example-in-article.html"><![CDATA[<p><em>Could we consider the remaining of this blog post as a good
code example ?</em></p>

<p>Using lihaoyi <a href="https://github.com/lihaoyi/requests-scala">requests-scala</a> http client API to
retrieve the content of a http request :</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nn">$ivy.</span><span class="n">`com.lihaoyi::requests:0.6.5`</span>
<span class="nv">requests</span><span class="o">.</span><span class="py">get</span><span class="o">(</span><span class="s">"https://httpbin.org/get"</span><span class="o">).</span><span class="py">lines</span><span class="o">().</span><span class="py">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</code></pre></div></div>

<p>Just copy/paste those lines into an <a href="https://ammonite.io/">ammonite</a> REPL session to execute
them and see the result.</p>

<p><img src="/blog/assets/2020-10-10-terminal-ammonite-repl.png" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[Could we consider the remaining of this blog post as a good code example ?]]></summary></entry><entry><title type="html">Code Example Manager 1.0.1 released</title><link href="https://crosson.org/blog/blog/2020/07/12/code-example-manager.html" rel="alternate" type="text/html" title="Code Example Manager 1.0.1 released" /><published>2020-07-12T16:00:00+02:00</published><updated>2020-07-12T16:00:00+02:00</updated><id>https://crosson.org/blog/blog/2020/07/12/code-example-manager</id><content type="html" xml:base="https://crosson.org/blog/blog/2020/07/12/code-example-manager.html"><![CDATA[<p><a href="https://github.com/dacr/code-examples-manager/">Code example manager (CEM)</a> is a software tool which manage your code examples
and provide publish mechanisms to <a href="https://github.com/">github.com</a> (<a href="https://docs.github.com/en/github/writing-on-github/creating-gists">gists</a>) or
<a href="https://gitlab.com/">gitlab.com</a> (<a href="https://docs.gitlab.com/ce/user/snippets.html">snippets</a>).</p>

<p>All my code examples (my programming knowledge base) are now shared using this tool,
you can take a look to <a href="https://gist.github.com/c071a7b7d3de633281cbe84a34be47f1">my public gists overview on github</a> to illustrate the 
publishing work achieved by CEM.</p>

<p>Current <a href="https://github.com/dacr/code-examples-manager/">Code example manager (CEM)</a> implementation is just a command line tool
which compare locally available examples with already published ones in order to find
what it should do (add, update, do nothing). At that time it doesn’t cache any state,
it scans systematically the remote destinations for published examples, this behavior
will change in a near future to accelerate the publishing operations.</p>

<p>It is now a mature tool thanks to the last refactoring. It now supports github.com,
gitlab.com, and can work with any company private github or gitlab instances.</p>

<p>The <a href="https://github.com/dacr/code-examples-manager/releases/latest">latest</a> release brings a classic packaging (archive) which allow you to
use CEM on any Operating System as soon as a Java Jvm release &gt;=8 is available. Just
read the instructions on <a href="https://github.com/dacr/code-examples-manager/">CEM project home page</a>.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Code example manager (CEM) is a software tool which manage your code examples and provide publish mechanisms to github.com (gists) or gitlab.com (snippets).]]></summary></entry><entry><title type="html">Lorem Ipsum Web service based on Akka-HTTP</title><link href="https://crosson.org/blog/blog/2020/04/05/lorem-ipsum-server-akkahttp.html" rel="alternate" type="text/html" title="Lorem Ipsum Web service based on Akka-HTTP" /><published>2020-04-05T01:42:42+02:00</published><updated>2020-04-05T01:42:42+02:00</updated><id>https://crosson.org/blog/blog/2020/04/05/lorem-ipsum-server-akkahttp</id><content type="html" xml:base="https://crosson.org/blog/blog/2020/04/05/lorem-ipsum-server-akkahttp.html"><![CDATA[<p><strong>The <a href="https://github.com/dacr/lorem-ipsum-server-akkahttp">lorem-ipsum-server-akkahttp</a> github opensource project</strong> :</p>
<ul>
  <li>An <a href="https://github.com/akka/akka-http">akka-http</a> based web service
    <ul>
      <li>which generates random <a href="https://en.wikipedia.org/wiki/Lorem_ipsum">Lorem Ipsum</a> paragraphs.</li>
    </ul>
  </li>
  <li>Based on this <a href="https://github.com/dacr/lorem-ipsum">lorem-ipsum library</a> which also support customizable corpus.</li>
  <li>Deployed on <a href="https://mapland.fr/lorem">my own infrastructure</a> (<a href="https://mapland.fr/lorem">https://mapland.fr/lorem</a>)</li>
</ul>

<p><strong>This project is using those great libraries</strong> :</p>
<ul>
  <li><a href="https://github.com/akka/akka-http">akka http</a> : Actor based http framework.</li>
  <li><a href="https://github.com/pureconfig/pureconfig">pure config</a> : Great library for easy and powerful configuration.</li>
  <li><a href="http://scalate.github.io/scalate/">scalate</a> : Multi-language page templating (mustache selected).</li>
  <li><a href="https://www.webjars.org/">webjars</a> : Managing client-side libraries as maven dependencies !</li>
  <li><a href="http://www.scalatest.org/">scalatest</a> : Great unit testing framework with a powerful DSL.</li>
  <li><a href="http://json4s.org/">json4s</a> : Powerful and multi-purpose JSON processing.</li>
</ul>

<p><strong>So why this project</strong> :</p>
<ul>
  <li>For learning purposes,</li>
  <li>Have a modern example web application,</li>
  <li>Find new approaches for software configuration,</li>
  <li>Collect real world data (elasticsearch and kafka is used behind the scene),</li>
  <li>Experiment various CI solutions, …</li>
</ul>

<p><img src="/blog/assets/lorem-ipsum-screenshot.png" alt="" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[The lorem-ipsum-server-akkahttp github opensource project : An akka-http based web service which generates random Lorem Ipsum paragraphs. Based on this lorem-ipsum library which also support customizable corpus. Deployed on my own infrastructure (https://mapland.fr/lorem)]]></summary></entry><entry><title type="html">Lorem Ipsum generator</title><link href="https://crosson.org/blog/blog/2020/03/25/lorem-ipsum.html" rel="alternate" type="text/html" title="Lorem Ipsum generator" /><published>2020-03-25T00:42:42+01:00</published><updated>2020-03-25T00:42:42+01:00</updated><id>https://crosson.org/blog/blog/2020/03/25/lorem-ipsum</id><content type="html" xml:base="https://crosson.org/blog/blog/2020/03/25/lorem-ipsum.html"><![CDATA[<h2 id="lorem-ipsum-and-you-">Lorem ipsum and you ?</h2>

<p>Want to known more about <a href="https://en.wikipedia.org/wiki/Lorem_ipsum">Lorem Ipsum</a> or <a href="https://github.com/dacr/lorem-ipsum">generate some using scala language</a>. You can also do it yourself using this <a href="http://ammonite.io/">Ammonite</a> script :</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nn">$ivy.</span><span class="n">`fr.janalyse::lorem-ipsum:0.0.2`</span>
<span class="k">import</span> <span class="nn">loremipsum._</span>
<span class="k">val</span> <span class="nv">story</span> <span class="k">=</span> <span class="nv">LoremIpsum</span><span class="o">.</span><span class="py">generate</span><span class="o">(</span><span class="mi">42</span><span class="o">*</span><span class="mi">6</span><span class="o">,</span><span class="kc">true</span><span class="o">).</span><span class="py">map</span><span class="o">(</span><span class="nv">_</span><span class="o">.</span><span class="py">text</span><span class="o">).</span><span class="py">mkString</span><span class="o">(</span><span class="s">"\n\n"</span><span class="o">)</span>
<span class="nf">println</span><span class="o">(</span><span class="n">story</span><span class="o">)</span>
</code></pre></div></div>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur.</p>

<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Lorem ipsum and you ?]]></summary></entry><entry><title type="html">Old compmoc blog is back !</title><link href="https://crosson.org/blog/blog/2020/03/22/compmoc-blog-is-back.html" rel="alternate" type="text/html" title="Old compmoc blog is back !" /><published>2020-03-22T18:20:44+01:00</published><updated>2020-03-22T18:20:44+01:00</updated><id>https://crosson.org/blog/blog/2020/03/22/compmoc-blog-is-back</id><content type="html" xml:base="https://crosson.org/blog/blog/2020/03/22/compmoc-blog-is-back.html"><![CDATA[<p>My very old blog is back, previously <a href="https://www.blogger.com/">blogger</a> based, and now powered
by <a href="https://doc.akka.io/docs/akka-http/current/index.html">AKKA HTTP</a> and <a href="https://jekyllrb.com/">Jekyll</a>.</p>

<p>All new articles are now directly written in <a href="https://en.wikipedia.org/wiki/Markdown">markdown</a>, previous ones were
imported using <a href="https://jekyllrb.com/">jekyll</a> migration support.</p>

<p>Those past years I didn’t write much articles, but instead I was quite busy by
various stuff as It can be seen through my <a href="https://github.com/dacr">github projects</a> and 
my <a href="https://gist.github.com/dacr">github gists code examples</a>.</p>

<p>With 2020, let’s publish some new content about programming, coding challenges,
software/framework experiments, …</p>]]></content><author><name></name></author><summary type="html"><![CDATA[My very old blog is back, previously blogger based, and now powered by AKKA HTTP and Jekyll.]]></summary></entry><entry><title type="html">Solutions to a small kids puzzle</title><link href="https://crosson.org/blog/blog/2015/05/26/solutions-to-small-kids-puzzle.html" rel="alternate" type="text/html" title="Solutions to a small kids puzzle" /><published>2015-05-26T00:41:00+02:00</published><updated>2015-05-26T00:41:00+02:00</updated><id>https://crosson.org/blog/blog/2015/05/26/solutions-to-small-kids-puzzle</id><content type="html" xml:base="https://crosson.org/blog/blog/2015/05/26/solutions-to-small-kids-puzzle.html"><![CDATA[How to solve the following <a
        href="http://www.theguardian.com/science/alexs-adventures-in-numberland/2015/may/20/can-you-do-the-maths-puzzle-for-vietnamese-eight-year-olds-that-has-stumped-parents-and-teachers">kid
    puzzle</a> by using only digits from 1 to 9 exactly one time :  <br/> <a
        href="http://i.guim.co.uk/static/w-700/h--/q-95/sys-images/Guardian/Pix/pictures/2015/5/20/1432109324993/f7e7f4a5-b59c-4580-88f4-ddc609584d19-bestSizeAvailable.png"
        imageanchor="1"><img border="0"
                             src="http://i.guim.co.uk/static/w-700/h--/q-95/sys-images/Guardian/Pix/pictures/2015/5/20/1432109324993/f7e7f4a5-b59c-4580-88f4-ddc609584d19-bestSizeAvailable.png"/></a>
<br/> With the following code, I found 20 solutions if we take into account operators priority, 119 without.
<script src="https://gist.github.com/dacr/627953b917f6c95cfebf.js"></script> <br/> The solutions are :
<pre><br/>List(3, 2, 1, 5, 4, 7, 8, 9, 6)<br/>List(3, 2, 1, 5, 4, 7, 9, 8, 6)<br/>List(5, 2, 1, 3, 4, 7, 8, 9, 6)<br/>List(5, 2, 1, 3, 4, 7, 9, 8, 6)<br/>List(5, 3, 1, 7, 2, 6, 8, 9, 4)<br/>List(5, 3, 1, 7, 2, 6, 9, 8, 4)<br/>List(5, 4, 1, 9, 2, 7, 3, 8, 6)<br/>List(5, 4, 1, 9, 2, 7, 8, 3, 6)<br/>List(5, 9, 3, 6, 2, 1, 7, 8, 4)<br/>List(5, 9, 3, 6, 2, 1, 8, 7, 4)<br/>List(6, 3, 1, 9, 2, 5, 7, 8, 4)<br/>List(6, 3, 1, 9, 2, 5, 8, 7, 4)<br/>List(6, 9, 3, 5, 2, 1, 7, 8, 4)<br/>List(6, 9, 3, 5, 2, 1, 8, 7, 4)<br/>List(7, 3, 1, 5, 2, 6, 8, 9, 4)<br/>List(7, 3, 1, 5, 2, 6, 9, 8, 4)<br/>List(9, 3, 1, 6, 2, 5, 7, 8, 4)<br/>List(9, 3, 1, 6, 2, 5, 8, 7, 4)<br/>List(9, 4, 1, 5, 2, 7, 3, 8, 6)<br/>List(9, 4, 1, 5, 2, 7, 8, 3, 6)<br/></pre>]]></content><author><name>david crosson</name></author><summary type="html"><![CDATA[How to solve the following kid puzzle by using only digits from 1 to 9 exactly one time : With the following code, I found 20 solutions if we take into account operators priority, 119 without. The solutions are : List(3, 2, 1, 5, 4, 7, 8, 9, 6)List(3, 2, 1, 5, 4, 7, 9, 8, 6)List(5, 2, 1, 3, 4, 7, 8, 9, 6)List(5, 2, 1, 3, 4, 7, 9, 8, 6)List(5, 3, 1, 7, 2, 6, 8, 9, 4)List(5, 3, 1, 7, 2, 6, 9, 8, 4)List(5, 4, 1, 9, 2, 7, 3, 8, 6)List(5, 4, 1, 9, 2, 7, 8, 3, 6)List(5, 9, 3, 6, 2, 1, 7, 8, 4)List(5, 9, 3, 6, 2, 1, 8, 7, 4)List(6, 3, 1, 9, 2, 5, 7, 8, 4)List(6, 3, 1, 9, 2, 5, 8, 7, 4)List(6, 9, 3, 5, 2, 1, 7, 8, 4)List(6, 9, 3, 5, 2, 1, 8, 7, 4)List(7, 3, 1, 5, 2, 6, 8, 9, 4)List(7, 3, 1, 5, 2, 6, 9, 8, 4)List(9, 3, 1, 6, 2, 5, 7, 8, 4)List(9, 3, 1, 6, 2, 5, 8, 7, 4)List(9, 4, 1, 5, 2, 7, 3, 8, 6)List(9, 4, 1, 5, 2, 7, 8, 3, 6)]]></summary></entry></feed>