<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:media="http://search.yahoo.com/mrss/"><channel>
<title>Code Katas in Scheme with Wisp</title>
<atom:link href="https://www.draketo.de/software/wisp-code-katas.xml" rel="self" type="application/rss+xml" />
<link>https://www.draketo.de/software</link>
<description><![CDATA[]]></description>
<language>en</language>
<pubDate>Fri, 18 Oct 2024 09:08:31 +0200</pubDate>
<lastBuildDate>Fri, 18 Oct 2024 09:08:31 +0200</lastBuildDate>
<generator>Emacs 30.0 Org-mode 9.7.12</generator>
<webMaster>arne@fluss (ArneBab)</webMaster>
<image>
<url>https://www.draketo.de/assets/portrait.png</url>
<title>Code Katas in Scheme with Wisp</title>
<link>https://www.draketo.de/software</link>
</image>

<div id="head">
  <div id="preamble">
    <div id="nav-list">
      <a href="../wissen.html" class="category-tab tab-inactive tab-wissen">Wissen</a>
      <a href="../software.html" class="category-tab tab-inactive tab-software">Software</a>
      <a href="../politik.html" class="category-tab tab-inactive tab-politik">Politik</a>
      <a href="../index.html" class="category-tab tab-inactive tab-photo" title="Startpage" aria-label="Startpage"> </a>
      <a href="../anderes.html" class="category-tab tab-inactive tab-anderes">Anderes</a>
      <a href="../kreatives.html" class="category-tab tab-inactive tab-kreatives">Kreatives</a>
      <a href="../rollenspiel.html" class="category-tab tab-inactive tab-rollenspiel">Rollenspiel</a>
    </div>
  </div>
</div>

<div class="dark-mode-toggle"><a onclick="invert()">(dark mode)</a></div>

<p>
Code Katas are a way to hone your coding skills. I’ve long tiptoed
around them; now it is time to change that and do some katas.
</p>

<div class="sourcebox" markdown="1" >
<a href="wisp-code-katas.pdf"><img width="168" height="235" title="PDF" src="../assets/pdf-thumbnail.png" /></a><br />
<a href="wisp-code-katas.pdf">PDF</a> (drucken)
</div>

<p>
I’m starting with the code katas from <a href="http://codekata.com/">codekata.com</a>, because that site
is simple and clear: Just descriptions of Katas. I will focus on the
coding parts, because I want to work them with <a href="http://www.draketo.de/english/wisp.html">Wisp</a>.
</p>

<p>
For more descriptions of code katas, just read <a href="http://codekata.com/">codekata.com</a>. There are
other sites, but many of the older ones got lost in the domain churn
that is still haunting the internet.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p>

<p>
Feel free to follow me along here or do the Katas yourself.
</p>

<p>
Check the <a href="https://www.draketo.de/software/wisp-code-katas.xml">RSS-Feed</a> to get informed when I add new katas.
</p>



<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#ID-465dd799-e2d2-454d-9345-92dc91fc9539">Kata02: Karate Chop</a>
<ul>
<li><a href="#ID-a85de073-5eac-4dae-90fe-70455818b88c">First day: Default upper + lower implementation</a></li>
<li><a href="#ID-67cc8410-7ce3-411c-95d8-04bce61eea31">Second day: Split vector in recursion</a></li>
<li><a href="#ID-3f85cc35-f109-4fbb-b15c-3c74cdaefdf5">Fibonacci-sequence: optimize by golden ratios</a></li>
</ul>
</li>
<li><a href="#ID-f8f1d4a1-2f60-4135-8070-43b643c3b433">Kata04: Data Munging</a>
<ul>
<li><a href="#ID-c51ceadf-2581-4af6-b88f-e8a137e72840">Part One: Weather Data</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<item>
<title>Kata02: Karate Chop</title>
<link>https://www.draketo.de/software/wisp-code-katas.html#org0bd5faa</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/wisp-code-katas.html#org0bd5faa</guid>
<pubDate>Thu, 02 Jul 2020 00:03:00 +0200</pubDate>

