<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0">
 <channel>
  <title>XGQT's blog: Posts tagged 'dev'</title>
  <description>XGQT's blog: Posts tagged 'dev'</description>
  <link>https://xgqt.gitlab.io/blog/tags/dev.html</link>
  <lastBuildDate>Fri, 03 Jul 2026 14:30:00 UT</lastBuildDate>
  <pubDate>Fri, 03 Jul 2026 14:30:00 UT</pubDate>
  <ttl>1800</ttl>
  <item>
   <title>My current gitmessage template</title>
   <link>https://xgqt.gitlab.io/blog/posts/2026/07/03/my-current-gitmessage-template/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2026-07-03-my-current-gitmessage-template</guid>
   <pubDate>Fri, 03 Jul 2026 14:30:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;It is possible to configure git to use a extra helpful git message when inside the &lt;code&gt;git commit&lt;/code&gt; editor.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# When committing follow those rules:&lt;/span&gt;
&lt;span class="c1"&gt;#   1. Use the Conventional Commits style when committing!&lt;/span&gt;
&lt;span class="c1"&gt;#      Follow this template:&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt; &amp;lt;type&amp;gt;[optional scope]: &amp;lt;description&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt; [optional body]&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt; [optional footer(s)]&lt;/span&gt;
&lt;span class="c1"&gt;#      Allowed commit types are:&lt;/span&gt;
&lt;span class="c1"&gt;#        fix, feat, build,&lt;/span&gt;
&lt;span class="c1"&gt;#        chore, ci, docs,&lt;/span&gt;
&lt;span class="c1"&gt;#        style, refactor, perf,&lt;/span&gt;
&lt;span class="c1"&gt;#        test.&lt;/span&gt;
&lt;span class="c1"&gt;#      See also: https://www.conventionalcommits.org/en/v1.0.0/&lt;/span&gt;
&lt;span class="c1"&gt;#   2. Remember to add a "Signed-off-by"!&lt;/span&gt;
&lt;span class="c1"&gt;#      For example:&lt;/span&gt;
&lt;span class="c1"&gt;#        &amp;gt; Signed-off-by: John Smith &amp;lt;js@js.org&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Save that as &lt;code&gt;.gitmessage&lt;/code&gt; on repo root.&lt;/p&gt;

&lt;p&gt;Then wire it to local git config with:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--local&lt;span class="w"&gt; &lt;/span&gt;commit.template&lt;span class="w"&gt; &lt;/span&gt;.gitmessage
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://dev.to/vetswhocode/git-gud-create-a-gitmessage-4ibj"&gt;https://dev.to/vetswhocode/git-gud-create-a-gitmessage-4ibj&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://codeberg.org/xgqt/blog/src/branch/dev/.gitmessage"&gt;https://codeberg.org/xgqt/blog/src/branch/dev/.gitmessage&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description></item>
  <item>
   <title>Scribble hacks: insert module code</title>
   <link>https://xgqt.gitlab.io/blog/posts/2026/06/29/scribble-hacks-insert-module-code/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2026-06-29-scribble-hacks-insert-module-code</guid>
   <pubDate>Sun, 28 Jun 2026 22:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;ul&gt;
 &lt;li&gt;&lt;a href="#__scribble_hacks__insert_module_code_get-module-content_for_"&gt;get-module-content for showing module implementation&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#__scribble_hacks__insert_module_code_get-module-content_usage_"&gt;get-module-content usage inside Scribble&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#__scribble_hacks__insert_module_code_see_also_"&gt;See also&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;&lt;a id="__scribble_hacks__insert_module_code_get-module-content_for_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id="get-module-content-for-showing-module-implementation"&gt;get-module-content for showing module implementation&lt;/h1&gt;

&lt;p&gt;Normally Scribble, the Racket&amp;rsquo;s documentation tool, does not provide a way to see how a function/object/module is actually defined in the code. Just recently I wound a good-enough way to insert the whole content of the module we are documenting with Scribble.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s my implementation:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get-module-content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;module-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;~&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;module-name&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" style="color: inherit"&gt;string-&amp;gt;symbol&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Module_Names_and_Loading.html#(def._((quote._~23~25kernel)._module-path-index-join))" style="color: inherit"&gt;module-path-index-join&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Module_Names_and_Loading.html#(def._((quote._~23~25kernel)._module-path-index-resolve))" style="color: inherit"&gt;module-path-index-resolve&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Module_Names_and_Loading.html#(def._((quote._~23~25kernel)._resolved-module-path-name))" style="color: inherit"&gt;resolved-module-path-name&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Filesystem.html#(def._((lib._racket/file..rkt)._file-~3elines))" style="color: inherit"&gt;file-&amp;gt;lines&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/private/list..rkt)._filter))" style="color: inherit"&gt;filter&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket/private/base..rkt)._lambda))" style="color: inherit"&gt;lambda&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._not))" style="color: inherit"&gt;not&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/regexp.html#(def._((lib._racket/private/base..rkt)._regexp-match-exact~3f))" style="color: inherit"&gt;regexp-match-exact?&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;#rx"^;.*"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt).__))" style="color: inherit"&gt;_&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/strings.html#(def._((lib._racket/string..rkt)._string-join))" style="color: inherit"&gt;string-join&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/strings.html#(def._((lib._racket/string..rkt)._string-trim))" style="color: inherit"&gt;string-trim&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;The input is a module name in the form that you would use in absolute require form, except that it is a string, not a bare syntax.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get-module-content&lt;/code&gt; will reach out to Your Racket package database and find a module that you gave. It will read it and remove all comments. It returns a Racket string.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;string?&lt;/code&gt; returned by &lt;code&gt;get-module-content&lt;/code&gt; can later be used to either extract some more info but it can be effectively used to insert the full module implementation block.&lt;/p&gt;

&lt;p&gt;&lt;a id="__scribble_hacks__insert_module_code_get-module-content_usage_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id="get-module-content-usage-inside-scribble"&gt;get-module-content usage inside Scribble&lt;/h1&gt;

&lt;p&gt;In Scribble I insert the module source code like so:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._this))" style="color: inherit"&gt;this&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;module:&lt;/span&gt;

