<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>drobilla.net - Programming Languages</title><link href="https://drobilla.net/" rel="alternate"></link><link href="https://drobilla.net/category/programming-languages/feed/atom" rel="self"></link><id>https://drobilla.net/</id><updated>2008-03-13T15:02:00-04:00</updated><entry><title>Iteration in Scheme</title><link href="https://drobilla.net/2008/03/13/iteration-in-scheme.html" rel="alternate"></link><published>2008-03-13T15:02:00-04:00</published><updated>2008-03-13T15:02:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2008-03-13:/2008/03/13/iteration-in-scheme.html</id><content type="html">&lt;p&gt;Thoughts brought on by using &lt;a href="http://www.swig.org/"&gt;SWIG&lt;/a&gt; to make Scheme
bindings for C/C++ code:&lt;/p&gt;
&lt;p&gt;In Scheme, being a LISP, pretty much everything is usually a list. This
is great and makes for elegant code, but as a data structures guy I
cringe to see the ridiculous amount of O(n) searching done in LISP code.
Why is the underlying structure (a list) a dependency of the code using
it? Lack of abstraction: car and cdr only work on cons cells, and lists
are made of cons cells - period. This sucks for plenty of reasons (the
one that encouraged this rant is making Scheme bindings for C++ code).&lt;/p&gt;
&lt;p&gt;Say you want to expose a C or C++ list in Scheme. To be really useful in
Scheme, it will have to work with car and cdr. Luckily any list has the
concept of 'get the value at this position' (car) and 'get the next
position' (cdr). For C++ the position is an iterator, car is *, and cdr
is ++. Unfortunately making 'nice' (ie typical and un-weird) Scheme
bindings for these means you literally have to duplicate the entire C++
list and build a Scheme list out of it, because there's no functional
abstraction going on here, and the type system is nonexistant.&lt;/p&gt;
&lt;p&gt;I guess this boils down to a rant about needing iterators in Scheme. I
cringe at sounding so much like an OO "patterns" kind of guy, but there
it is :)&lt;/p&gt;
&lt;p&gt;Lets say our Scheme dialect has some a type system with polymorphism.
Scheme code is generally something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;list&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="nf"&gt;something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;list&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;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;null?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;list&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="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a-list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a-list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Rename car "get" and cdr "next" to avoid confusion, and use an iterator:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;iter&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="nf"&gt;something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;iter&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;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;valid?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;iter&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="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a-collection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;whatever&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;do-something&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a-collection&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The idiom for do-something (the fundamental LISP idiom if there ever was
one) is the same. The only difference is the call to do-something must
pass an iterator, here with the start function. Slightly unfortunate
maybe, but the benefits are huge:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Common list-like iteration for all data structures (e.g. trees)&lt;/li&gt;
&lt;li&gt;Different styles of iteration (use reverse-end instead of start and
   have do-something work in reverse without modification)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I suppose since I'm assuming a stronger/better/faster Scheme dialect
with a good type system, a collection could just automatically convert
to the 'start' iterator, and the calling code could even be the same if
you just want classic LISP style code. I'm a huge fan of LISP style
languages (mostly because the code is a simple list structure itself),
but there really needs to be an abstraction between the underlying data
structure and the code that uses it.&lt;/p&gt;</content><category term="misc"></category><category term="Hacking"></category><category term="Programming Languages"></category><category term="Scheme"></category></entry></feed>