<description><![CDATA[<p>
Create 5 different implementations of binary search, one per day.
</p>

<p>
<b>Note:</b> In the first version I had accumulating rounding errors,
because I tried to get the simplest version — that isn’t actually
simple. I already knew that once, but had forgotten it. To hit such
things outside production is exactly why I do these Katas. Also:
training is useful.
</p>

<p>
Goals:
</p>
<ul class="org-ul">
<li>Take notes of subtle errors.</li>
<li>check for merits of the different approaches: which was most fun, hardest to get working, best for production. Why?</li>
<li>How did you find 5 unique approaches?</li>
</ul>

<p>
Requirements:
</p>
<ul class="org-ul">
<li>Efficient enough with up to 100.000 elements that I don’t kill it out of boredom and that it does not exhaust all memory.</li>
<li>Returns the index on success and -1 on failure.</li>
</ul>

<p>
Test:
</p>
<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #0000ff;">import</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">srfi</span> srfi-64
<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">check</span> chop
<span style="color: #0000ff;">    test-begin</span> <span style="color: #8b2252;">"check-chop"</span>
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">3</span> #()
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">3</span> #(<span style="color: #0000ff;">1</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">0</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">1</span> #(<span style="color: #0000ff;">1</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">0</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">1</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">3</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">2</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">5</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">0</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">2</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">4</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">6</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">0</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">1</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">3</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">2</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">5</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span>  <span style="color: #008b8b;">3</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">7</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">0</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">2</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">4</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">6</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">8</span> #(<span style="color: #0000ff;">1</span> <span style="color: #008b8b;">3</span> <span style="color: #008b8b;">5</span> <span style="color: #008b8b;">7</span>)
    <span style="color: #b22222;">;; </span><span style="color: #b22222;">performance-requirement:</span>
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">-1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">list-&gt;vector</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">iota</span> <span style="color: #008b8b;">100000</span>
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">1</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">list-&gt;vector</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">iota</span> <span style="color: #008b8b;">100000</span>
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">50</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">50</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">list-&gt;vector</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">iota</span> <span style="color: #008b8b;">100000</span>
<span style="color: #0000ff;">    test-equal</span> <span style="color: #008b8b;">99995</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop</span> <span style="color: #008b8b;">99995</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">list-&gt;vector</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">iota</span> <span style="color: #008b8b;">100000</span>
<span style="color: #0000ff;">    test-end</span> <span style="color: #8b2252;">"check-chop"</span>
</pre>
</div>
<div id="outline-container-ID-a85de073-5eac-4dae-90fe-70455818b88c" class="outline-3">
<h3 id="ID-a85de073-5eac-4dae-90fe-70455818b88c">First day: Default upper + lower implementation</h3>
<div class="outline-text-3" id="text-orga68523b">
<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop-index</span> target vec
<span style="color: #a020f0;">  . </span><span style="color: #8b2252;">"Simple index-based binary search."</span>
  <span style="color: #483d8b;">define</span> len<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-length</span> vec
  <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">=</span> <span style="color: #008b8b;">0</span> len
<span style="color: #a020f0;">     . </span><span style="color: #008b8b;">-1</span>
     <span style="color: #483d8b;">let</span> loop
<span style="color: #a020f0;">       : </span><span style="color: #0000ff;">lower</span> <span style="color: #008b8b;">0</span>
<span style="color: #0000ff;">         upper</span> len
       <span style="color: #483d8b;">define</span> mid<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">+</span> lower<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">floor/</span> {upper - lower} <span style="color: #008b8b;">2</span>
       <span style="color: #483d8b;">define</span> value<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-ref</span> vec mid
       <span style="color: #b22222;">;; </span><span style="color: #b22222;">used debugging here: </span>
<span style="color: #0000ff;">       format</span> <span style="color: #008b8b;">#t</span> <span style="color: #8b2252;">"target ~a len ~a upper ~a lower ~a mid ~a value ~a vec ~a\n"</span> target len upper lower mid value (<span style="color: #483d8b;">if</span> {len &gt; 100} <span style="color: #008b8b;">#f</span> vec)
<span style="color: #0000ff;">       cond</span>
<span style="color: #0000ff;">         {target</span> = value}
<span style="color: #a020f0;">           . </span>mid
         <span style="color: #b22222;">;; </span><span style="color: #b22222;">error: terminator-condition wasn&#8217;t clear. Must be lower=mid due to floor/</span>
<span style="color: #0000ff;">         {lower</span> = mid}
<span style="color: #a020f0;">           . </span><span style="color: #008b8b;">-1</span>
<span style="color: #0000ff;">         {target</span> &lt; value}
<span style="color: #0000ff;">             loop</span> lower mid
<span style="color: #0000ff;">         {target</span> &gt; value}
<span style="color: #0000ff;">             loop</span> {mid + 1} upper

<span style="color: #0000ff;">{{{tests}}}</span>           
<span style="color: #0000ff;">check</span> chop-index
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-67cc8410-7ce3-411c-95d8-04bce61eea31" class="outline-3">
<h3 id="ID-67cc8410-7ce3-411c-95d8-04bce61eea31">Second day: Split vector in recursion</h3>
<div class="outline-text-3" id="text-org775f8ab">
<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop-split</span> target vec
<span style="color: #a020f0;">  . </span><span style="color: #8b2252;">"Split the vector in recursion."</span>
  <span style="color: #483d8b;">let</span> loop<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(vec</span> vec) (<span style="color: #0000ff;">offset</span> <span style="color: #008b8b;">0</span>)
    <span style="color: #b22222;">;; </span><span style="color: #b22222;">Error: (out-of-range "vector-ref" "Argument 2 out of range: ~S" (0) (0))</span>
    <span style="color: #483d8b;">define</span> len<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-length</span> vec
    <span style="color: #483d8b;">define</span> half<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">floor/</span> len <span style="color: #008b8b;">2</span>
    <span style="color: #b22222;">;; </span><span style="color: #b22222;">Error: missed the zero-length case</span>
    <span style="color: #483d8b;">define</span> value<span style="color: #a020f0;"> : </span><span style="color: #483d8b;">if</span> {len = 0} <span style="color: #008b8b;">#f</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-ref</span> vec half
<span style="color: #0000ff;">    format</span> <span style="color: #008b8b;">#t</span> <span style="color: #8b2252;">"target ~a len ~a half ~a offset ~a value ~a vec ~a\n"</span> target len half offset value (<span style="color: #483d8b;">if</span> {len &gt; 100} <span style="color: #008b8b;">#f</span> vec)
<span style="color: #0000ff;">    cond</span>
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">=</span> len <span style="color: #008b8b;">0</span>
<span style="color: #a020f0;">        . </span><span style="color: #008b8b;">-1</span>
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">=</span> target value
<span style="color: #0000ff;">        +</span> offset half
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">=</span> len <span style="color: #008b8b;">1</span>
<span style="color: #a020f0;">        . </span><span style="color: #008b8b;">-1</span>
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">&gt;</span> target value
        <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> v2<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">make-vector</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">-</span> len half
<span style="color: #0000ff;">          vector-move-left!</span> vec half len v2 <span style="color: #008b8b;">0</span>
<span style="color: #0000ff;">          loop</span> v2<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">+</span> half offset
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">=</span> half <span style="color: #008b8b;">0</span> <span style="color: #b22222;">;; </span><span style="color: #b22222;">fallthrough: skip vector operation</span>
<span style="color: #a020f0;">        . </span><span style="color: #008b8b;">-1</span>
<span style="color: #a020f0;">      : </span><span style="color: #0000ff;">&lt;</span> target value
        <span style="color: #b22222;">;; </span><span style="color: #b22222;">Error: got the half wrong (used half + 1)</span>
        <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> v2<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">make-vector</span> half
<span style="color: #0000ff;">          vector-move-left!</span> vec <span style="color: #008b8b;">0</span> half v2 <span style="color: #008b8b;">0</span>
<span style="color: #0000ff;">          loop</span> v2 offset

<span style="color: #0000ff;">{{{tests}}}</span>           
<span style="color: #0000ff;">check</span> chop-split
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-3f85cc35-f109-4fbb-b15c-3c74cdaefdf5" class="outline-3">
<h3 id="ID-3f85cc35-f109-4fbb-b15c-3c74cdaefdf5">Fibonacci-sequence: optimize by golden ratios</h3>
<div class="outline-text-3" id="text-org7dc3369">
<p>
This is an experimental implementation. It works for the tests, but I’m not sure whether it is general enough.
</p>

<p>
It took me a while to find that I have to allow for index-clamping at the upper end.
</p>

<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">chop-fib</span> target vec
<span style="color: #a020f0;">  . </span><span style="color: #8b2252;">"Use golden sequence steps."</span>
  <span style="color: #483d8b;">define</span> len<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-length</span> vec
  <span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> n
    <span style="color: #483d8b;">if</span> {n = 0} <span style="color: #008b8b;">1</span>
       <span style="color: #483d8b;">let</span> loop<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(f1</span> <span style="color: #008b8b;">1</span>) (<span style="color: #0000ff;">f2</span> <span style="color: #008b8b;">1</span>) (<span style="color: #0000ff;">step</span> <span style="color: #008b8b;">0</span>)
         <span style="color: #483d8b;">if</span> {step &gt;= n} f2
<span style="color: #0000ff;">           loop</span> f2 {f1 + f2} {step + 1}
  <span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib-steps</span> len
<span style="color: #a020f0;">    . </span><span style="color: #8b2252;">"the number of steps needed in a fibonacci-sequence to hit at least the given length"</span>
    <span style="color: #483d8b;">if</span> {len &lt;= 1} <span style="color: #008b8b;">1</span>
      <span style="color: #483d8b;">let</span> loop<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(f1</span> <span style="color: #008b8b;">1</span>) (<span style="color: #0000ff;">f2</span> <span style="color: #008b8b;">1</span>) (<span style="color: #0000ff;">step</span> <span style="color: #008b8b;">1</span>)
        <span style="color: #483d8b;">if</span> {f2 &gt;= len} step
<span style="color: #0000ff;">          loop</span> f2 {f1 + f2} {step + 1}
  <span style="color: #483d8b;">define</span> max-steps<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib-steps</span> len
  <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">=</span> <span style="color: #008b8b;">0</span> len
<span style="color: #a020f0;">     . </span><span style="color: #008b8b;">-1</span>
     <span style="color: #483d8b;">let</span> loop
<span style="color: #a020f0;">       : </span><span style="color: #0000ff;">index</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">min</span> {len - 1}<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> {max-steps - 2}
<span style="color: #0000ff;">         step</span> <span style="color: #008b8b;">1</span>
<span style="color: #0000ff;">         direction</span><span style="color: #008b8b;"> 'right</span>
<span style="color: #0000ff;">       cond</span>
<span style="color: #0000ff;">         {step</span> &gt; { <span style="color: #008b8b;">2</span> * max-steps }} <span style="color: #008b8b;">-1</span> <span style="color: #b22222;">;; </span><span style="color: #b22222;">error: limited steps, but the staggered step-sizes we can take here can break this.</span>
<span style="color: #0000ff;">         {index</span> &lt; 0} <span style="color: #008b8b;">-1</span>
<span style="color: #0000ff;">         {index</span> &gt;= len} <span style="color: #008b8b;">-1</span>
<span style="color: #0000ff;">         else</span>
          <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> value<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">vector-ref</span> vec index
           <span style="color: #b22222;">;; </span><span style="color: #b22222;">used debugging here: </span>
<span style="color: #0000ff;">           format</span> <span style="color: #008b8b;">#t</span> <span style="color: #8b2252;">"target ~a step ~a max-steps ~a len ~a index ~a value ~a vec ~a\n"</span> target step max-steps len index value (<span style="color: #483d8b;">if</span> {len &gt; 100} <span style="color: #008b8b;">#f</span> vec)
<span style="color: #0000ff;">           cond</span>
<span style="color: #0000ff;">             {target</span> = value} index
<span style="color: #0000ff;">             {step</span> &gt; max-steps} <span style="color: #008b8b;">-1</span> <span style="color: #b22222;">;; </span><span style="color: #b22222;">error: limited steps, but rounding of diff can break this</span>
<span style="color: #0000ff;">             {index</span> &lt; 0} <span style="color: #008b8b;">-1</span>
<span style="color: #0000ff;">             {target</span> &gt; value}
               <span style="color: #b22222;">;; </span><span style="color: #b22222;">move to right</span>
               <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">=</span> index {len - 1}
<span style="color: #a020f0;">                  . </span><span style="color: #008b8b;">-1</span>
                  <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> direction<span style="color: #008b8b;"> 'right</span>
                      <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> diff<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> {max-steps - step - 3}
                          <span style="color: #b22222;">;; </span><span style="color: #b22222;">format #t "right smaller diff ~a\n" diff</span>
<span style="color: #0000ff;">                          loop</span> <span style="color: #b22222;">;</span>
<span style="color: #0000ff;">                            min</span> {len - 1}<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">+</span> index diff <span style="color: #b22222;">;; </span><span style="color: #b22222;">error: missed that I have to clamp the index when moving up.</span>
<span style="color: #0000ff;">                            +</span> step <span style="color: #008b8b;">2</span>
<span style="color: #a020f0;">                            . </span>'right
                      <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> diff<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> {max-steps - step - 2}
                          <span style="color: #b22222;">;; </span><span style="color: #b22222;">format #t "right larger diff ~a\n" diff</span>
<span style="color: #0000ff;">                          loop</span> <span style="color: #b22222;">;</span>
<span style="color: #0000ff;">                            min</span> {len - 1}<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">+</span> index diff
<span style="color: #0000ff;">                            +</span> step <span style="color: #008b8b;">1</span>
<span style="color: #a020f0;">                            . </span>'right
<span style="color: #0000ff;">             {target</span> &lt; value}
               <span style="color: #b22222;">;; </span><span style="color: #b22222;">move to left</span>
               <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> direction<span style="color: #008b8b;"> 'left</span>
                   <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> diff<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> {max-steps - step - 3}
                       <span style="color: #b22222;">;; </span><span style="color: #b22222;">format #t "left smaller diff ~a\n" diff</span>
<span style="color: #0000ff;">                       loop</span> <span style="color: #b22222;">;</span>
<span style="color: #0000ff;">                         -</span> index diff
<span style="color: #0000ff;">                         +</span> step <span style="color: #008b8b;">2</span>
<span style="color: #a020f0;">                         . </span>'left
                   <span style="color: #483d8b;">let</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">:</span> diff<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">fib</span> {max-steps - step - 2}
                       <span style="color: #b22222;">;; </span><span style="color: #b22222;">format #t "left larger diff ~a\n" diff</span>
<span style="color: #0000ff;">                       loop</span> <span style="color: #b22222;">;</span>
<span style="color: #0000ff;">                         -</span> index diff
<span style="color: #0000ff;">                         +</span> step <span style="color: #008b8b;">1</span>
<span style="color: #a020f0;">                         . </span>'left


<span style="color: #0000ff;">{{{tests}}}</span>           
<span style="color: #0000ff;">check</span> chop-fib
</pre>
</div>
</div>
</div>
]]></description>
</item>
<item>
<title>Kata04: Data Munging</title>
<link>https://www.draketo.de/software/wisp-code-katas.html#org03b1684</link>
<author>arne@fluss (ArneBab)</author>
<guid isPermaLink="false">https://www.draketo.de/software/wisp-code-katas.html#org03b1684</guid>
<pubDate>Tue, 29 Dec 2020 02:11:00 +0100</pubDate>