&lt;span class="n"&gt;@codeblock&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;@get-module-content&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mypkg/utils/path&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a id="__scribble_hacks__insert_module_code_see_also_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id="see-also"&gt;See also&lt;/h1&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://codeberg.org/xgqt/xgqt-racket-app-enigma-emacs/src/commit/9d47fa366b215ef943f3770d92db634cbbcaa982/code/source/v1/enigma-app/doc/enigma-doc/enigma/scribblings/utils/content.rkt"&gt;scribblings/utils/content.rkt&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://codeberg.org/xgqt/xgqt-racket-app-enigma-emacs/src/commit/9d47fa366b215ef943f3770d92db634cbbcaa982/code/source/v1/enigma-app/doc/enigma-doc/enigma/system/utils/path.scrbl#L50"&gt;utils/path.scrbl#L50&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description></item>
  <item>
   <title>Common Project Layout, Version 1... A Rough Draft #1</title>
   <link>https://xgqt.gitlab.io/blog/posts/2026/04/15/common-project-layout-version-1-a-rough-draft-1/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2026-04-15-common-project-layout-version-1-a-rough-draft-1</guid>
   <pubDate>Wed, 15 Apr 2026 18:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;For CPL version 0 see &lt;a href="https://xgqt.gitlab.io/blog/posts/2023/10/17/common-project-layout-version-0/"&gt;common-project-layout-version&amp;ndash;0&lt;/a&gt;. A template project for CPL v1 can be found at &lt;a href="https://gitlab.com/xgqt/xgqt-misc-template-cplv1/"&gt;gitlab.com/xgqt/xgqt-misc-template-cplv1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To solve the repository layout problem we propose this hierarchy:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;separate the code from text/prose by clear distinction on top-level &amp;mdash; thus the &lt;code&gt;code&lt;/code&gt; dir&lt;/li&gt;
 &lt;li&gt;for &lt;code&gt;code&lt;/code&gt; we create this structure:
  &lt;ul&gt;
   &lt;li&gt;&lt;code&gt;authoring&lt;/code&gt; &amp;mdash; authoring scripts for developers&lt;/li&gt;
   &lt;li&gt;&lt;code&gt;copyright&lt;/code&gt; &amp;mdash; copyright documents &lt;em&gt;for the code&lt;/em&gt;&lt;/li&gt;
   &lt;li&gt;&lt;code&gt;integration&lt;/code&gt; &amp;mdash; integration scripts, ie CI/CD scripts or Groovy sources for Jenkins&lt;/li&gt;
   &lt;li&gt;&lt;code&gt;source&lt;/code&gt; &amp;mdash; versioned application/library sources, each &lt;strong&gt;major&lt;/strong&gt; version is assigned a &lt;code&gt;v&amp;lt;MAJOR&amp;gt;&lt;/code&gt; directory; this allows us to keep and maintain multiple versions, it is very reminiscent to having multiple package versions in a Ports (FreeBSD/Gentoo) repository
    &lt;ul&gt;
     &lt;li&gt;for the &lt;code&gt;v&amp;lt;MAJOR&amp;gt;&lt;/code&gt; dirs we separate each bag of sources or scripts into its own directory, for example:
      &lt;ul&gt;
       &lt;li&gt;&lt;code&gt;3rd-party&lt;/code&gt;&lt;/li&gt;
       &lt;li&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/li&gt;
       &lt;li&gt;&lt;code&gt;build-support&lt;/code&gt;&lt;/li&gt;
       &lt;li&gt;&lt;code&gt;run&lt;/code&gt;&lt;/li&gt;
       &lt;li&gt;&lt;code&gt;&amp;lt;APPNAME&amp;gt;-app&lt;/code&gt;&lt;/li&gt;
       &lt;li&gt;&lt;code&gt;&amp;lt;APPNAME&amp;gt;-lib&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</description></item>
  <item>
   <title>Tutorial: PowerShell Modules in FSharp</title>
   <link>https://xgqt.gitlab.io/blog/posts/2025/05/12/tutorial-powershell-modules-in-fsharp/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2025-05-12-tutorial-powershell-modules-in-fsharp</guid>
   <pubDate>Mon, 12 May 2025 16:47:03 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/fsharp/what-is-fsharp/"&gt;F#&lt;/a&gt; is a amazing functional language bridging C#/.NET ecosystem with &lt;a href="https://ocaml.org/"&gt;OCaml&lt;/a&gt; and interactive programming. It has recently became by favorite language to create personal projects in. It both has additional security of strong typing, unlike Python or Ruby while keeping the functional and interactive properties of weak-typed languages. F# is truly a engineering marvel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/pl-pl/powershell/"&gt;PowerShell 7&lt;/a&gt; is the Open-Source implementation of the old Windows PowerShell that is also cross-platform and can be used for scripting and automation. It&amp;rsquo;s Object-orientation makes an amazing extension capability compared to Bash.&lt;/p&gt;

&lt;p&gt;You can use the F# language to create PowerShell modules. Normally PS Modules are written in C# but since the interop between .NET languages is insanely fluent one can just swap C# for F#.&lt;/p&gt;

&lt;h2 id="creating-new-project"&gt;Creating new project&lt;/h2&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/source/temporary/powershell-modules/fs-example
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/source/temporary/powershell-modules/fs-example
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h3 id="dotnet-classlib"&gt;Dotnet ClassLib&lt;/h3&gt;

&lt;p&gt;Init new F# Class project:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;dotnet&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;classlib&lt;span class="w"&gt; &lt;/span&gt;--language&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"F#"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h3 id="dependencies"&gt;Dependencies&lt;/h3&gt;

&lt;p&gt;Add dependency on Powershell interaction library:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;dotnet&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;package&lt;span class="w"&gt; &lt;/span&gt;PowerShellStandard.Library&lt;span class="w"&gt; &lt;/span&gt;--version&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;.1.1
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="f-interaction-with-powershell"&gt;F# interaction with PowerShell&lt;/h2&gt;

&lt;p&gt;Let&amp;rsquo;s rewrite Library.fs to contain:&lt;/p&gt;

&lt;div class="brush: fsharp"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;FsExample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PowerShell&lt;/span&gt;

&lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;System.Management.Automation&lt;/span&gt;

&lt;span class="o"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Cmdlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;VerbsCommon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"FsExample"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;FsExample&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;inherit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PSCmdlet&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ValidateNotNullOrEmpty&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Me"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BeginProcessing&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printfn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Hello %s"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Then, change &lt;code&gt;RootNamespace&lt;/code&gt; to the main module name, that is &lt;code&gt;FsExample.PowerShell&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We need to copy all assemblies to output. Add &lt;code&gt;&amp;lt;CopyLocalLockFileAssemblies&amp;gt;true&amp;lt;/CopyLocalLockFileAssemblies&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;div class="brush: xml"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net9.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;RootNamespace&amp;gt;&lt;/span&gt;FsExample.PowerShell&lt;span class="nt"&gt;&amp;lt;/RootNamespace&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;GenerateDocumentationFile&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/GenerateDocumentationFile&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;CopyLocalLockFileAssemblies&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/CopyLocalLockFileAssemblies&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Snip ... --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="powershell-library"&gt;PowerShell library&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;PSModuleAssets&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;PSModuleAssets
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;PSModuleAssets
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;The main module file will in turn load the DLL compiled form above F# code.&lt;/p&gt;

&lt;p&gt;Create main module file - &lt;code&gt;fs-example.psm1&lt;/code&gt;:&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c"&gt;#!/usr/bin/env -S pwsh -NoLogo -NoProfile -NonInteractive&lt;/span&gt;

&lt;span class="nb"&gt;Import-Module&lt;/span&gt; &lt;span class="s2"&gt;"$PSScriptRoot/fs-example.dll"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;We then need to create the main manifest file &lt;code&gt;fs-example.psd1&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;Path&lt;/code&gt; - relative path to output the manifest,&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;RootModule&lt;/code&gt; - relative module path to load on module import,&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;ModuleVersion&lt;/code&gt;, &lt;code&gt;Description&lt;/code&gt;, &lt;code&gt;Author&lt;/code&gt; and &lt;code&gt;Copyright&lt;/code&gt;  are some of standard metadata fields,&lt;/li&gt;
 &lt;li&gt;&lt;code&gt;AliasesToExport&lt;/code&gt;, &lt;code&gt;CmdletsToExport&lt;/code&gt;, &lt;code&gt;DscResourcesToExport&lt;/code&gt;,  &lt;code&gt;FunctionsToExport&lt;/code&gt; and &lt;code&gt;VariablesToExport&lt;/code&gt; are either globs or lists that  tell what functions will be available on module load,  for simplicity we will just specify a glob expression &lt;code&gt;'*'&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;New-ModuleManifest&lt;/span&gt; &lt;span class="n"&gt;-Path&lt;/span&gt; &lt;span class="p"&gt;./&lt;/span&gt;&lt;span class="n"&gt;fs-example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psd1&lt;/span&gt; &lt;span class="n"&gt;-RootModule&lt;/span&gt; &lt;span class="p"&gt;./&lt;/span&gt;&lt;span class="n"&gt;fs-example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;psm1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;-ModuleVersion&lt;/span&gt; &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;-Description&lt;/span&gt; &lt;span class="s2"&gt;"FSharp example module"&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;-Author&lt;/span&gt; &lt;span class="s2"&gt;"Me"&lt;/span&gt; &lt;span class="n"&gt;-Copyright&lt;/span&gt; &lt;span class="s2"&gt;"Copyright (c) 2025, Me"&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;-AliasesToExport&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-CmdletsToExport&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;-DscResourcesToExport&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-FunctionsToExport&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-VariablesToExport&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="copying-powershell-assets"&gt;Copying PowerShell assets&lt;/h2&gt;

&lt;p&gt;Following &lt;code&gt;ItemGroup&lt;/code&gt; will copy all files from &lt;code&gt;PSModuleAssets&lt;/code&gt; to the output directory:&lt;/p&gt;

&lt;div class="brush: xml"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Snip ... --&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;None&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"PSModuleAssets/*.*"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;Link&amp;gt;&lt;/span&gt;%(Filename)%(Extension)&lt;span class="nt"&gt;&amp;lt;/Link&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;CopyToOutputDirectory&amp;gt;&lt;/span&gt;Always&lt;span class="nt"&gt;&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/None&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Snip ... --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="building-the-f-module"&gt;Building the F# module&lt;/h2&gt;

&lt;p&gt;Clean up the old builds:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-fr&lt;span class="w"&gt; &lt;/span&gt;./psrepository
rm&lt;span class="w"&gt; &lt;/span&gt;-fr&lt;span class="w"&gt; &lt;/span&gt;./out-module/fs-example
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h3 id="dotnet-build"&gt;Dotnet-Build&lt;/h3&gt;

&lt;p&gt;And then build the module:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;dotnet&lt;span class="w"&gt; &lt;/span&gt;restore
dotnet&lt;span class="w"&gt; &lt;/span&gt;build&lt;span class="w"&gt; &lt;/span&gt;--configuration&lt;span class="w"&gt; &lt;/span&gt;Release&lt;span class="w"&gt; &lt;/span&gt;--output&lt;span class="w"&gt; &lt;/span&gt;./out-module/fs-example
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="language-locality-bug"&gt;Language locality bug&lt;/h2&gt;

&lt;p&gt;You have to use the &lt;code&gt;en-US&lt;/code&gt; locale when publishing PowerShell modules.&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$env:LANG&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"en_US.UTF-8"&lt;/span&gt;
&lt;span class="nv"&gt;$env:LANGUAGE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"en_US.UTF-8"&lt;/span&gt;
&lt;span class="nv"&gt;$env:LC_MESSAGES&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"en_US.utf8"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;

&lt;p&gt;Remove old registered PowerShell repository:&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;Unregister-PSRepository&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;fs-example&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h3 id="register-psrepository-and-publish-module"&gt;Register-PSRepository and Publish-Module&lt;/h3&gt;

&lt;p&gt;This quite complicated script will:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;set up a PowerShell repository in current location,&lt;/li&gt;
 &lt;li&gt;register the PowerShell repository,&lt;/li&gt;
 &lt;li&gt;publish the module into the PowerShell repository,&lt;/li&gt;
 &lt;li&gt;install that published module from the PowerShell repository.&lt;/li&gt;&lt;/ul&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$repo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"fs-example"&lt;/span&gt;
&lt;span class="nv"&gt;$repoPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"$pwd/psrepository/fs-example"&lt;/span&gt;

&lt;span class="nb"&gt;New-Item&lt;/span&gt; &lt;span class="n"&gt;-ItemType&lt;/span&gt; &lt;span class="n"&gt;Directory&lt;/span&gt; &lt;span class="n"&gt;-Path&lt;/span&gt; &lt;span class="nv"&gt;$repoPath&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Out-Null&lt;/span&gt;
&lt;span class="nb"&gt;Register-PSRepository&lt;/span&gt; &lt;span class="n"&gt;-InstallationPolicy&lt;/span&gt; &lt;span class="n"&gt;Trusted&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="nv"&gt;$repo&lt;/span&gt; &lt;span class="n"&gt;-SourceLocation&lt;/span&gt; &lt;span class="nv"&gt;$repoPath&lt;/span&gt;

&lt;span class="nb"&gt;Publish-Module&lt;/span&gt; &lt;span class="n"&gt;-Verbose&lt;/span&gt; &lt;span class="n"&gt;-Path&lt;/span&gt; &lt;span class="nv"&gt;$pwd&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;out-module&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fs-example&lt;/span&gt; &lt;span class="n"&gt;-Repository&lt;/span&gt; &lt;span class="nv"&gt;$repo&lt;/span&gt;
&lt;span class="nb"&gt;Install-Module&lt;/span&gt; &lt;span class="n"&gt;-Scope&lt;/span&gt; &lt;span class="n"&gt;CurrentUser&lt;/span&gt; &lt;span class="n"&gt;-Force&lt;/span&gt; &lt;span class="n"&gt;-Verbose&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;fs-example&lt;/span&gt; &lt;span class="n"&gt;-Repository&lt;/span&gt; &lt;span class="nv"&gt;$repo&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="removal"&gt;Removal&lt;/h2&gt;

&lt;h3 id="uninstall-module"&gt;Uninstall-Module&lt;/h3&gt;

&lt;p&gt;Just call &lt;code&gt;Uninstall-Module&lt;/code&gt; to remove any PowerShell module.&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Uninstall-Module&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;fs-example&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="usage-in-the-repl"&gt;Usage in the REPL&lt;/h2&gt;

&lt;h3 id="import-module"&gt;Import-Module&lt;/h3&gt;

&lt;p&gt;Import it with &lt;code&gt;Import-Module&lt;/code&gt;.&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Import-Module&lt;/span&gt; &lt;span class="n"&gt;-Verbose&lt;/span&gt; &lt;span class="n"&gt;fs-example&lt;/span&gt; &lt;span class="n"&gt;-Force&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h3 id="finally---use-format-fsexample"&gt;Finally - use Format-FsExample&lt;/h3&gt;

&lt;p&gt;Remember the above F# function that was defined in the class?&lt;/p&gt;

&lt;div class="brush: fsharp"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Cmdlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;VerbsCommon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"FsExample"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;FsExample&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;It will be now available under the name composed of the &amp;ldquo;common verb&amp;rdquo; and a secondary part, so &lt;code&gt;Format-FsExample&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try it:&lt;/p&gt;