<description><![CDATA[<div id="outline-container-ID-c51ceadf-2581-4af6-b88f-e8a137e72840" class="outline-3">
<h3 id="ID-c51ceadf-2581-4af6-b88f-e8a137e72840">Part One: Weather Data</h3>
<div class="outline-text-3" id="text-org426ec6a">
<p>
Output the day number (column one) with the smallest temperature
spread (second column minus third column).
</p>

<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #0000ff;">import</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">only</span> (<span style="color: #0000ff;">srfi</span> srfi-1) first second
<span style="color: #0000ff;">         only</span> (<span style="color: #0000ff;">ice-9</span> rdelim) read-line

<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-columns</span> port
    <span style="color: #483d8b;">let</span> loop<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(columns</span> <span style="color: #008b8b;">'()</span>) (<span style="color: #0000ff;">index</span> <span style="color: #008b8b;">0</span>)
        <span style="color: #483d8b;">define</span> column  
          <span style="color: #483d8b;">let</span> linereader<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(word-index</span> index) (<span style="color: #0000ff;">heading</span> <span style="color: #008b8b;">'()</span>) (<span style="color: #0000ff;">in-word</span> <span style="color: #008b8b;">#f</span>) (<span style="color: #0000ff;">ch</span> (<span style="color: #0000ff;">read-char</span> port))
<span style="color: #0000ff;">            cond</span>
<span style="color: #a020f0;">              : </span><span style="color: #483d8b;">and</span> in-word<span style="color: #a020f0;"> : </span><span style="color: #483d8b;">or</span> (<span style="color: #0000ff;">equal?</span> ch <span style="color: #008b8b;">#\space)</span> (<span style="color: #0000ff;">equal?</span> ch <span style="color: #008b8b;">#\newline)</span>
<span style="color: #0000ff;">                cons</span> index<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">cons</span> word-index<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">apply</span> string<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">reverse</span> heading
<span style="color: #0000ff;">              in-word</span>
<span style="color: #0000ff;">                linereader</span> (<span style="color: #0000ff;">+</span> <span style="color: #008b8b;">1</span> word-index) (<span style="color: #0000ff;">cons</span> ch heading) in-word<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-char</span> port
<span style="color: #a020f0;">              : </span><span style="color: #483d8b;">not</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> <span style="color: #008b8b;">#\space</span> ch
<span style="color: #0000ff;">                linereader</span> (<span style="color: #0000ff;">+</span> <span style="color: #008b8b;">1</span> word-index) (<span style="color: #0000ff;">cons</span> ch heading) <span style="color: #008b8b;">#t</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-char</span> port
<span style="color: #0000ff;">              else</span>
<span style="color: #0000ff;">                linereader</span> (<span style="color: #0000ff;">+</span> <span style="color: #008b8b;">1</span> word-index) heading in-word<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-char</span> port
        <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> <span style="color: #008b8b;">#\newline</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">peek-char</span> port
<span style="color: #a020f0;">            . </span>columns
<span style="color: #0000ff;">            loop</span>
<span style="color: #0000ff;">                cons</span> column columns
<span style="color: #0000ff;">                car</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">cdr</span> column

<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-one-line-by-column-names</span> port column-info names
  <span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">get-name</span> column
<span style="color: #0000ff;">     cdr</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">cdr</span> column
  <span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">index-starts-named-column?</span> index
<span style="color: #0000ff;">    filter</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">&#955;(x)</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> index<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">first</span> x
<span style="color: #0000ff;">        filter</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">&#955;(x)</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">member</span> (<span style="color: #0000ff;">get-name</span> x) names
<span style="color: #a020f0;">           . </span>column-info
  <span style="color: #483d8b;">let</span> skip-to-column<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(data</span> <span style="color: #008b8b;">'()</span>) (<span style="color: #0000ff;">index</span> <span style="color: #008b8b;">0</span>) (<span style="color: #0000ff;">ch</span> (<span style="color: #0000ff;">read-char</span> port))
      <span style="color: #483d8b;">define</span> relevant-columns<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">index-starts-named-column?</span> index
<span style="color: #0000ff;">      cond</span>
<span style="color: #a020f0;">          : </span><span style="color: #483d8b;">or</span> (<span style="color: #0000ff;">equal?</span> ch <span style="color: #008b8b;">#\newline)</span> (<span style="color: #0000ff;">eof-object?</span> ch)
<span style="color: #a020f0;">            . </span>data
<span style="color: #a020f0;">          : </span><span style="color: #0000ff;">null?</span> relevant-columns
<span style="color: #0000ff;">            skip-to-column</span> data (<span style="color: #0000ff;">+</span> index <span style="color: #008b8b;">1</span>) (<span style="color: #0000ff;">read-char</span> port)
<span style="color: #0000ff;">          else</span>
            <span style="color: #483d8b;">let</span> :
              <span style="color: #483d8b;">define</span> column<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">first</span> relevant-columns
              <span style="color: #483d8b;">define</span> column-name<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">get-name</span> column
              <span style="color: #483d8b;">define</span> column-end<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">second</span> column
              <span style="color: #483d8b;">let</span> read-column<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(column-content</span> (<span style="color: #0000ff;">list</span>)) (<span style="color: #0000ff;">index</span> index) (<span style="color: #0000ff;">ch</span> ch)
                <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">equal?</span> column-end index
<span style="color: #0000ff;">                   skip-to-column</span>
<span style="color: #0000ff;">                       cons</span> (<span style="color: #0000ff;">cons</span> column-name (<span style="color: #0000ff;">apply</span> string (<span style="color: #0000ff;">reverse</span> column-content))) data
<span style="color: #a020f0;">                       . </span>index
<span style="color: #0000ff;">                       read-char</span> port
<span style="color: #0000ff;">                   read-column</span>
<span style="color: #0000ff;">                     cons</span> ch column-content
<span style="color: #0000ff;">                     +</span> index <span style="color: #008b8b;">1</span>
<span style="color: #0000ff;">                     read-char</span> port

<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">find-day-with-minimal-spread</span> port columns
<span style="color: #a020f0;">    . </span><span style="color: #8b2252;">"Find the day (Dy) with minimal spread (MxT - MnT)"</span>
    <span style="color: #483d8b;">let</span> loop<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">(min-day</span> <span style="color: #008b8b;">#f</span>) (<span style="color: #0000ff;">min-spread</span> <span style="color: #008b8b;">#f</span>)
      <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">eof-object?</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">peek-char</span> port
<span style="color: #a020f0;">         . </span>min-day
         <span style="color: #483d8b;">let</span> :
           <span style="color: #483d8b;">define</span> line 
<span style="color: #0000ff;">             read-one-line-by-column-names</span> port columns '(<span style="color: #8b2252;">"Dy"</span> <span style="color: #8b2252;">"MxT"</span> <span style="color: #8b2252;">"MnT"</span>)
           <span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">column-value</span> name
<span style="color: #0000ff;">             string-&gt;number</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">string-trim</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">assoc-ref</span> line name
           <span style="color: #483d8b;">define</span> day<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">column-value</span> <span style="color: #8b2252;">"Dy"</span>
           <span style="color: #483d8b;">define</span> MxT<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">column-value</span> <span style="color: #8b2252;">"MxT"</span>
           <span style="color: #483d8b;">define</span> MnT<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">column-value</span> <span style="color: #8b2252;">"MnT"</span>
           <span style="color: #483d8b;">define</span> spread
             <span style="color: #483d8b;">if</span><span style="color: #a020f0;"> : </span><span style="color: #483d8b;">and</span> MxT MnT
<span style="color: #0000ff;">                -</span> MxT MnT
<span style="color: #a020f0;">                . </span><span style="color: #008b8b;">#f</span>
<span style="color: #0000ff;">           cond</span>
<span style="color: #a020f0;">             : </span><span style="color: #483d8b;">not</span> min-day
<span style="color: #0000ff;">               loop</span> day spread
<span style="color: #a020f0;">             : </span><span style="color: #483d8b;">or</span> (<span style="color: #483d8b;">not</span> day) (<span style="color: #483d8b;">not</span> spread) <span style="color: #b22222;">;; </span><span style="color: #b22222;">error condition: not parseable</span>
<span style="color: #0000ff;">               loop</span> min-day min-spread
<span style="color: #0000ff;">             {spread</span> &lt; min-spread}
<span style="color: #0000ff;">               loop</span> day spread
<span style="color: #0000ff;">             else</span>
<span style="color: #0000ff;">               loop</span> min-day min-spread


<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-weather</span>
<span style="color: #0000ff;">    call-with-input-file</span> <span style="color: #8b2252;">"weather.dat"</span>
<span style="color: #0000ff;">      &#955;</span> (<span style="color: #0000ff;">port</span>)
        <span style="color: #483d8b;">define</span> columns<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">read-columns</span> port
<span style="color: #0000ff;">        newline</span>
<span style="color: #0000ff;">        read-line</span> port <span style="color: #b22222;">; </span><span style="color: #b22222;">strip empty line</span>
<span style="color: #0000ff;">        display</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">find-day-with-minimal-spread</span> port columns
<span style="color: #0000ff;">        newline</span>

</pre>
</div>

<p>
Let’s add a little <a href="https://www.draketo.de/proj/py2guile/#sec-2-2-3-2-2">scaffolding</a> to make this efficient<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> to run as script.
</p>

<div class="org-src-container">
<pre class="src src-wisp"><span style="color: #b22222;">#!/usr/bin/env bash</span>
<span style="color: #0000ff;">exec</span> guile -L $(<span style="color: #0000ff;">dirname</span> $(<span style="color: #0000ff;">realpath</span> <span style="color: #8b2252;">"$0"</span>)) -x .w --language=wisp -e<span style="color: #008b8b;"> '(weather)'</span> -c<span style="color: #008b8b;"> ''</span> <span style="color: #8b2252;">"$@"</span>
<span style="color: #b22222;">; </span><span style="color: #b22222;">!#</span>
<span style="color: #0000ff;">define-module</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">weather</span>
<span style="color: #a020f0;">   . </span>#:export<span style="color: #a020f0;"> : </span><span style="color: #0000ff;">main</span>

{{{weather}}}

<span style="color: #483d8b;">define</span><span style="color: #a020f0;"> : </span><span style="color: #0000ff;">main</span> args
<span style="color: #0000ff;">  read-weather</span>
</pre>
</div>
</div>
</div>
]]></description>
</item>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
To secure this page against domain churn, it also exists <a href="https://d6.gnutella2.info/freenet/USK@LHeuG-SU5ZvYQXTu8Y9mhjCYyQxB-m-W~ryElufr-2M,Ij9l0U1Wa~FQu7GFBf~ciwUbCwpTFv6mWZkS1YuoxQk,AQACAAE/arnebab-org/51/">within Freenet</a>, so it will only fall to link churn if people don’t visit it. Also you can <a href="https://hg.sr.ht/~arnebab/draketo/">find its full source on hg.sr.ht</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
The bash-indirection is pretty efficient, since it uses the compile-cache of Guile that <a href="https://wingolog.org/archives/2014/01/19/elf-in-guile">can be mmapped directly</a>. To test its performance again, I just ran the script 100 times in a simple for loop and divided the time by 100. Parsing the weather takes around 33ms on my machine. Running a module where the main just returns <code>#f</code> takes around 25ms.
</p></div></div>


</div>
</div></channel>
</rss>