&lt;div class="brush: powershell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Format-FsExample&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;Maciej&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>GHC 9.8 and Cabal 3.10.3 on Gentoo Linux</title>
   <link>https://xgqt.gitlab.io/blog/posts/2024/11/07/ghc-9-8-and-cabal-3-10-3-on-gentoo-linux/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2024-11-07-ghc-9-8-and-cabal-3-10-3-on-gentoo-linux</guid>
   <pubDate>Thu, 07 Nov 2024 15:02:31 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;The official &lt;code&gt;::gentoo&lt;/code&gt; repository currently contains only GHC on version 9.2.8. To install newer GHC one has to either download/build themselves or use the &lt;code&gt;::haskell&lt;/code&gt; overlay (&lt;a href="https://github.com/gentoo-haskell/gentoo-haskell"&gt;https://github.com/gentoo-haskell/gentoo-haskell&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id="enable-the-haskell-overlay"&gt;Enable the ::haskell overlay&lt;/h2&gt;

&lt;p&gt;Enable:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;eselect&lt;span class="w"&gt; &lt;/span&gt;repository&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;haskell
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Sync:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;emerge&lt;span class="w"&gt; &lt;/span&gt;--sync&lt;span class="w"&gt; &lt;/span&gt;haskell
egencache&lt;span class="w"&gt; &lt;/span&gt;--update&lt;span class="w"&gt; &lt;/span&gt;--repo&lt;span class="w"&gt; &lt;/span&gt;haskell&lt;span class="w"&gt; &lt;/span&gt;--jobs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--load&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;
eix-update
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="unmask-needed-packages"&gt;Unmask needed packages&lt;/h2&gt;

&lt;p&gt;Add to &lt;code&gt;/etc/portage/package.unmask/0000_hs.conf&lt;/code&gt;&lt;/p&gt;

&lt;div class="brush: conf"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;dev-lang/ghc-9.9

&amp;lt;dev-haskell/cabal-3.11
&amp;lt;dev-haskell/cabal-install-3.11
&amp;lt;dev-haskell/cabal-install-solver-3.11
&amp;lt;dev-haskell/cabal-syntax-3.11
&amp;lt;dev-haskell/text-2.2
&amp;lt;dev-haskell/parsec-3.1.18
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Add to &lt;code&gt;/etc/portage/package.accept_keywords/0000_hs.conf&lt;/code&gt;&lt;/p&gt;

&lt;div class="brush: conf"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;app-admin/haskell-updater
dev-haskell/*
dev-lang/ghc
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="install"&gt;Install&lt;/h2&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;emerge&lt;span class="w"&gt; &lt;/span&gt;--ask&lt;span class="w"&gt; &lt;/span&gt;--verbose&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=dev-lang/ghc-9.8"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=dev-haskell/cabal-install-3.10"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Build of GHC 9.8 takes around ~2 hours on a 8-core laptop-grade CPU.&lt;/p&gt;

&lt;h2 id="bonus-masking-packages-from-haskell"&gt;Bonus: masking packages from ::haskell&lt;/h2&gt;

&lt;p&gt;If you want to exclude a given version from the &lt;code&gt;::haskell&lt;/code&gt; overly from being installed/updated, then you can add a similar line(s) to &lt;code&gt;/etc/portage/package.mask/0000_hs.conf&lt;/code&gt;:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;app-emacs/haskell-mode::haskell
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>Tag the releases</title>
   <link>https://xgqt.gitlab.io/blog/posts/2024/10/03/tag-the-releases/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2024-10-03-tag-the-releases</guid>
   <pubDate>Thu, 03 Oct 2024 15:43:33 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;Tag your releases!&lt;/p&gt;

&lt;p&gt;There were so many times when I wanted to use some package, it has a version on repology, but when I open the project&amp;rsquo;s repo there are no tags.&lt;/p&gt;

&lt;p&gt;Nowadays it is extremely easy to bump software versions according to semantic versioning and also to tag them, that it should go without saying that most OSS and proprietary projects could also follow that workflow.&lt;/p&gt;

&lt;p&gt;There are many projects both language-specific and agnostic to manage the release (and tagging) process. My favorite agnostic one is &lt;a href="https://github.com/your-tools/tbump/"&gt;tbump&lt;/a&gt; and I highly recommend it.&lt;/p&gt;</description></item>
  <item>
   <title>Install Bazel ZSH completion</title>
   <link>https://xgqt.gitlab.io/blog/posts/2024/08/02/install-bazel-zsh-completion/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2024-08-02-install-bazel-zsh-completion</guid>
   <pubDate>Fri, 02 Aug 2024 18:20:08 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"bazelbuild/bazel"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://raw.githubusercontent.com/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;url&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="nv"&gt;raw&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/master/scripts/zsh_completion/_bazel"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;site_functions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/share/zsh/site-functions"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-O&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;site_functions&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/_bazel
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Afterwards, restart your ZSH shell session.&lt;/p&gt;

&lt;p&gt;This also works if you have &lt;code&gt;bazelisk&lt;/code&gt; installed but &lt;code&gt;bazel&lt;/code&gt; has to be symlinked to the &lt;code&gt;bazelisk&lt;/code&gt; executable path.&lt;/p&gt;</description></item>
  <item>
   <title>Change location of intermediate objects in .NET</title>
   <link>https://xgqt.gitlab.io/blog/posts/2024/03/06/change-location-of-intermediate-objects-in-net/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2024-03-06-change-location-of-intermediate-objects-in-net</guid>
   <pubDate>Wed, 06 Mar 2024 22:32:17 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;.NET creates the so-called intermediate objects while building .NET projects, those are located in the &amp;ldquo;bin&amp;rdquo; and &amp;ldquo;obj&amp;rdquo; directories. The default is not very satisfying, primarily because if a program from a different machine or a container modifies those, then any cached file system paths that are encoded in the objects will be broken. But also it is probably mostly a legacy behavior to have them split between &amp;ldquo;bin&amp;rdquo; and &amp;ldquo;obj&amp;rdquo; directories.&lt;/p&gt;

&lt;p&gt;I prefer for them to say in one - ".cache", because that&amp;rsquo;s that they are - cache. With the following configuration objects will be stored inside the ".cache" directory. Furthermore, the objects produced by the native machine in the &amp;ldquo;native&amp;rdquo; subdirectory and the ones produced by container software in &amp;ldquo;container&amp;rdquo; subdirectory.&lt;/p&gt;

&lt;div class="brush: xml"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;CachePath&amp;gt;&lt;/span&gt;.\.cache\native&lt;span class="nt"&gt;&amp;lt;/CachePath&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;CachePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"&amp;#39;$(DOTNET_RUNNING_IN_CONTAINER)&amp;#39; == &amp;#39;true&amp;#39;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;.\.cache\container&lt;span class="nt"&gt;&amp;lt;/CachePath&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;MSBUildProjectExtensionsPath&amp;gt;&lt;/span&gt;$(CachePath)\obj\&lt;span class="nt"&gt;&amp;lt;/MSBUildProjectExtensionsPath&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;BaseIntermediateOutputPath&amp;gt;&lt;/span&gt;$(CachePath)\obj\&lt;span class="nt"&gt;&amp;lt;/BaseIntermediateOutputPath&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;BaseOutputPath&amp;gt;&lt;/span&gt;$(CachePath)\bin\&lt;span class="nt"&gt;&amp;lt;/BaseOutputPath&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;If anybody want to go hardcore and cache the intermediate objects based on the &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/rid-catalog"&gt;RID&lt;/a&gt; or &lt;a href="https://wiki.osdev.org/Target_Triplet"&gt;architecture triplet&lt;/a&gt;, then this can also be done, for example, by adding environment variables to the path.&lt;/p&gt;</description></item>
  <item>
   <title>Common Project Layout, version 0</title>
   <link>https://xgqt.gitlab.io/blog/posts/2023/10/17/common-project-layout-version-0/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2023-10-17-common-project-layout-version-0</guid>
   <pubDate>Tue, 17 Oct 2023 19:45:50 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;This is a tongue-in-cheek &amp;ldquo;draft&amp;rdquo; for Common Project Layout, version 0. It will probably never become any sort of adopted standard but I think it is good to share some ideas that I had while working on this.&lt;/p&gt;

&lt;h2 id="definition"&gt;Definition&lt;/h2&gt;

&lt;p&gt;Common Project Layout (CPL) is a set of good practices for structuring medium-to-large monorepo-like software repositories.&lt;/p&gt;

&lt;h2 id="benefits"&gt;Benefits&lt;/h2&gt;

&lt;p&gt;CPL helps with code organization. It can be a good &amp;ldquo;framework&amp;rdquo; (in a very loose meaning of this word) to modularize product components.&lt;/p&gt;

&lt;p&gt;It can make large repositories easier to work with and understand.&lt;/p&gt;

&lt;h2 id="upfront-limitations"&gt;Upfront limitations&lt;/h2&gt;

&lt;p&gt;CPL is strictly designed for &amp;ldquo;hosting&amp;rdquo; software and all the non-code assets are left up to the engineers to decide their location.&lt;/p&gt;

&lt;p&gt;For example branding assets could be put into the &lt;code&gt;Branding&lt;/code&gt; top-level directory, but on the other hand are we sure they will stay the same with major version?&lt;/p&gt;

&lt;p&gt;Since we can agree that we consider documentation &amp;ldquo;producers&amp;rdquo; (not the produced artifacts) to be code we could also acknowledge that some assets could have their own versioned subproject.&lt;/p&gt;

&lt;h2 id="requirements"&gt;Requirements&lt;/h2&gt;

&lt;h3 id="versioning"&gt;Versioning&lt;/h3&gt;

&lt;p&gt;CPL requires that the software is versioned inside directories whose names include the version. Recommended pattern is to name directories &lt;code&gt;vMAJOR&lt;/code&gt; where &lt;code&gt;MAJOR&lt;/code&gt; is either the current tagged major version or one that will be if no tags exist. It is also recommended to group the &lt;code&gt;vMAJOR&lt;/code&gt; directories under one common directory, for example &lt;code&gt;Source&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="subprojects"&gt;Subprojects&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;vMAJOR&lt;/code&gt; could theoretically contain all the source code mixed together but it should be grouped and organized by their purpose.&lt;/p&gt;

&lt;p&gt;Subproject is defined as a directory inside a versioned (&lt;code&gt;vMAJOR&lt;/code&gt;) directory. &amp;ldquo;Versioned subproject&amp;rdquo; and &amp;ldquo;subproject&amp;rdquo; are synonymous to CPL.&lt;/p&gt;

&lt;p&gt;To mark the purpose of a subproject, whether it is to be used as a helper or as a &amp;ldquo;container&amp;rdquo; for source that is actually exposed (or binaries created from it), it should be adequately named.&lt;/p&gt;

&lt;p&gt;For helpers name does not matter but for source subproject it should be prefixed by project name.&lt;/p&gt;

&lt;p&gt;For example we could have this layout:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;Source/
└──&lt;span class="w"&gt; &lt;/span&gt;v1/
&lt;span class="w"&gt;    &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;Makefile
&lt;span class="w"&gt;    &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;VERSION
&lt;span class="w"&gt;    &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;admin/
&lt;span class="w"&gt;    &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;make/
&lt;span class="w"&gt;    &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;my-project-app/
&lt;span class="w"&gt;    &lt;/span&gt;└──&lt;span class="w"&gt; &lt;/span&gt;my-project-util/
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;In the above example &lt;code&gt;my-project-app&lt;/code&gt; and &lt;code&gt;my-project-lib&lt;/code&gt; are the source subproject and admin and make are subproject that are there only to help in building, managing and deploying the actual source subprojects.&lt;/p&gt;

&lt;p&gt;At the and it is up to the engineer to choose if something is considered a source subproject. For example: If we have a helper subproject that all it does is hold Docker / Podman files for creating a development container what should we name it? As of now I had named them &lt;code&gt;PROJECT-dev-container&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="recommendations"&gt;Recommendations&lt;/h2&gt;

&lt;h3 id="make-and-admin"&gt;Make and admin&lt;/h3&gt;

&lt;p&gt;I think it is a good practice for each &lt;code&gt;vMAJOR&lt;/code&gt; to have a Makefile, or equivalent in other build system, that will call scripts inside &lt;code&gt;vMAJOR/admin&lt;/code&gt; directory that each take care of some small / specific task.&lt;/p&gt;

&lt;p&gt;For example the &lt;code&gt;vMAJOR/Makefile&lt;/code&gt; recipe for &lt;code&gt;build&lt;/code&gt; can call &lt;code&gt;admin/build_my_project_app.py&lt;/code&gt; and &lt;code&gt;admin/build_my_project_lib.py&lt;/code&gt;. Each those scripts would call the &amp;ldquo;real&amp;rdquo; build system specific to the subproject they act upon.&lt;/p&gt;

&lt;h3 id="version-file"&gt;VERSION file&lt;/h3&gt;

&lt;p&gt;It is nice to have a &lt;code&gt;VERSION&lt;/code&gt; file in the &lt;code&gt;vMAJOR&lt;/code&gt; directory. It can be reused by build tools and also to show what was the last version worked upon inside &lt;code&gt;vMAJOR&lt;/code&gt;, the latest git tag can either be put on different major version or simply not be there yet.&lt;/p&gt;

&lt;h2 id="references"&gt;References&lt;/h2&gt;

&lt;p&gt;See those repositories for referencing the CPL layout:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://gitlab.com/xgqt/blog/-/tree/47c4ebf0584384b46043f2374923b9faaf4fd7da/"&gt;gitlab.com/xgqt/blog&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://gitlab.com/xgqt/xgqt-csharp-app-fedimpost/-/tree/9116ac99ffeb87b321c7cf89cdba1c0581baa773/"&gt;gitlab.com/xgqt/xgqt-csharp-app-fedimpost&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description></item>
  <item>
   <title>Using gzexe for shipping Racket executables</title>
   <link>https://xgqt.gitlab.io/blog/posts/2023/09/28/using-gzexe-for-shipping-racket-executables/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2023-09-28-using-gzexe-for-shipping-racket-executables</guid>
   <pubDate>Thu, 28 Sep 2023 18:18:12 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;Racket executables made by &lt;code&gt;raco exe&lt;/code&gt; are known to be quite large. One of tools that can be used to help reduce the size of produced binaries is the &lt;code&gt;gzexe&lt;/code&gt; program.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gzexe&lt;/code&gt; is a tool that can compress a executable binary. It can be acquired by installing &lt;code&gt;gzip&lt;/code&gt; on most Linux distributions (included in the &lt;code&gt;app-arch/gzip&lt;/code&gt; package on Gentoo).&lt;/p&gt;

&lt;h2 id="creating-a-hello-world-executable-with-racket"&gt;Creating a hello-world executable with Racket&lt;/h2&gt;

&lt;p&gt;Write following contents to &lt;code&gt;hello-world.rkt&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;racket/base&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Writing.html#(def._((lib._racket/private/misc..rkt)._displayln))" style="color: inherit"&gt;displayln&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"It REPLs. Ship it!"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/module.html#(form._((lib._racket/private/base..rkt)._module+))" style="color: inherit"&gt;module+&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;To make a binary run:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;raco&lt;span class="w"&gt; &lt;/span&gt;exe&lt;span class="w"&gt; &lt;/span&gt;--orig-exe&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;hello-world&lt;span class="w"&gt; &lt;/span&gt;hello-world.rkt
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;The file &lt;code&gt;hello-world&lt;/code&gt; will be produced.&lt;/p&gt;

&lt;p&gt;This is what &lt;code&gt;file hello-world&lt;/code&gt; says about it:&lt;/p&gt;

&lt;div class="brush: text"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;hello-world: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 3.2.0, stripped
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;This &amp;ldquo;small&amp;rdquo; executable weights &lt;strong&gt;46 MB&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;In comparison &lt;code&gt;busybox&lt;/code&gt; weights around &lt;em&gt;2 MB&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id="compressing-with-gzexe"&gt;Compressing with gzexe&lt;/h2&gt;

&lt;p&gt;Keep in mind that &lt;code&gt;gzexe&lt;/code&gt; will overwrite the compressed file and create a backup with appended "~".&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;gzexe&lt;span class="w"&gt; &lt;/span&gt;hello-world
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;And this gives us only &lt;strong&gt;8,5 MB&lt;/strong&gt;. Nice!&lt;/p&gt;

&lt;p&gt;In comparison &lt;code&gt;bazel&lt;/code&gt;, which is a single-binary build system written in JAVA, executable takes &lt;em&gt;33 MB&lt;/em&gt; on my Gentoo machine. I tried compressing it with &lt;code&gt;gzexe&lt;/code&gt; and it reduces it only by &lt;em&gt;10%&lt;/em&gt;, to around &lt;em&gt;29 MB&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gzexe&lt;/code&gt;is not a silver bullet but with Racket exes it works very nicely.&lt;/p&gt;</description></item>
  <item>
   <title>Shell script setup</title>
   <link>https://xgqt.gitlab.io/blog/posts/2023/07/16/shell-script-setup/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2023-07-16-shell-script-setup</guid>
   <pubDate>Sun, 16 Jul 2023 21:12:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="good-practices"&gt;Good practices&lt;/h1&gt;

&lt;h2 id="use-sh"&gt;Use sh&lt;/h2&gt;

&lt;p&gt;If you do not need &lt;code&gt;bash&lt;/code&gt; features, then use &lt;code&gt;sh&lt;/code&gt;, it is installed on every UNIX-like system.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="exit-on-failure"&gt;Exit on failure&lt;/h2&gt;

&lt;p&gt;Shell scripts continue even if a command returns error. To fail right away use:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="trap-c-c"&gt;Trap C-c&lt;/h2&gt;

&lt;p&gt;Catch Control-c and exit.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exit 130"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;INT
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="use-script-directory"&gt;Use script directory&lt;/h1&gt;

&lt;p&gt;Assume we are executing a script from directory &lt;code&gt;/Admin&lt;/code&gt;, where &lt;code&gt;/&lt;/code&gt; is the root of a given project directory.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;script_path&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="nv"&gt;0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;script_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dirname&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;script_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;We can use &lt;code&gt;${script_root}&lt;/code&gt; to call other scripts form the &lt;code&gt;Admin&lt;/code&gt; directory, but we can also use it to relate to the &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;project_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;realpath&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;script_root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/../"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[INFO] Entering directory: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;project_root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;project_root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;So with above we can run commands form &lt;code&gt;/&lt;/code&gt; (repository root). Like for example &lt;code&gt;make&lt;/code&gt; and other:&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;make
python3&lt;span class="w"&gt; &lt;/span&gt;./Admin/serve_1.py
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="even-better"&gt;Even better&lt;/h1&gt;

&lt;p&gt;Use Python for repository maintenance scripts.&lt;/p&gt;

&lt;div class="brush: python"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chdir&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;subprocess&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;

&lt;span class="n"&gt;script_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;realpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;script_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;project_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;realpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script_root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;".."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;" * Entering directory: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project_root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;leftover_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;::]&lt;/span&gt;
&lt;span class="n"&gt;command_arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"make"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;leftover_args&lt;/span&gt;

&lt;span class="n"&gt;cmd_string&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="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command_arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;" * Executing command: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cmd_string&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command_arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>Debugging Frog blog with syntax macros</title>
   <link>https://xgqt.gitlab.io/blog/posts/2023/07/15/debugging-frog-blog-with-syntax-macros/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2023-07-15-debugging-frog-blog-with-syntax-macros</guid>
   <pubDate>Sat, 15 Jul 2023 16:24:16 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="constructing-debugging-syntax"&gt;Constructing debugging syntax&lt;/h1&gt;

&lt;p&gt;I wanted to echo parameter values when I set them in my blog&amp;rsquo;s &lt;code&gt;frog.rkt&lt;/code&gt; config file.&lt;/p&gt;

&lt;p&gt;Nothing simpler in Racket!&lt;/p&gt;

&lt;p&gt;First I create this macro for echoing a single parameter value when it is set:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/misc..rkt)._define-syntax-rule))" style="color: inherit"&gt;define-syntax-rule&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose-set-parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin))" style="color: inherit"&gt;begin&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; Set the parameter.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameter-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; Then call the parameter and print it&amp;#39;s value.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; The "&amp;#39;parameter-id" is special syntax&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; for turning a "parameter-id" identifier to a symbol.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; We can also write it like:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; &amp;gt; (quote parameter-id)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; to be less confusing.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._printf))" style="color: inherit"&gt;printf&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[DEBUG] (~a ~v)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;parameter-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameter-id&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;then, I create a wrapper for above macro that can take multiple parameter pairs:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/misc..rkt)._define-syntax-rule))" style="color: inherit"&gt;define-syntax-rule&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose-set-parameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameter-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._......))" style="color: inherit"&gt;...&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin))" style="color: inherit"&gt;begin&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; Unpack a chain of "(parameter-id parameter-value)" pairs&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;;; using the "..." syntax.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose-set-parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter-value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket/private/stxcase-scheme..rkt)._......))" style="color: inherit"&gt;...&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="using-the-macro"&gt;Using the macro&lt;/h1&gt;

&lt;p&gt;Afterwards we can call it like so:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose-set-parameters&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"XGQT's blog"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maciej Barć"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Notice that even the form of setting a parameter, that is &lt;code&gt;(parameter-procedure "value")&lt;/code&gt;, remains the same, but in reality it is just similar to how the syntax macro pattern-matches on it.&lt;/p&gt;

&lt;h1 id="inspecting-macro-expansion"&gt;Inspecting macro expansion&lt;/h1&gt;

&lt;p&gt;In &lt;code&gt;racket-mode&lt;/code&gt; inside GNU Emacs we can inspect the macro expansion with &lt;code&gt;racket-expand-region&lt;/code&gt;. Stepping through the expansion provided this result:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin))" style="color: inherit"&gt;begin&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin))" style="color: inherit"&gt;begin&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"XGQT's blog"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._printf))" style="color: inherit"&gt;printf&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[DEBUG] (~a ~v)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;current-title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-title&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin))" style="color: inherit"&gt;begin&lt;/a&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maciej Barć"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._printf))" style="color: inherit"&gt;printf&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[DEBUG] (~a ~v)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;current-author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current-author&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>Comparing objects in Racket</title>
   <link>https://xgqt.gitlab.io/blog/posts/2023/06/18/comparing-objects-in-racket/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2023-06-18-comparing-objects-in-racket</guid>
   <pubDate>Sat, 17 Jun 2023 23:39:38 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="equality-methods"&gt;Equality methods&lt;/h1&gt;

&lt;p&gt;By implementing a method for equality &lt;code&gt;equal-to?&lt;/code&gt; and two extraction methods &lt;code&gt;equal-hash-code-of&lt;/code&gt; and &lt;code&gt;equal-secondary-hash-code-of&lt;/code&gt; we can define our own object comparison rules.&lt;/p&gt;

&lt;p&gt;For more info see &lt;a href="https://docs.racket-lang.org/reference/objectequality.html"&gt;Object Equality and Hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._class*))" style="color: inherit"&gt;class*&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(def._((lib._racket/private/class-internal..rkt)._object~25))" style="color: inherit"&gt;object%&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/objectequality.html#(def._((lib._racket/private/class-internal..rkt)._equal~3c~25~3e))" style="color: inherit"&gt;equal&amp;lt;%&amp;gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._super-new))" style="color: inherit"&gt;super-new&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._init-field))" style="color: inherit"&gt;init-field&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._define/public))" style="color: inherit"&gt;define/public&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equal-to?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;other-object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;recur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._~3d))" style="color: inherit"&gt;=&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/ivaraccess.html#(form._((lib._racket/private/class-internal..rkt)._get-field))" style="color: inherit"&gt;get-field&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;other-object&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._define/public))" style="color: inherit"&gt;define/public&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equal-hash-code-of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hash-code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash-code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._define/public))" style="color: inherit"&gt;define/public&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equal-secondary-hash-code-of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hash-code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash-code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;If we create a new &lt;code&gt;integer%&lt;/code&gt; object we can notice that it is not transparent (we can not inspect values of any of it&amp;rsquo;s fields).&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;;;  =&amp;gt; (object:integer% ...)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;But if we compare two fresh &lt;code&gt;integer%&lt;/code&gt; objects they will be equal.&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Equality.html#(def._((quote._~23~25kernel)._equal~3f))" style="color: inherit"&gt;equal?&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;;  =&amp;gt; #true&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="transparent-class"&gt;Transparent class&lt;/h1&gt;

&lt;p&gt;A transparent cvlass is a class with the &lt;code&gt;inspect&lt;/code&gt; expression valuye se to &lt;code&gt;#false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From Racket documentation &lt;a href="https://docs.racket-lang.org/reference/createclass.html"&gt;Creating Classes&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
 &lt;p&gt; Just as for structure types,  an inspector controls access to the class’s fields,  including private fields, and also affects comparisons using equal?.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._class))" style="color: inherit"&gt;class&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(def._((lib._racket/private/class-internal..rkt)._object~25))" style="color: inherit"&gt;object%&lt;/a&gt;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._super-new))" style="color: inherit"&gt;super-new&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._inspect))" style="color: inherit"&gt;inspect&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/createclass.html#(form._((lib._racket/private/class-internal..rkt)._init-field))" style="color: inherit"&gt;init-field&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;If we create a new &lt;code&gt;integer%&lt;/code&gt; object we can see it&amp;rsquo;s field values.&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;;;  =&amp;gt; (object:integer% 0)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;And if we compare two fresh &lt;code&gt;integer%&lt;/code&gt; objects they will be equal.&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/Equality.html#(def._((quote._~23~25kernel)._equal~3f))" style="color: inherit"&gt;equal?&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/objcreation.html#(form._((lib._racket/private/class-internal..rkt)._new))" style="color: inherit"&gt;new&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integer%&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;;  =&amp;gt; #true&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>Mkdocs with Scribble</title>
   <link>https://xgqt.gitlab.io/blog/posts/2022/07/12/mkdocs-with-scribble/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2022-07-12-mkdocs-with-scribble</guid>
   <pubDate>Mon, 11 Jul 2022 22:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="intro"&gt;Intro&lt;/h1&gt;

&lt;p&gt;Instead of changing CSS style for Your &lt;a href="https://racket-lang.org/"&gt;Racket&lt;/a&gt; projects documentation, You may be interested in compiling &lt;a href="https://en.wikipedia.org/wiki/Markdown"&gt;Markdown&lt;/a&gt; files generated form &lt;a href="https://docs.racket-lang.org/scribble/"&gt;Scribble&lt;/a&gt; source into HTML documentation website.&lt;/p&gt;

&lt;h1 id="creating-mkdocs-project"&gt;Creating MkDocs project&lt;/h1&gt;

&lt;ol&gt;
 &lt;li&gt;
  &lt;p&gt;Create &lt;code&gt;docs&lt;/code&gt; directory and &lt;code&gt;mkdocs.yml&lt;/code&gt;  config file in current directory, along with a dummy  &lt;code&gt;index.md&lt;/code&gt; file in &lt;code&gt;docs&lt;/code&gt; folder.&lt;/p&gt;
  &lt;div class="brush: shell"&gt;
   &lt;div class="source"&gt;
    &lt;table class="sourcetable"&gt;
     &lt;tbody&gt;
      &lt;tr&gt;
       &lt;td class="linenos"&gt;
        &lt;div class="linenodiv"&gt;
         &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
       &lt;td class="code"&gt;
        &lt;div&gt;
         &lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdocs&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/li&gt;
 &lt;li&gt;
  &lt;p&gt;Edit the name of the project.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Replace &lt;code&gt;Racket-Project&lt;/code&gt; with your project name.&lt;/em&gt;&lt;/p&gt;
  &lt;div class="brush: yaml"&gt;
   &lt;div class="source"&gt;
    &lt;table class="sourcetable"&gt;
     &lt;tbody&gt;
      &lt;tr&gt;
       &lt;td class="linenos"&gt;
        &lt;div class="linenodiv"&gt;
         &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
       &lt;td class="code"&gt;
        &lt;div&gt;
         &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="nt"&gt;site_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Racket-Project&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;

&lt;h1 id="building-scribble"&gt;Building Scribble&lt;/h1&gt;

&lt;p&gt;Generate markdown files form scribble documentation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Replace &lt;code&gt;Racket-Project.scrbl&lt;/code&gt; with path to your scribble documentation main source file.&lt;/em&gt;&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;scribble&lt;span class="w"&gt; &lt;/span&gt;--markdown&lt;span class="w"&gt; &lt;/span&gt;--dest&lt;span class="w"&gt; &lt;/span&gt;./docs&lt;span class="w"&gt; &lt;/span&gt;--dest-name&lt;span class="w"&gt; &lt;/span&gt;index.md&lt;span class="w"&gt; &lt;/span&gt;Racket-Project.scrbl
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="building-markdown"&gt;Building Markdown&lt;/h1&gt;

&lt;p&gt;Compile HTML documentation from the markdown source.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdocs&lt;span class="w"&gt; &lt;/span&gt;build
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;HTML files should appear in the &lt;code&gt;site&lt;/code&gt; directory.&lt;/p&gt;

&lt;h1 id="running-the-server"&gt;Running the server&lt;/h1&gt;

&lt;p&gt;Some features, like search for example are only available when running the mkdocs server.&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdocs&lt;span class="w"&gt; &lt;/span&gt;serve
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="caveats"&gt;Caveats&lt;/h1&gt;

&lt;p&gt;Some scribble functions do not look good or work correctly for markdown-to-HTML compilation by MkDocs.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;
  &lt;p&gt;&lt;code&gt;table-of-contents&lt;/code&gt; - looks like a source block&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;
  &lt;p&gt;&lt;code&gt;index-section&lt;/code&gt; - letter links do not work&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h1 id="example-configuration"&gt;Example configuration&lt;/h1&gt;

&lt;div class="brush: yaml"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;site_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;Racket-Ebuild&lt;/span&gt;
&lt;span class="nt"&gt;site_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;xgqt@riseup.net&lt;/span&gt;
&lt;span class="nt"&gt;site_description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;library to ease ebuild creation&lt;/span&gt;
&lt;span class="nt"&gt;site_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;https://gitlab.com/gentoo-racket/racket-ebuild&lt;/span&gt;

&lt;span class="nt"&gt;repo_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;gentoo-racket/racket-ebuild&lt;/span&gt;
&lt;span class="nt"&gt;repo_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;https://gitlab.com/gentoo-racket/racket-ebuild&lt;/span&gt;

&lt;span class="nt"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;search&lt;/span&gt;

&lt;span class="nt"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;material&lt;/span&gt;

&lt;span class="nt"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;social&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;fontawesome/brands/gitlab&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;https://gitlab.com/gentoo-racket/racket-ebuild&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;</description></item>
  <item>
   <title>Portage CI</title>
   <link>https://xgqt.gitlab.io/blog/posts/2022/03/08/portage-ci/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2022-03-08-portage-ci</guid>
   <pubDate>Mon, 07 Mar 2022 23:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="potential-benefits"&gt;Potential benefits&lt;/h1&gt;

&lt;h2 id="running-tests"&gt;Running tests&lt;/h2&gt;

&lt;ul&gt;
 &lt;li&gt;test BEFORE (&lt;code&gt;src_test&lt;/code&gt;) and AFTER  (&lt;code&gt;pkg_postinst&lt;/code&gt;) installation&lt;/li&gt;
 &lt;li&gt;test if and how services break if they are not reloaded&lt;/li&gt;
 &lt;li&gt;test buildsystem configuration&lt;/li&gt;
 &lt;li&gt;sandbox enforces strict and consistent build rules&lt;/li&gt;
 &lt;li&gt;benchmarking with different compilation flags and libraries  versions/releases&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="configuration-matrix"&gt;Configuration matrix&lt;/h2&gt;

&lt;p&gt;We can test across Cartesian product of different configuration settings, like:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://wiki.gentoo.org/wiki/USE_flag"&gt;USE flags&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;MAKEOPTS&lt;/li&gt;
 &lt;li&gt;CFLAGS, CXXFLAGS, CPPFLAGS, LDFAGS, RUSTFLAGS, etc.&lt;/li&gt;
 &lt;li&gt;arches (cross-compilation or run in qemu)&lt;/li&gt;
 &lt;li&gt;static linking&lt;/li&gt;
 &lt;li&gt;supported releases &amp;amp; versions of libraries (eg. glibc &amp;amp; musl)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Also, we could create diffs of installed files across different merges.&lt;/p&gt;

&lt;h2 id="reproducibility"&gt;Reproducibility&lt;/h2&gt;

&lt;ul&gt;
 &lt;li&gt;mini &lt;a href="https://wiki.gentoo.org/wiki/Ebuild_repository"&gt;overlay&lt;/a&gt; with  ::gentoo or any other (eg. company's own) as master&lt;/li&gt;
 &lt;li&gt;record VCS (eg. git) hash of the dependent overlays&lt;/li&gt;&lt;/ul&gt;

&lt;h2 id="binaries"&gt;Binaries&lt;/h2&gt;

&lt;ul&gt;
 &lt;li&gt;grab dependencies from  &lt;a href="https://wiki.gentoo.org/wiki/Binary_package_guide#Setting_up_a_binary_package_host"&gt;binhosts&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;distribute built binaries (maybe upload to a company's own  artifacts server)&lt;/li&gt;
 &lt;li&gt;make &lt;a href="https://appimage.org/"&gt;AppImage&lt;/a&gt;s&lt;/li&gt;&lt;/ul&gt;

&lt;h1 id="getting-there"&gt;Getting there&lt;/h1&gt;

&lt;h2 id="how-do-we-run-this"&gt;How do we run this?&lt;/h2&gt;

&lt;p&gt;Do we want to write a proper tool, which we probably do or do we just run Portage + shells scripts?&lt;/p&gt;

&lt;p&gt;Do we want to run under root, user, in &lt;a href="https://wiki.gentoo.org/wiki/Project:Prefix"&gt;eprefix&lt;/a&gt;, maybe all in docker?&lt;/p&gt;

&lt;h2 id="configuration-files"&gt;Configuration files&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.portci&lt;/code&gt; directory contains the configuration.&lt;/p&gt;

&lt;h2 id="bug-799626"&gt;Bug 799626&lt;/h2&gt;

&lt;p&gt;Link: &lt;a href="https://bugs.gentoo.org/799626"&gt;bugs.gentoo.org/799626&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of using Ansible, Python, Yaml or Scheme we might use something similar to this for simple configuration, or if gets merged to upstream Portage the better.&lt;/p&gt;

&lt;p&gt;Worth mentioning is the idea from Michał Górny who proposes to configure portage with toml files, like the example given in the bug report.&lt;/p&gt;

&lt;div class="brush: conf"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;[package.unmask]
~virtual/libcrypt-2

[package.use.mask]
sys-libs/libxcrypt -system -split-usr

[package.use.force]
sys-libs/glibc -crypt
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Also, &lt;code&gt;package.x&lt;/code&gt; + Toml == a match made in heaven, it looks very nice!&lt;/p&gt;</description></item>
  <item>
   <title>Awesome Racket language features</title>
   <link>https://xgqt.gitlab.io/blog/posts/2021/05/03/awesome-racket-language-features/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2021-05-03-awesome-racket-language-features</guid>
   <pubDate>Sun, 02 May 2021 22:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;p&gt;Also see: &lt;a href="https://github.com/racket/racket/wiki/Fast-Racket"&gt;Fast-Racket at Racket's GitHub Wiki&lt;/a&gt;&lt;/p&gt;

&lt;h1 id="creating-binaries"&gt;Creating binaries&lt;/h1&gt;

&lt;p&gt;You can create &lt;strong&gt;portable&lt;/strong&gt; binaries with Racket's &lt;code&gt;raco&lt;/code&gt; command! Use &lt;code&gt;raco exe&lt;/code&gt; and &lt;code&gt;raco distribute&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;More -&amp;gt; &lt;a href="https://docs.racket-lang.org/raco/exe.html"&gt;https://docs.racket-lang.org/raco/exe.html&lt;/a&gt;&lt;/p&gt;

&lt;h1 id="sample-games"&gt;Sample games&lt;/h1&gt;

&lt;p&gt;Racket provides a executable &lt;code&gt;plt-games&lt;/code&gt;, when ran (from console) it opens a menu of miscellaneous games, among them: jewel, minesweeper, aces, spider, checkers. &amp;amp; more (20 games total).&lt;/p&gt;

&lt;h1 id="plots"&gt;Plots&lt;/h1&gt;

&lt;p&gt;You can &lt;a href="https://docs.racket-lang.org/plot/index.html"&gt;plot&lt;/a&gt; data in &lt;a href="https://docs.racket-lang.org/plot/intro.html#%28part._.Plotting_2.D_.Graphs%29"&gt;2d&lt;/a&gt; &amp;amp; &lt;a href="https://docs.racket-lang.org/plot/intro.html#%28part._.Plotting_3.D_.Graphs%29"&gt;3d&lt;/a&gt; forms.&lt;/p&gt;

&lt;h2 id="2d"&gt;2D&lt;/h2&gt;

&lt;p&gt;Sample code:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;racket/base&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" style="color: inherit"&gt;require&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;racket/gui/base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;racket/math&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot-new-window?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._sin))" style="color: inherit"&gt;sin&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._-))" style="color: inherit"&gt;-&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:label&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"y &lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._~3d))" style="color: inherit"&gt;=&lt;/a&gt; sin(x)"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h2 id="3d"&gt;3D&lt;/h2&gt;

&lt;p&gt;Sample code:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;racket/base&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" style="color: inherit"&gt;require&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;racket/gui/base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;racket/math&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot-new-window?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;#true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot3d&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;surface3d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket/private/base..rkt)._lambda))" style="color: inherit"&gt;lambda&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._*))" style="color: inherit"&gt;*&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._cos))" style="color: inherit"&gt;cos&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._sin))" style="color: inherit"&gt;sin&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._-))" style="color: inherit"&gt;-&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._-))" style="color: inherit"&gt;-&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((lib._racket/math..rkt)._pi))" style="color: inherit"&gt;pi&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An R × R &lt;a href="http://docs.racket-lang.org/ts-reference/type-ref.html#(form._((lib._typed-racket/base-env/base-types-extra..rkt)._~e2~86~92))" style="color: inherit"&gt;→&lt;/a&gt; R function"&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:x-label&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"x"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:y-label&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"y"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;#:z-label&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cos(x) sin(y)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="browser"&gt;Browser&lt;/h1&gt;

&lt;p&gt;There's a included library to render web pages, just "&lt;a href="https://docs.racket-lang.org/browser/index.html"&gt;(require browser)&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;Sample code:&lt;/p&gt;

&lt;div class="brush: racket"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;racket&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" style="color: inherit"&gt;require&lt;/a&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;open-url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://xgqt.gitlab.io/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;h1 id="ffi"&gt;FFI&lt;/h1&gt;

&lt;p&gt;You can use Racket's Foreign Function Interface to interact with non-Racket libraries to make use of very fast libraries written in (mainly) FORTRAN &amp;amp; C.&lt;/p&gt;

&lt;p&gt;For example &lt;a href="https://github.com/soegaard/sci"&gt;sci&lt;/a&gt; uses FFI for &lt;a href="http://www.netlib.org/blas/"&gt;CBLAS &amp;amp; LAPACK&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id="parallelism"&gt;Parallelism&lt;/h1&gt;

&lt;p&gt;For greater speed up with parallel execution there are &lt;a href="https://docs.racket-lang.org/reference/futures.html"&gt;futures&lt;/a&gt;, &lt;a href="https://docs.racket-lang.org/reference/places.html"&gt;places&lt;/a&gt; and &lt;a href="https://docs.racket-lang.org/distributed-places/index.html"&gt;distributed places&lt;/a&gt; (for distributed programming).&lt;/p&gt;</description></item>
  <item>
   <title>How to read this blog</title>
   <link>https://xgqt.gitlab.io/blog/posts/2021/01/02/how-to-read-this-blog/?utm_source=dev&amp;utm_medium=RSS</link>
   <guid isPermaLink="false">urn:https-xgqt-gitlab-io:-blog-posts-2021-01-02-how-to-read-this-blog</guid>
   <pubDate>Fri, 01 Jan 2021 23:00:00 UT</pubDate>
   <author>Maciej Barć</author>
   <description>
&lt;h1 id="git"&gt;Git&lt;/h1&gt;

&lt;p&gt;Because contents of this blog are stored in a git repository you can just&lt;/p&gt;

&lt;div class="brush: shell"&gt;
 &lt;div class="source"&gt;
  &lt;table class="sourcetable"&gt;
   &lt;tbody&gt;
    &lt;tr&gt;
     &lt;td class="linenos"&gt;
      &lt;div class="linenodiv"&gt;
       &lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
     &lt;td class="code"&gt;
      &lt;div&gt;
       &lt;pre&gt;&lt;span&gt;&lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;--verbose&lt;span class="w"&gt; &lt;/span&gt;--recursive&lt;span class="w"&gt; &lt;/span&gt;https://gitlab.com/xgqt/blog
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;then, read the "raw" ORG files in 'posts' directory or make the HTML version executing the 'dev.sh' script (remember that you will need GNU Emacs to render the posts into HTML files).&lt;/p&gt;

&lt;p&gt;Then, you can just git pull to read the news whenever you wish, maybe do it with cron or a script that will pull many repos at once, for example with &lt;a href="https://gitlab.com/xgqt/mydot/-/blob/master/scripts/.local/share/bin/git-mass"&gt;this script&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id="rss"&gt;RSS&lt;/h1&gt;

&lt;p&gt;Org-Static-Blog creates a RSS Feed file &lt;code&gt;rss.xml&lt;/code&gt;, so to subscribe add the link &lt;a href="https://xgqt.gitlab.io/blog/rss.xml"&gt;https://xgqt.gitlab.io/blog/rss.xml&lt;/a&gt; to your favorite RSS reader.&lt;/p&gt;

&lt;p&gt;You can also subscribe to the &lt;a href="https://gitlab.com/xgqt/blog/commits/master.atom"&gt;GitLab repository Atom&lt;/a&gt; feed.&lt;/p&gt;</description></item></channel></rss>