<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6687315</id><updated>2012-01-12T19:47:27.584-08:00</updated><category term='iSeries'/><category term='SQL'/><category term='Zen'/><category term='anaphora'/><category term='functions'/><category term='ontology'/><category term='syntax'/><category term='IDE'/><category term='program transformation'/><category term='oregon state university'/><category term='evolution'/><category term='types'/><category term='chi'/><category term='Eckhart Tolle'/><category term='f#'/><category term='haskell polynomials'/><category term='AI'/><category term='lojban'/><category term='python'/><category term='haskell'/><category term='polynomials'/><category term='syntonicity programming workflow monad'/><category term='precedence'/><category term='programming languages'/><category term='referential transparency'/><category term='comments'/><category term='center embedding'/><category term='end-user programming'/><category term='currying'/><category term='array slicing'/><category term='refactoring'/><category term='logic'/><category term='HCI'/><category term='programming'/><category term='icfp'/><category term='genetic algorithms'/><category term='parameters'/><category term='lisp'/><category term='monads'/><category term='databases'/><category term='gripe'/><category term='icfp contest'/><category term='chi2009 thanatosensitivity'/><category term='DB2'/><category term='functional programming'/><category term='microsoft'/><category term='ocaml'/><category term='relational model'/><category term='user study'/><category term='mono'/><category term='bloat'/><category term='burrows-wheeler transform'/><category term='beginner'/><title type='text'>Sambangu</title><subtitle type='html'>About languages that bridge the gap between minds and machines.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>51</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6687315.post-2539338832863489599</id><published>2011-11-28T17:07:00.001-08:00</published><updated>2011-11-28T18:14:33.418-08:00</updated><title type='text'>Darius and the Dragons</title><content type='html'>I love the writing system designed for the dragons in Bethesda's new game, Skyrim.&lt;br /&gt;&lt;br /&gt;According to a &lt;a href="http://www.gameinformer.com/b/features/archive/2011/01/20/skyrim-s-dragon-shouts.aspx?PostPageIndex=1"&gt;gameinformer interview&lt;/a&gt; with the language's designers, the symbols are designed to look like they were gouged into stone by dragons with three talons and a dewclaw (that odd extra toe partway up your cat's leg that seems to serve no purpose)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Fmgp7zQkVa8/TtQkDMFEh6I/AAAAAAAAA5Q/SsYNLfYgSAA/s1600/skyrim_image.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/-Fmgp7zQkVa8/TtQkDMFEh6I/AAAAAAAAA5Q/SsYNLfYgSAA/s320/skyrim_image.jpg" width="300" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-DU7IojlHZ50/TtQkDHbA33I/AAAAAAAAA5Y/bhHLRcU1G50/s1600/skyrim_image2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="86" src="http://3.bp.blogspot.com/-DU7IojlHZ50/TtQkDHbA33I/AAAAAAAAA5Y/bhHLRcU1G50/s320/skyrim_image2.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Dragon writing from Skyrim&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Bethesda (the company that makes Skyrim) was not the first bunch to encounter this graphic design problem. &lt;a href="http://en.wikipedia.org/wiki/Cyrus_the_Great"&gt;Cyrus the Great&lt;/a&gt; was an ancient Persian king (around 600 BCE) with the same idea: he wanted to create monumental inscriptions to celebrate his grandiose awesomeness, and he appeared to have a similar aesthetic, and apparently had stoneworking tools not unlike Skyrim dragon talons:&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-MZUW6j0_W7k/TtQl72Aa-xI/AAAAAAAAA50/m2MmCUZJ0Fs/s1600/800px-BehistunInscriptiondetail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="210" src="http://4.bp.blogspot.com/-MZUW6j0_W7k/TtQl72Aa-xI/AAAAAAAAA50/m2MmCUZJ0Fs/s320/800px-BehistunInscriptiondetail.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;"Newer" cuneiform of Cyrus and Darius, &lt;br /&gt;&amp;nbsp;about 600 BCE (from Wikipedia)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;That's from the Behistun inscription in Iran, which is a really good sample of this writing by a slightly later king, Darius the Great. It is a solemn record of how awesome he is, and what he's conquered: it begins, "I (am) Darius, the great king, the king of kings, the king in Persia, the king of countries." &lt;br /&gt;&lt;br /&gt;This is technically cuneiform, "wedge-shaped" writing. Cuneiform is the oldest kind of writing we know of, originally used by the Sumerians. But Sumerian cuneiform was invented for a different medium: they wrote it by pressing a wedge-shaped tool into clay, not by whacking spikes into cliffs.&lt;br /&gt;&lt;br /&gt;The Sumerian writing system was already at least two thousand years old and on the decline when Cyrus and Darius came along, but Cyrus's people revived it and adapted it to his language (Old Persian) to make this type of monumental inscription.  I don't know why, but I wonder if they had the same feelings about it as the Skyrim artists: it evokes dragon's claws and ancient secret meanings. Maybe Cyrus hoped to co-opt the mystique of ancient Sumerian and Akkadian writing, the same way we invent Latin mottos for modern institutions.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-MkNsKSu7FNE/TtQqcA40gKI/AAAAAAAAA6A/OXbRGR8fpBs/s1600/hamuexemplar.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-MkNsKSu7FNE/TtQqcA40gKI/AAAAAAAAA6A/OXbRGR8fpBs/s320/hamuexemplar.jpg" width="95" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Older cuneiform, &lt;br /&gt;from Code of &lt;br /&gt;Hammurabi &lt;br /&gt;(~1700 BCE)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;But I think Cyrus improved on the state of the art. Compare the Behistun inscription with real old skool cuneiform back when it was still in regular use a thousand years before: on the right here is a sample from the Code of Hammurabi. Cyrus's relatively simple script is almost a true alphabet (it represents syllables with about 50 symbols), but Hammurabi was writing the Akkadian language with more complicated cuneiform shapes, with more varied shapes and angles, uneven spacing, and the symbols representing, like modern Japanese, a mix of sounds and meanings. To me, Hammurabi's writing has a sloppy, random look, and as you look at even older inscriptions, it gets even sloppier. I think the simpler systems of Cyrus the Great and Skyrim's Dragon Writing look more imposing as inscription than Hammurabi's did. &amp;nbsp;Each serves their purpose well enough; Hammurabi was trying to codify a stable system of law in a writing system people at the time understood, while Cyrus was trying to make people's hair stand on end.&lt;br /&gt;&lt;br /&gt;It's time for a cuneiform revival: let's come up with a system for writing English using this style of writing, and start marking gravestones and monuments this way. The Roman alphabet has been fun for these last couple thousand years, and it's perfectly adequate for business expense reimbursement vouchers and vampire romance novels, but clearly it lacks the gravitas of stonecarved cuneiform.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-2539338832863489599?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/2539338832863489599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=2539338832863489599&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2539338832863489599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2539338832863489599'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2011/11/darius-and-dragons.html' title='Darius and the Dragons'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Fmgp7zQkVa8/TtQkDMFEh6I/AAAAAAAAA5Q/SsYNLfYgSAA/s72-c/skyrim_image.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-3604706562305152129</id><published>2009-11-16T14:22:00.000-08:00</published><updated>2009-11-16T14:27:50.045-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bloat'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='gripe'/><title type='text'>Code bloat</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_bSZRfbZs5OE/SwHQ_NmRXvI/AAAAAAAAAL4/dpdAZlCm41s/s1600/Screen+shot+2009-11-16+at+2.20.54+PM.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 103px;" src="http://1.bp.blogspot.com/_bSZRfbZs5OE/SwHQ_NmRXvI/AAAAAAAAAL4/dpdAZlCm41s/s320/Screen+shot+2009-11-16+at+2.20.54+PM.png" alt="" id="BLOGGER_PHOTO_ID_5404830812221824754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Really, Microsoft?  It takes 200.2 MB of code to convert an XML file? Really?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-3604706562305152129?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/3604706562305152129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=3604706562305152129&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3604706562305152129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3604706562305152129'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/11/code-bloat' title='Code bloat'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_bSZRfbZs5OE/SwHQ_NmRXvI/AAAAAAAAAL4/dpdAZlCm41s/s72-c/Screen+shot+2009-11-16+at+2.20.54+PM.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-7241461856637924129</id><published>2009-06-11T16:23:00.000-07:00</published><updated>2009-06-11T16:27:03.681-07:00</updated><title type='text'>Use case stick figures</title><content type='html'>The stick figures in use case diagrams seem simple and featureless, but they undoubtedly have a rich inner life.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_bSZRfbZs5OE/SjGSccATezI/AAAAAAAAAKE/fKxA4pI1CpM/s1600-h/usecase.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 255px; height: 293px;" src="http://4.bp.blogspot.com/_bSZRfbZs5OE/SjGSccATezI/AAAAAAAAAKE/fKxA4pI1CpM/s320/usecase.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5346215249916951346" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-7241461856637924129?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/7241461856637924129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=7241461856637924129&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7241461856637924129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7241461856637924129'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/06/use-case-stick-figures' title='Use case stick figures'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_bSZRfbZs5OE/SjGSccATezI/AAAAAAAAAKE/fKxA4pI1CpM/s72-c/usecase.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4901673779047345905</id><published>2009-04-09T07:29:00.000-07:00</published><updated>2009-04-09T08:10:05.199-07:00</updated><title type='text'>chi2009 -- day 3</title><content type='html'>Chi day 3. Everyone here has done a formative study to show how users go about some task on the computer or in their lives, generated a list of design criteria from that, mocked up a prototype, tested it in lab study, and shown with bar graphs that people do whatever it is 22% more efficiently.&lt;br /&gt;&lt;br /&gt;If I add up all these 22% more efficiencies in every area of my life, I somehow don't see myself as 22% better off.  Lots of things seem kind of cool in isolation, and I wouldn't mind being able to use them.  But there's some kind of deeper "why" question I don't really see being addressed in the formative studies.  Maybe it comes down to an ROI analysis: just because something is more efficient doesn't mean it's worth your time to switch to it: consider the costs versus benefits of switching the world from QWERTY to Dvorak.  Dvorak is probably slightly more efficient, but the amount of campaigning it would take to change this, would be better spent campaigning for something else.&lt;br /&gt;&lt;br /&gt;So, when studying people doing stuff with an eye towards making that stuff easier, there ought to be a rule of thumb you can apply to find out when to drop  the whole thing and say "this person is actually doing OK; they don't really need something new".  I don't know what that rule might be; it would have to be pretty subtle.  The most comically inappropriate example was the guy presenting on Monday who was &lt;a href="http://www.chi2009.org/altchisystem/login.php?action=showsubmission&amp;id=225&amp;"&gt;studying love&lt;/a&gt; with the idea of how a device might "improve" it.  Sometimes people miss each other: this emotion serves a purpose, and it's not at all clear to me that we would be better off if we had technological gimmicks to trick ourselves out of it. &lt;br /&gt;&lt;br /&gt;That's obviously a more extreme example than someone trying to help you search for restaurant reviews faster, or keep "to-do" notes all in one place, but maybe there's some ineffable factor in all of these things that's being missed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4901673779047345905?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4901673779047345905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4901673779047345905&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4901673779047345905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4901673779047345905'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/04/chi2009-day-3' title='chi2009 -- day 3'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5841771591037648495</id><published>2009-04-07T20:52:00.001-07:00</published><updated>2009-04-07T21:51:24.369-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chi2009 thanatosensitivity'/><title type='text'>chi2009 -- day 2</title><content type='html'>Some interesting stuff at CHI today:&lt;br /&gt;&lt;br /&gt;- "Difficulties in establishing common ground in multiparty groups using machine translation": Naomi Yamashita talked about a study where they had a Chinese speaker, and Korean speaker, and a Japanese speaker all working together on a task over machine-translated instant messaging.  Apparently this kind of works with two languages, but it's a disaster with three.  She did detailed analysis of their chat logs to figure out where things went wrong: because you can't see the translation flaws between the other two speakers, you don't have enough information to understand why they make the adjustments they do in trying to communicate.  So things spin out of control.  They had some elaborate suggestions for fixing this, by loading up everyone with more information.  I didn't really care for their solutions; I think doing three-way translations probably requires a specialized translation engine that maps words consistently among the three languages, even at the cost of some inaccuracy.  I bet people could adapt better to some translation weirdness if it least everything was consistent and predictable.&lt;br /&gt;&lt;br /&gt;- "Spectator Understanding of Error in Performance": this was a poster in the poster room, and I chatted with one of the authors.  They had a psychological theory about how people interpret mistakes in musical performances, especially for unfamiliar kinds of music: did the musician hit the wrong note, or did the listener misunderstand what the musician was trying to do?  The guy kindly engaged me in philosophical musing about it as I tried to think how it might relate to a programmer's perception of program errors when debugging.&lt;br /&gt;&lt;br /&gt;- "Resilience through technology adoption: merging the old and the new in Iraq": Gloria Mark talked about internet, cell phone, and satellite TV use in Iraq.  Fascinating stuff, but the biggest takeaway for me was this: bring a printout of your slides, so if the projectors or computers go horribly, horribly awry, you can give your talk without a computer in front of you.  I gather that an Iraqi would have known that!&lt;br /&gt;&lt;br /&gt;- Another poster by Anja Austerman, and Seiji Yamada: It was a very clever study about how people try to train robots.  They gave people the task of training a robot.  But the robot in fact already knew the task, and was programmed to behave or misbehave at certain times, in order to collect data about how the people tried to train it.  Her idea was that a robot for the home might go through a pre-training phase like this, to learn its owners training styles; then later they could train it to do real tasks in a way that felt natural to them.&lt;br /&gt;&lt;br /&gt;- alt.chi is a set of sessions with stuff that doesn't get accepted into the regular conference.  So the talks are a little weird or speculative.  There was one about how computers can help "improve love"; one on "thanatosensitivity" in design (product designers should plan for the death of the user and how the family is going to deal with the deceased's online identity, cell phone contacts, etc); and a study about people who do medical research online before they go see their doctor.&lt;br /&gt;&lt;br /&gt;- Jet Townsend from CMU had a gizmo you can wear on your arm, that tells you where there are strong electromagnetic signals in the room around you.  I wish I had the skills to do hardware hacking like that.&lt;br /&gt;&lt;br /&gt;- Todd's been all a-twitter, and I've found out about cool stuff 2nd hand through him, like the MIT tour last night, and a Stockholm University shindig tonight, at which I met many cool people.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5841771591037648495?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5841771591037648495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5841771591037648495&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5841771591037648495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5841771591037648495'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/04/chi2009-day-2' title='chi2009 -- day 2'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-3120381586156273447</id><published>2009-04-06T20:35:00.000-07:00</published><updated>2009-04-06T21:23:09.657-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chi'/><title type='text'>CHI2009 -- day 1</title><content type='html'>I'm in Boston for &lt;a href="www.chi2009.org"&gt;CHI&lt;/a&gt;, a conference about human-computer interaction.  It's interesting, although some of the language in the talks is a little fluffy: lots of people doing research through design to explore a process of discovery that reveals empowering affordances. &lt;br /&gt;&lt;br /&gt;Some of the actual stuff people are coming up with is pretty cool though, so I don't meant to knock the work itself. These designers have a genuine interest in making technology work better for people, so they're trying new interface techniques all the time and reporting on how well they work for people.  For example I saw today some multi-touch pressure-sensitive mousepads, only with no mouse.  Simple idea but it works very nicely, and probably a lot cheaper than multi-touch sensitive screens.&lt;br /&gt;&lt;br /&gt;There are also some wacky muppet-labs kind of inventions, like the "crowdsourced haptic interface" where you let anonymous strangers give you backrubs over the internet.  I'm not sure what problem that solves, but I guess it was worth trying.&lt;br /&gt;&lt;br /&gt;After a reception tonight, some nice MIT grad students took a bunch of us over on a tour of the CSAIL building, where we saw roombas watering plants, Richard Stallman's office, discarded dusty robots lurking in corners, and we walked the whole length of an infinite hallway. CSAIL is housed in a Frank Gehry building, and all the plants died when they finally plugged up all the leaks that had been watering them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-3120381586156273447?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/3120381586156273447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=3120381586156273447&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3120381586156273447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3120381586156273447'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/04/chi2009-day-1' title='CHI2009 -- day 1'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-7562881817754554779</id><published>2009-03-25T17:17:00.000-07:00</published><updated>2009-03-25T18:10:54.545-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='syntonicity programming workflow monad'/><title type='text'>Syntonicity</title><content type='html'>I learned a new word today, "syntonicity".  Syntonicity is when you understand something by identifying with it, rather than understanding it purely abstractly. Here's a presentation by &lt;a href="http://www.comp.rgu.ac.uk/staff/sw/presentations/syntonicity.pdf"&gt;Stuart Watt talking about syntonicity&lt;/a&gt; in the context of programming language design.&lt;br /&gt;&lt;br /&gt;Beginners to programming (and, frankly, all of us sometimes) have problems stepping through a program in their heads to see if it will work. They remember their intent when they wrote the code, but they have trouble putting themselves in the computer's shoes and seeing the program through its eyes.  Watt claims that &lt;a href="http://www.pappert.org"&gt;Seymour Papert&lt;/a&gt; was trying to aid this kind of thinking when he invented the Logo language.  In most graphics languages, there's a set of coordinates on the screen, with (0,0) in the upper left corner, from the viewer's perspective.  In Logo, everything's done from a cursor's perspective (the "turtle") as it moves around the screen.&lt;br /&gt;&lt;br /&gt;Watt was involved in the creation of &lt;a href="http://projects.kmi.open.ac.uk/hank/index.htm"&gt;Hank&lt;/a&gt;, a specialized programming language for psychology students where information is shuffled around by a character named Fido. John Pane's language for children, &lt;a href="http://www.cs.cmu.edu/~pane/research.html"&gt;Hands&lt;/a&gt;, does very nearly the same thing, but actually draws a dog ("Handy") on the screen with a pack of cards in its paw.&lt;br /&gt;&lt;br /&gt;I don't know one way or the other if explicitly naming some part of your language or environment after an animal helps people think about programming the right way. But I can see where syntonicity could be a way of evaluating more subtle features about a language.  &lt;br /&gt;&lt;br /&gt;Consider for example the naming difference between &lt;a href="http://www.infoq.com/articles/pickering-fsharp-workflow"&gt;F#'s workflows&lt;/a&gt; and &lt;a href="http://www.haskell.org/haskellwiki/Monad"&gt;Haskell's monads&lt;/a&gt;. They're similar concepts: a way of kind of quoting some code, so you can later say "execute it in the following peculiar way".  The lines of the code are there, and you later say how information is passed from line to line.  "Workflow" isn't a perfect description of that, but it gives the impression that you're going to hand it over to the processor later, and say, "do this work".  "Monad" on the other hand is a mathematical term from &lt;a href="http://www.haskell.org/haskellwiki/Category_theory"&gt;category theory&lt;/a&gt;, that describes the mathematical relationship between the type signatures of the lines of code.&lt;br /&gt;&lt;br /&gt;"Workflow" leads you to identify with the good old blue-collar working function you're going to hand this thing off to to execute thing, while "Monad", if you're a category theoretician, leads you to think about the types underlying the code as interesting theoretical objects: how can they be twisted around and changed and reapplied in new ways?&lt;br /&gt;&lt;br /&gt;This fits nicely with the goals of F# and Haskell: the former is meant to be a practical programming language for scientific and financial programming, and the latter is primarily a research testbed and playground. &lt;br /&gt;&lt;br /&gt;So, I think the names for things do matter when designing a language.  If you choose names that sound like verbs, and those verbs have subjects that might be imagined to have a consistent point of view about your programming model, maybe it will help guide users into the right mindset for reasoning about your language the way you'd like them to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-7562881817754554779?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/7562881817754554779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=7562881817754554779&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7562881817754554779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7562881817754554779'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2009/03/syntonicity' title='Syntonicity'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-6417102475597501621</id><published>2008-12-10T10:22:00.000-08:00</published><updated>2008-12-10T11:07:51.125-08:00</updated><title type='text'>Java beginners: beware the black hole of "static"</title><content type='html'>I've just been grading a bunch of programming assignments from college sophomores taking their second term of Java, and I've noticed a dangerous pattern.&lt;br /&gt;&lt;br /&gt;Suppose you have a class like this in your project:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Foo {&lt;br /&gt;   private int state = 42;&lt;br /&gt;   void doStuff() { System.out.println(state); }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The right way to use the doStuff() method is like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Foo f = new Foo();&lt;br /&gt;f.doStuff();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But a common mistake is for people to try to access it like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Foo.doStuff();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The latter doesn't work, because it's the syntax for referring to a static method: that is, a method that belongs to the &lt;i&gt;class&lt;/i&gt; rather than to each particular object in the class.&lt;br /&gt;&lt;br /&gt;So, if you make that mistake, Eclipse gives you the option to &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;change modifier of doStuff() to static?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Don't do it!  Run away!  &lt;i&gt;That's not the right way to fix it.&lt;/i&gt;  In most cases, it means you forgot to create a Foo object.&lt;br /&gt;&lt;br /&gt;But suppose you take Eclipse's bad advice anyway. Then you get a new error, because now doStuff() can't see the integer state anymore.  What does Eclipse offer to do for you?  You guessed it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;change modifier of state to static?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you do that, then your program will &lt;i&gt;seem&lt;/i&gt; to work again.  But the meaning is very different, and as soon as you try to use multiple instances of this Foo object, your state variable will appear to do crazy things -- because it will be shared between all your Foo's.&lt;br /&gt;&lt;br /&gt;So beware of static.  If you have a method that refers to variables that aren't either passed in as arguments, or declared inside its brackets (like state, in this example), then it probably shouldn't be static.  &lt;br /&gt;&lt;br /&gt;As for making data items static, ask yourself this: think of some future modification of this program where you might need to have several different objects made from this class.  Do you want them all to have the same value for this variable?  If the answer is "no", then using static is bad form, even if it doesn't currently cause a problem.&lt;br /&gt;&lt;br /&gt;So do the extra work and eliminate "static" from your Java code if you've added it in "just to make it compile".  It'll be tedious to get it to compile again.  It might require you passing extra parameters to methods, or creating new object variables.  But take the time to figure it out. Learning this will give you the right intuitions, and will save you headaches later on in your programming career.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-6417102475597501621?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/6417102475597501621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=6417102475597501621&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/6417102475597501621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/6417102475597501621'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/12/java-beginners-beware-black-hole-of' title='Java beginners: beware the black hole of &quot;static&quot;'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-7782112655008216823</id><published>2008-10-31T07:55:00.000-07:00</published><updated>2008-10-31T08:00:03.319-07:00</updated><title type='text'>Learning from game designers</title><content type='html'>Here's a very readable presentation about how computer game designers&lt;br /&gt;manage to build in a more evenly-sloped learning curve than application designers&lt;br /&gt;do.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lostgarden.com/2008/10/princess-rescuing-application-slides.html"&gt;Princess-Rescuing Application&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-7782112655008216823?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/7782112655008216823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=7782112655008216823&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7782112655008216823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/7782112655008216823'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/10/learning-from-game-designers' title='Learning from game designers'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4032579146624171800</id><published>2008-08-13T12:40:00.001-07:00</published><updated>2008-08-13T12:40:54.866-07:00</updated><title type='text'>What kind of debugging should we be studying?</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;I really think, but just can't back this up, that a lot of the time when programmers are debugging, they're doing it on code that they're pretty familiar with. The research literature empirically studying people debugging, seems heavily biased towards comprehension and debugging of code that people are seeing for the first time.  This has got to be a methodological issue -- it's just so much easier to bring people into a lab and hand them code they haven't seen before.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Some people I've asked about this seem to disagree -- they think it's commonplace for programmers to be thrown into new unfamiliar code in their workplace and have to figure it out. Could be, but I still think they spend most of their time around familiar code, hour by hour. And that will judge their debugging tools by how well they work for them in familiar code.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This makes a big difference, because people who are debugging familiar code already have some understanding of how it works, and they're trying to compare the real code against the understanding in their head, to see where they, or it, are going wrong.  So it's kind of a scientific process, coming up with hypotheses and refuting them by testing them out, until they narrow down the exact point where the code goes astray from their notions about it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;People debugging unfamiliar code, on the other hand, are going to start with a comprehension phase where they go bottom up, looking at it and just trying to make sense of it. If academic research, and product development research, puts too much focus into understanding that particular situation, I think it will be giving short shrift to the later phases of code maintenance.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4032579146624171800?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4032579146624171800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4032579146624171800&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4032579146624171800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4032579146624171800'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/08/what-kind-of-debugging-should-we-be' title='What kind of debugging should we be studying?'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5387215373973245748</id><published>2008-07-15T12:10:00.000-07:00</published><updated>2008-07-15T12:12:14.185-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='ocaml'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><category scheme='http://www.blogger.com/atom/ns#' term='user study'/><title type='text'>Help with study of functional programmers</title><content type='html'>Are you currently developing or maintaining a medium to large-sized&lt;br /&gt;program written in a functional language, such as Haskell, F#, OCaml,&lt;br /&gt;or Lisp?  I'm doing a study of functional programmers, as part of&lt;br /&gt;a research internship at Microsoft, and I would like the opportunity to look over&lt;br /&gt;your shoulder while you do debugging or coding on your project.&lt;br /&gt;&lt;br /&gt;I'm looking for people with at least a year's experience doing&lt;br /&gt;functional programming, and who are currently working on a real&lt;br /&gt;project (i.e. for some purpose other than learning functional&lt;br /&gt;programming).  I'm only allowed to use people who can work in the US&lt;br /&gt;(because of the gratuity, which is taxable income). I'd simply come&lt;br /&gt;watch you work, and ask a few questions along the way. You'd do&lt;br /&gt;whatever you would normally be doing.  If you're near Seattle or&lt;br /&gt;Portland, I'd come to your office for a couple of hours.  If you're&lt;br /&gt;not near Seattle or Portland, then we'd set you up with LiveMeeting&lt;br /&gt;or some other remote screencast software so I can watch you from here.&lt;br /&gt;&lt;br /&gt;Obviously security concerns are an issue - I will not share any&lt;br /&gt;proprietary information that I learn about while visiting you. &lt;br /&gt;&lt;br /&gt;In exchange for your help, Microsoft will offer you your pick of free&lt;br /&gt;software off its gratuity list (which has about 50 items, including&lt;br /&gt;Visual Studio Professional, Word for Mac, XBOX 360 games) or any book&lt;br /&gt;from MS Press.&lt;br /&gt;&lt;br /&gt;We're doing this because expert functional programmers have not been&lt;br /&gt;studied much.  We plan to share our findings through academic&lt;br /&gt;publications, to help tool developers create debugging tools that are&lt;br /&gt;genuinely helpful in real-world settings.&lt;br /&gt;&lt;br /&gt;I'm hoping to finish my observations by August 8th, so please contact &lt;br /&gt;me immediately if you're interested!&lt;br /&gt;&lt;br /&gt;Thank you,&lt;br /&gt;&lt;br /&gt;Chris Bogart&lt;br /&gt;425-538-3562&lt;br /&gt;t-chribo@microsoft.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5387215373973245748?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5387215373973245748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5387215373973245748&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5387215373973245748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5387215373973245748'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/07/help-with-study-of-functional' title='Help with study of functional programmers'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5068149124398226938</id><published>2008-07-13T09:02:00.000-07:00</published><updated>2008-07-13T09:38:43.514-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='icfp contest'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><title type='text'>icfp contest update</title><content type='html'>Well, I got threads and tcp and everything all figured out, and my simple "spike" solution works the way I intended it: the rover makes a beeline for home base, ignoring craters, martians, and boulders, and usually dying or crashing.&lt;br /&gt;&lt;br /&gt;However I can't get it to run in Mono on the LiveCD environment for the contest.  I've been using Visual Studio on a virtual machine on my mac.  Visual Studio runs a little slow, but the program runs fine.  But when I try to run it in mono, I get a big wodge of error messages, none of them pertaining to my code.  I used some new features of F#, so it may be that it exercises some corners of mono that haven't been tested yet.&lt;br /&gt;&lt;br /&gt;I think at this point I'm going to give up on submitting a solution and just post interesting bits of my code here after the contest ends.  I still want to think some about a quick and dirty way of avoiding craters, but I probably won't spend much more time on it: it's nice out today!&lt;br /&gt;&lt;br /&gt;I feel like I've gotten what I wanted to out of this: building something significant in F#.  I have 238 lines of code, and I used F#'s Erlang-style mailboxes, asynchronous workflow, discriminated unions, class definitions, and I overcame the headaches of separating things into multiple modules while making sure all references went backwards.  I got threading and networking in a pretty clean way I think.  The ugliest part of the code is actually probably the navigation code, that looks at where the rover is and how fast it's going, and decides how to head for home base.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5068149124398226938?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5068149124398226938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5068149124398226938&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5068149124398226938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5068149124398226938'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/07/icfp-contest-update' title='icfp contest update'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4069294565797461577</id><published>2008-07-12T11:23:00.000-07:00</published><updated>2008-07-12T11:39:03.400-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monads'/><category scheme='http://www.blogger.com/atom/ns#' term='icfp contest'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><title type='text'>ICFP contest day 2</title><content type='html'>I spent a few hours programming last night, and I still don't have a running program yet.  F# turns out to have some pretty interesting monad-like things for handling asynchronous code (they're called "workflows") and this appears to be the right way to handle sending and receiving stuff from a TCP/IP connection.  &lt;br /&gt;&lt;br /&gt;I think I have a pretty good idea how to make this work, but I'm banging my head against the details: for example I want to asynchronously read a line of text from a socket, passing it along to the rest of my program as soon as a carriage return is received.  So, do I have to read one byte at a time in a tail-recursive function, adding to a mutable string?  Or is there an object or something in the library that will do this for me?  There's a tradeoff between searching and searching in the docs to find the most natural way of doing it in the language you're trying to learn, versus writing it from the ground up yourself, probably less efficiently, as a newbie.&lt;br /&gt;&lt;br /&gt;My problem may be that I need to sit down and read a book on .NET instead of thinking I can adhoccumulate expertise efficiently. &lt;br /&gt;&lt;br /&gt;By the way, I like Expert F# better than Foundations of F#.  I wish I'd read the former instead of the latter as preparation.&lt;br /&gt;&lt;br /&gt;Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4069294565797461577?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4069294565797461577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4069294565797461577&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4069294565797461577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4069294565797461577'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/07/icfp-contest-day-2' title='ICFP contest day 2'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4917299367089412626</id><published>2008-07-11T12:38:00.000-07:00</published><updated>2008-07-11T12:47:42.589-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='icfp'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><title type='text'>ICFP contest! Rovers on Mars!</title><content type='html'>The &lt;a href="http://www.icfpcontest.org/"&gt;2008 icfp contest&lt;/a&gt; just started!  Sadly I'm at work for another several hours, but I skimmed through the description, and hopefully the programmer-lobe of my brain is already hard at work on the problem while my researcher-lobe is busy dealing with participant recruitment for a study.&lt;br /&gt;&lt;br /&gt;This one is not all parsey like the last two years: it's all real-time execution and floating point numbers in a navigation problem.  It's not the kind of thing I've thought about much, so it should be an interesting challenge.  Also, my laptop plug *just* stopped working, so I may have to complete the entire task in 2 hours and 27 minutes.  Hopefully they have extras in Seattle somewhere.&lt;br /&gt;&lt;br /&gt;My plan this year is to do it in &lt;a href="http://research.microsoft.com/fsharp"&gt;F#&lt;/a&gt;, since it's cool and also I'm doing a study on it for my summer internship.  But they made it a little harder by not including F# in the list of supported languages.  But no worries -- they do have mono (the .NET clone, not the disease), so I'll just have to upload an executable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4917299367089412626?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4917299367089412626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4917299367089412626&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4917299367089412626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4917299367089412626'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2008/07/icfp-contest-rovers-on-mars' title='ICFP contest! Rovers on Mars!'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-736772960272037479</id><published>2007-10-10T07:46:00.000-07:00</published><updated>2007-10-16T11:10:05.295-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monads'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><category scheme='http://www.blogger.com/atom/ns#' term='precedence'/><category scheme='http://www.blogger.com/atom/ns#' term='beginner'/><title type='text'>5 Hints for Beginning Haskellers</title><content type='html'>Here are some things that have caused me headaches in learning Haskell.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Function calls. Functions are called by giving the name and the arguments separated by spaces. If a function f has two parameters, a and b, you call it with &lt;span style="font-weight: bold;"&gt;f a b&lt;/span&gt; not &lt;span style="font-weight: bold;"&gt;f(a,b).&lt;/span&gt;  The latter would be a one-argument function whose argument is a pair.  You can do things that way if you like, but it'll make things a lot trickier later.&lt;br /&gt;  &lt;/li&gt; &lt;li&gt;Precedence.  Those spaces in the function call syntax are about the tightest binding thing in the language.  So if &lt;span style="font-weight: bold;"&gt;distance&lt;/span&gt; is an integer, and &lt;span style="font-weight: bold;"&gt;show&lt;/span&gt; is an &lt;span style="font-weight: bold;"&gt;(Int -&gt; String)&lt;/span&gt;, then &lt;span style="font-weight: bold;"&gt;show distance++" miles"&lt;/span&gt; is good syntax, because &lt;span style="font-weight: bold;"&gt;show distance&lt;/span&gt; is evaluated before the &lt;span style="font-weight: bold;"&gt;++&lt;/span&gt;.  On the other hand, if &lt;span style="font-weight: bold;"&gt;c&lt;/span&gt; is a character and &lt;span style="font-weight: bold;"&gt;cs&lt;/span&gt; is a string, then &lt;span style="font-weight: bold;"&gt;length c:cs&lt;/span&gt; is a type error.  Haskell will try to evaluate &lt;span style="font-weight: bold;"&gt;length c&lt;/span&gt; first, then prefix that number to the front of the list &lt;span style="font-weight: bold;"&gt;cs&lt;/span&gt;.  Instead, you want &lt;span style="font-weight: bold;"&gt;length (c:cs)&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Parens in patterns. This is really an example of the precedence issue above, but it trips me up all the time.  You need more parens on the left hand side of function calls than you'd think. I don't know how many times I've written code like the sample below, leaving out the parens at first.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li style="font-weight: bold;"&gt;data Coord = Coord Int Int&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;manhattandist :: Coord -&gt; Int&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;manhattandist Coord x1 y1 = x1 + y1       &lt;span style="color: rgb(204, 0, 0);"&gt;WRONG&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;manhattandist (Coord x1 y1) = x1 + y1    &lt;span style="color: rgb(51, 204, 0);"&gt;RIGHT&lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/li&gt; &lt;/ul&gt;&lt;li&gt;Arrows in type declarations.  The type of &lt;span style="font-weight: bold;"&gt;(+)&lt;/span&gt; is &lt;span style="font-weight: bold;"&gt;Int -&gt; Int -&gt; Int&lt;/span&gt;; and we're supposed to accept that the first two Ints are the arguments, and the last Int is the return value. But turns out there's a cool reason for this. An equivalent type declaration would be &lt;span style="font-weight: bold;"&gt;Int -&gt; (Int -&gt; Int)&lt;/span&gt; (because -&gt; groups right). You can think about addition this way, and Haskell cooperates nicely: + is a function that takes one integer, and returns a function. So &lt;span style="font-weight: bold;"&gt;plus x y = x+y&lt;/span&gt; is equivalent to &lt;span style="font-weight: bold;"&gt;plus x = \y -&gt; x + y&lt;/span&gt; (search for lambda in the Haskell docs if you don't know that backslash syntax). So if you need a one-argument function (that returns a function) for some reason, it's OK to go ahead and define it as a two-argument function returning a number; Haskell doesn't make a distinction, and it's more convenient sometimes to express it that way.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Monads. These are famously hard to get. There are 10,000 tutorials out there, and most of them help a little. I'd recommend you start by learning to use the important standard ones, like Maybe, IO, and List, more or less by rote. Beyond that, if you're in a situation where you'd need to roll your own, I'd say just forget monads exist and write the code yourself. Once you get so you really understand the ugliness involved firsthand, monads will be an obvious benefit.  Anyway, that's my plan right now.  I think I get them well enough to explain them, but I make a lot of stupid mistakes when I try to use them, so I probably don't understand them as well as I think I do.  (More on this later -- I'm taking two classes right now that rely on Haskell, so I'll comment on this more as I have little insights).&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-736772960272037479?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/736772960272037479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=736772960272037479&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/736772960272037479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/736772960272037479'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/10/5-hints-for-beginning-haskellers' title='5 Hints for Beginning Haskellers'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-2502449258321728702</id><published>2007-09-07T12:31:00.001-07:00</published><updated>2007-09-07T12:40:54.169-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='parameters'/><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='array slicing'/><category scheme='http://www.blogger.com/atom/ns#' term='currying'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Types to distinguish parameters and dimensions</title><content type='html'>Suppose a language had a rule that said a function could only have one parameter of a given type, and each dimension of a multidimensional array had to be indexed by a different type.&lt;br /&gt;&lt;br /&gt;This would have several benefits:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; You'd get extra fine-grained checking; you couldn't possibly get parameters mixed up&lt;/li&gt;&lt;li&gt;When making array slices or currying, you wouldn't have to concern yourself with the ordering of the parameters.&lt;/li&gt;&lt;li&gt;You wouldn't need to distinguish between optional named parameters and ordinal parameters.  The name of a parameter would be (or would be derived from) it's type.&lt;/li&gt;&lt;/ol&gt;With functions like + that seem to require two items of the same type, you could interpret the two (or more) arguments as a collection.  Lists certainly could contain homogeneously typed members.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-2502449258321728702?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/2502449258321728702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=2502449258321728702&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2502449258321728702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2502449258321728702'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/09/types-to-distinguish-parameters-and' title='Types to distinguish parameters and dimensions'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5547561913310151376</id><published>2007-07-23T11:52:00.000-07:00</published><updated>2007-07-23T12:20:38.779-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='icfp'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python to the rescue: ICFP contest 2007</title><content type='html'>The &lt;a href="http://www.icfpcontest.org/"&gt;ICFP contest&lt;/a&gt; was great fun this year, as usual, and I actually arranged travel and moving plans so that I would be in one place for the weekend to work on it.&lt;br /&gt;&lt;br /&gt;I resolved to work in Scala this year, because it seemed like a practical functional language I'd like to know better; and it allows imperative programming with the java libraries, so I thought it would be a smooth learning curve.&lt;br /&gt;&lt;br /&gt;Well, I spent the first day butting my head up against Scala, and dealing with condo repair contractors and a fussy HOA board in the meantime: at the end of the day I had basically no running code and a splitting headache.  The cure: beer and python.&lt;br /&gt;&lt;br /&gt;The second day I changed to Python, which I really haven't used *that* much, but it's easier to figure out how to do things.  I'm not sure why -- maybe it's a question of documentation, or maybe it's just that I don't get functional programming as well as I thought I did.&lt;br /&gt;&lt;br /&gt;In Python I managed to get an interpreter that basically worked, reading the DNA file and creating images using Tkinter.  I don't think it was ever flawless.  There was a self-test screen that I eventually got all "OK"s on, but I never did see these manual pages that people on the discussion list were talking about.&lt;br /&gt;&lt;br /&gt;The Python was still too slow to make further debugging feasible, so I rewrote it in C.  Got that working sometime Sunday, and it was faster, but it wasn't faster enough.  The real solution  needed to be linked lists to pointers to memory, so one wouldn't need to shuffle megabytes of DNA around -- but I had no mental energy to implement anything like that by that point.&lt;br /&gt;&lt;br /&gt;Lessons learned:&lt;br /&gt;   Either scala documentation needs work, or I just need to spend more time learning the paradigm&lt;br /&gt;   When the problem statement says that shifting byte strings around needs to be done in faster than linear time, that's an optimization I should think through up front, not "get to it later".  It made all my implementations useless.&lt;br /&gt;   Python is the best language I know of for expressing algorithms.  It isn't fast enough, though.  (although I wonder what if I tried the linked-list thing in python?  I may try that as an experiment)&lt;br /&gt;   &lt;br /&gt;There were some complaints on the discussion list by people saying that the up-front work was too hard, and that most people never got to the meat of the problem.  I totally disagree with that.  ICFP is all about making functional programming usable and efficient.  If, with current tools, we are forced into low-level bit-schlepping in C, it points to a deficiency with the most common tools of functional programming, or in the training of programmers.  The contest ought to be about illustrating that kind of issue in a fun way.&lt;br /&gt;&lt;br /&gt;Here's an interesting point: languages with higher-order kinds of functionality tend to abstract one away from the machine more; working with heavy integer "objects", for example, instead of raw machine integers as C does.  Is it possible to have a language where you can talk about bare metal, even registers and such, but do it in a higher-order abstract way when desired?  I guess C++ attempts to do this in some ways, but it's an extremely complex language.  Is there no better compromise?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5547561913310151376?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5547561913310151376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5547561913310151376&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5547561913310151376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5547561913310151376'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/07/python-to-rescue-icfp-contest-2007' title='Python to the rescue: ICFP contest 2007'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-736012310933564313</id><published>2007-06-03T16:46:00.001-07:00</published><updated>2007-06-03T21:49:45.041-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='end-user programming'/><category scheme='http://www.blogger.com/atom/ns#' term='oregon state university'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><category scheme='http://www.blogger.com/atom/ns#' term='HCI'/><title type='text'>Representin' in Oregon</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_bSZRfbZs5OE/RmNk6CBidKI/AAAAAAAAABY/XR5odHRhuqA/s1600-h/swc-jerriilookup.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_bSZRfbZs5OE/RmNk6CBidKI/AAAAAAAAABY/XR5odHRhuqA/s320/swc-jerriilookup.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5072008553487824034" /&gt;&lt;/a&gt;I haven't posted in a while, but I have good news -- I've been accepted into the PhD program at Oregon State University!  I first discovered the program by googling what turned out to be &lt;a href="http://eecs.oregonstate.edu/research/members/burnett/index.html"&gt;Margaret Burnett&lt;/a&gt;'s turn of phrase, "HCI of Programming".&lt;br /&gt;&lt;br /&gt;It's been 15 years since I got my master's at Colorado State.  Turning 40 last year, I've been thinking about where my life is headed and what I wanted to do next.  I've been doing very practical programming in the title industry in the daytime, and thinking and writing about programming languages at night.  &lt;a href="http://en.wikipedia.org/wiki/Strangers_With_Candy"&gt;So now I'm back in school, and although the faces have changed, the hassles are all the same&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Up until now I have thought more about the challenges of language design for professional programmers, but at OSU I'll be diving into the whole realm of &lt;a href="http://eusesconsortium.org/"&gt;end user software engineering&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;When designing a language for a professional programmer, maybe we can assume that the user knows what he or she is doing.  Programmers are expected to have an analytical mindset, and plenty of practice at debugging things.  They have endured years of indoctrination into the sacraments of testing, code correctness, documentation and version control.  They have fingernails that shine like justice.  They have RTFM.  It's safe to assume that they have this expertise.  It may not actually be true that they have it, but it's safe: our asses are covered, because we said on the box "professionals only".  &lt;br /&gt;&lt;br /&gt;An "end user" may in fact be a professional programmer, but we no longer have our asses covered; the environment must share in the responsibility.  There is an intelligent being sitting in front of us, who thinks in a very different way than the computer does.  They have some concept of what they want the computer to do, and we have to cooperate with them in representing that concept.  Without being making so many wrong assumptions, or so few right assumptions, that we annoy the user into walking away in frustration.&lt;br /&gt;&lt;br /&gt;When I was going through the application process, I went for advice to University of Colorado professor, &lt;a href="http://spot.colorado.edu/~clayton/"&gt;Clayton Lewis&lt;/a&gt;, who introduced me to the notion of Theory of Representation: that a lot of what's interesting in computing can be seen in terms of making valid mappings from one representation system to another.  In those terms, HCI is about mapping between formal and human representations.  But the human representation system is a pretty quirky thing that cognitive scientists are still attempting to explore; so HCI is kind of an engineering discipline working ahead of its time: trying to translate in and out of human representations before human representations can really be said to be understood by science.&lt;br /&gt;&lt;br /&gt;This process has got to be a two-way street, because human representations of programming solutions are invariably wrong to start with, at least at a sufficiently fine level of detail.  They need refinement, and the process of formal representation helps with that refinement.&lt;br /&gt;&lt;br /&gt;In HCI of programming there is more going on, however.  Engineering is not just a set of concepts, it's a discipline.  "Discipline" is a deep set of mental habits.  So to turn end users into software engineers, or to turn software engineers into &lt;span style="font-style:italic;"&gt;better&lt;/span&gt; software engineers, it seems to me that an ideal software engineering environment will do more than represent users' ideas; it will help teach the user the mental habits necessary to refine those ideas efficiently.  Maybe that goes beyond theory of representation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-736012310933564313?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/736012310933564313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=736012310933564313&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/736012310933564313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/736012310933564313'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/06/representin-in-oregon' title='Representin&apos; in Oregon'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_bSZRfbZs5OE/RmNk6CBidKI/AAAAAAAAABY/XR5odHRhuqA/s72-c/swc-jerriilookup.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-8568999431359596257</id><published>2007-05-19T21:18:00.000-07:00</published><updated>2007-06-03T21:51:39.178-07:00</updated><title type='text'>Bring to a boil: programming with cairns</title><content type='html'>I'd like to see more computer language instructions like the "bring to a boil" instruction you see in recipes.  "Bring to a boil" doesn't tell you to put the pot on the stove, or how you turn the burner on, or how long it takes to boil.  In fact, that may vary based on your altitude, the quality of your tap water, and the shape of your pot.&lt;br /&gt;&lt;br /&gt;"Bring to a boil" jumps ahead past a bunch of obvious steps.  It's not just like a subroutine call, encapsulating a handful of steps for brevity; it just describes the endpoint of a bunch of steps, and it's assumed you can find your way there yourself.&lt;br /&gt;&lt;br /&gt;Finding its way there itself is something computers &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; do.  Algorithms to traverse mazes are not &lt;span style="font-style: italic;"&gt;that&lt;/span&gt; tricky, and in some limited domain, figuring out how to accomplish some process could be likened to navigating through a maze.  In some limited domain where an algorithm can be generated to get from here to there, why not give programmers that for free?&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Cairn"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://2.bp.blogspot.com/_bSZRfbZs5OE/Rk_ff7CNXYI/AAAAAAAAABQ/iq0kRHNI5W4/s320/200px-Cairn_3.jpg" alt="Cairn" id="BLOGGER_PHOTO_ID_5066513845330992514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Presuming that automatic programming is hard in the general case, but easy in sufficiently constrained cases, then programmers should be able to set a series of cairns for the compiler to follow, each close enough to the last for automatic programming to find its way, but far enough apart to save having to type in a lot of tedious steps.&lt;br /&gt;&lt;br /&gt;The other nice thing about this kind of instruction is that it entails a test.  Often we write code that clanks along like an insane robot, following instructions without checking every so often to see that it's still on course.  "Bring to a boil" isn't the sort of instruction that can accidentally be followed when you're in the bedroom instead of the kitchen, blindly going through the motions of  turning on an imaginary stove while standing in front of the laundry hamper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-8568999431359596257?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/8568999431359596257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/8568999431359596257'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/05/bring-to-boil-programming-with-cairns' title='Bring to a boil: programming with cairns'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_bSZRfbZs5OE/Rk_ff7CNXYI/AAAAAAAAABQ/iq0kRHNI5W4/s72-c/200px-Cairn_3.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5561181830022728062</id><published>2007-03-25T10:35:00.000-07:00</published><updated>2007-03-25T11:27:12.069-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='center embedding'/><title type='text'>Hobbling scheme for readability?</title><content type='html'>There's a discussion going on over at &lt;a href="http://lambda-the-ultimate.org/node/1282"&gt;Lambda the Ultimate&lt;/a&gt; about the use of Scheme as a shell scripting language (&lt;a href="www.scsh.net"&gt;scsh&lt;/a&gt;).  As is typical in such discussions, the people accustomed to parentheses are saying that all the parentheses aren't so bad, while the people unaccustomed to them feel that traditional shell scripting is clearer.&lt;br /&gt;&lt;br /&gt;I gotta come down firmly on the no-parens side of this debate.  Lispy parentheses are an egregious example of &lt;a href="http://en.wikipedia.org/wiki/Center_embedding"&gt;center embedding&lt;/a&gt;, which are an impossible strain on short-term memory.  It's quite hard to write lisp code without help from an editor program that counts parentheses for you.  Lisp is optimized for machine parsing, but pessimized for human parsing.&lt;br /&gt;&lt;br /&gt;It would be interesting to see just what limits there are on programs you can write without center embedding.  Suppose you had a dialect of lisp in which the outermost expression did not need parentheses around it, a comma would close a single paren, a period would close multiple parens, and whenever there are two levels of paren, the ONLY way to close them would be with a period, which would end the outermost expression.  So something like this would be legal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a (b c, d (e f, (g  (h (i j.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and would look like this in traditional syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(a (b c) d (e f) (g (h (i j))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The point being that you could nest as deeply as you liked, but only at the end of the expression.  I don't know, it looks kind of ugly at first glance, but it parallels nicely English structures like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;This is the cat that ate the rat that lived in the house that Jack built.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you forced yourself to write in that style, and just defined variables to refer to when you couldn't find a way to structure things in this way, I wonder what the program would look like.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5561181830022728062?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5561181830022728062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5561181830022728062&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5561181830022728062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5561181830022728062'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/03/hobbling-scheme-for-readability' title='Hobbling scheme for readability?'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-8935082253557312078</id><published>2007-03-17T14:46:00.000-07:00</published><updated>2007-03-17T15:38:28.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ontology'/><category scheme='http://www.blogger.com/atom/ns#' term='relational model'/><category scheme='http://www.blogger.com/atom/ns#' term='databases'/><title type='text'>select * from universe where planet=earth</title><content type='html'>In &lt;a href="http://tenwaystosunday.blogspot.com/2004/10/always-bigger-scope.html"&gt;Ten Ways to Sunday&lt;/a&gt;, Nathan Allen discusses the fact that the powerful relational model you have for referring to data in a database, does not extend to entities outside the database, and he proposes that similar relational model should be available to refer to everything a computer has access to, with some way of explicitly narrowing the scope of this system for the context of a particular task.&lt;br /&gt;&lt;br /&gt;Referring to everything in the world with a consistent relational model is a conceptual nightmare, as Nathan hints at, and as you'll soon discover too if you peruse an upper-level ontology like &lt;a href="http://www.articulatesoftware.com/"&gt;SUMO&lt;/a&gt; or &lt;a href="http://www.cyc.com/"&gt;cyc&lt;/a&gt;, and contemplate relating some dataset that you work with into  one of these ontologies.  But I think something along these lines is going to end up bearing fruit in the long run.  Human communication always uses words with known meanings, linked into a shared cultural knowledge set.  Because of that, we can describe data, processes, and new ideas to each other without having to define terms nearly as often as we must when writing software or laying out databases.  Our data is implicitly embodied as part of society's larger body of knowledge.  Today's databases, on the other hand, are a bunch of arbitrary items whose interpretation is described by machine-unreadable documentation, and implicitly described by the the way software happens to be written to use it.&lt;br /&gt;&lt;br /&gt;While humans seem to share an implicit upper-level ontology, we don't actually know what it is, as evidenced by the difficulties and controversies surrounding the building of formal upper level ontologies.  If we can figure out why we can communicate so well with each other despite that, I think we'll have learned something important.  I suspect what's going on is that we have multiple ontologies for different kinds of ideas and objects, that are loosely and inconsistently interrelated. &lt;br /&gt;&lt;br /&gt;The inconsistency of our ontological landscape is evidenced by those weird questions we stay up late at night arguing about like "why is there a universe" or "does red look the same to you as it does to me" or "is there a God".  It's also where "religious" debates come from, by which I mean those debates where your position seems so obvious that you think the other guy must be being deliberately obtuse not to see what you see so clearly.&lt;br /&gt;&lt;br /&gt;Someday AIs in charge of personal data management will fritter away their spare CPU cycles arguing about whether postal codes should be intrinsic parts of addresses or derived data items by way of post office servers.  During the day, though, they'll warily agree to disagree and find a practical workaround.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-8935082253557312078?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/8935082253557312078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=8935082253557312078&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/8935082253557312078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/8935082253557312078'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/03/select-from-universe-where-planetearth' title='select * from universe where planet=earth'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-2530991859016145452</id><published>2007-02-25T14:44:00.000-08:00</published><updated>2007-02-25T16:04:37.264-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lojban'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><category scheme='http://www.blogger.com/atom/ns#' term='logic'/><title type='text'>Lojban</title><content type='html'>I just realized that although I chose a &lt;a href="http://www.lojban.org"&gt;Lojban&lt;/a&gt; name for this blog, I haven't written much about it.&lt;br /&gt;&lt;br /&gt;Lojban (and its predecessor/competitor Loglan) was conceived as a language that would fit more or less within the realm of human language universals, but that at the same time would be syntactically unambiguous, and its semantics would be "based on" predicate calculus.  If some version of the &lt;a href="http://en.wikipedia.org/wiki/Sapir-Whorf_hypothesis"&gt;Sapir-Whorf Hypothesis&lt;/a&gt; is true, then maybe learning a language based on predicate calculus would cause you to be a more logical thinker.&lt;br /&gt;&lt;br /&gt;The Lojban experiment has been a success in the sense that a complete, usable language was developed, and there are a community of speakers doing translations, original writing, and holding conversations in it.  I participated in the Lojban community in the mid 90s, and I found learning it to be an interesting mental exercise for several reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It required some distinctions that are not habitually made in English; for example there are 14 logical connectives to choose from, plus some non-logical connectives.  At first you find yourself drawing truth tables to figure these things out, but eventually they come more naturally as you use them enough.&lt;/li&gt;&lt;li&gt;Other things were easier than English.  As in Japanese, in Lojban you can often elide important words, with the hole being implicitly filled in with "whatever is obvious to both speakers".&lt;/li&gt;&lt;li&gt;There was an incredibly fun and productive word construction process, where you'd take these three-letter word bricks and glue them together to make compounds.  German's got nothing on Lojban.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The language is excessively rich in hundreds of little words that approximately fill the role of prepositions.  Some of these were thought up rather cavalierly for theoretical reasons or out of a sense of completeness, to fill out a pattern of similar words, so while their meaning was clear, it was not always clear when they would be useful.  Coming up with plausible usages and trying to nonchalantly work them into forum conversations was great fun.&lt;/li&gt;&lt;li&gt;There was also a composable vocabulary of short words made exclusively of vowels and glottal stops, called "attitudinals", representing emotions.  You could often get your point across by just expressing how you felt about it, and let the content be implied. &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Some of Lojban's downsides, that eventually led me away from spending time on the project:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;While Lojban borrowed some concepts from propositional logic to great benefit, in the end I don't think it would be fair to say Lojban was "based on" logic.  To me that would mean that language structures would be defined in terms of a simpler and pre-existing formal logic already known and understood by logicians.  As it was, we had endless arguments about how to correctly translate example sentences from Quine, like, say, "I want a sloop" in the case where there is not a particular sloop you have your eye on.   I think problems of this sort went pretty deep, and probably the language should have been designed from the ground up around a particular theory of meaning, right or wrong, rather than making up a grammar and arguing about what it meant later.&lt;/li&gt;&lt;li&gt;The community was fascinated with navel-gazing issues of this sort, which was highly addictive but not very fruitful in my opinion.  It was educational and thought provoking for me, but I did not have the formal logic/philosophy of language background to contribute as productively as I wished I could have.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;All that being said, I think Lojban has made an important gesture by exploring a wholly new point along the computer/human-language spectrum.  One lesson I'd like to see the programming language world learn from it, is that it the names we assign to things in programming languages are almost always completely arbitrary and unanalyzable.  What if something that the computer could actually dissect, akin Lojban's word-building system ("lujvo"), were mandatory for most variable/function/class names in a program?   In no human language do we invent most of the words used in a paragraph, and begin by defining them; we instead stretch existing vocabulary to meet our needs.  Perhaps that contributes to the error-pronity of software development in some way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-2530991859016145452?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/2530991859016145452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=2530991859016145452&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2530991859016145452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2530991859016145452'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/02/lojban' title='Lojban'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-3518333591087906268</id><published>2007-02-16T07:34:00.000-08:00</published><updated>2007-02-16T08:10:16.039-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AI'/><category scheme='http://www.blogger.com/atom/ns#' term='genetic algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><title type='text'>Evolution of AI</title><content type='html'>Grey Thumb brings our attention to this article: &lt;a href="http://www.greythumb.org/blog/index.php?/archives/180-Lee-Spector-on-evolution-and-AI.html"&gt;The Evolution of AI&lt;/a&gt;, published in Artificial Intelligence last year.&lt;br /&gt;&lt;br /&gt;The author accuses AI researchers of being crypto-creationists, for not putting more emphasis on evolutionary techniques in their research.  While I think the author is essentially right in saying that evolutionary techniques will play an important role in the research and development of artificial intelligence, it seems to me to be merely practical tool in that field, not a relevant object of study in that context.  What's interesting about AI is not the mere production of software that has intelligence-like features, but the deeper understanding this process can lead to: just what intelligence and consciousness really are, and how the human mind might work.&lt;br /&gt;&lt;br /&gt;The problem with evolutionary techniques is they often lead to &lt;a href="http://archive.bcs.org/BCS/Products/publishing/itnow/OnlineArchive/jan98/leadingedge.htm"&gt;designs we can't understand&lt;/a&gt;, or that, on analysis, turn out to work for strange, quirky reasons. &lt;br /&gt;&lt;br /&gt;I call that a "problem" only in that it doesn't naturally lead to a better understanding of a problem domain.  If you're trying to design a tone discriminator, as in the article above, or a better antenna, it's fantastic what genetic algorithms can do for you.  But in trying to understand intelligence, the project as a whole would be too large for a genetic algorithm to tackle and would lead to an unanalyzable mess.  I'm not making that statement without evidence -- look at what nature has given us: our brains took billions of years to evolve, and after thousands of years of trial, error, and science we still can't reliably tweak it to cure common problems like depression and schizophrenia. &lt;br /&gt;&lt;br /&gt;I'm sure as evolutionary techniques improve, people will use them to design components of intelligent systems, and analyze those designs to come up with theories about how they work.  In fact we'll probably do a lot more of that in a lot of fields.  But the only way I see evolutionary theory as being directly a part of the AI field is if it turns out that there are evolutionary processes going on within the human mind in real time -- a possibility the paper does not even discuss.&lt;br /&gt;&lt;br /&gt;In short, he's conflating a research technique with a field of study.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-3518333591087906268?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/3518333591087906268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=3518333591087906268&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3518333591087906268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/3518333591087906268'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/02/evolution-of-ai' title='Evolution of AI'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-9196289788262015277</id><published>2007-01-23T18:22:00.000-08:00</published><updated>2008-09-24T08:42:04.025-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='burrows-wheeler transform'/><title type='text'>Burrows-Wheeler Transform in Haskell</title><content type='html'>I got curious about program transformation techniques, and went looking to see what kind of work had been done on round-trip parsing: i.e. using the same grammar to turn a string into an abstract syntax tree, and then to turn it back into a string.&lt;br /&gt;&lt;br /&gt;Well, I got distracted by this very odd thing I found called the &lt;a href="http://en.wikipedia.org/wiki/Burrows-Wheeler%20Transform"&gt;Burrows-Wheeler transform&lt;/a&gt;.  It's a weird way of sorting a string that is reversible.   (And happens to be likely more easily compressed with something like run-length encoding, hence its use in compression programs such as bzip2).  Basically you sort the string, then replace each character with the one that used to appear to the left of it back in the original ordering (or an "end of string" marker for the character that came from the front of the string).&lt;br /&gt;&lt;br /&gt;Anyway, as an exercise I wrote an encoder and decoder in Haskell.  Here it is, for your amusement.  Feel free to use it if you want, but it's probably not very efficient.  I need to read up on when Haskell does and does not save results of function calls -- are they always memoized?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;module Bwt3 where&lt;br /&gt;import Ix&lt;br /&gt;import Data.List&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;-- For BWT we want to compare strings with the special&lt;br /&gt;-- rule that the end of string sorts as greater than any&lt;br /&gt;-- other character&lt;br /&gt;--&lt;br /&gt;compHighEol [] [] = EQ&lt;br /&gt;compHighEol lst1 [] = LT&lt;br /&gt;compHighEol [] lst2 = GT&lt;br /&gt;compHighEol (x:xs) (y:ys)&lt;br /&gt;    | x &gt; y    = GT&lt;br /&gt;    | x &lt; y    = LT&lt;br /&gt;    | x == y   = compHighEol xs ys&lt;br /&gt;    &lt;br /&gt;-- Datatype for rotated string; the string starts where the&lt;br /&gt;-- integer member says it does, and wraps around when it hits the&lt;br /&gt;-- end, conceptually&lt;br /&gt;-- This lets us store multiple rotations of the same string&lt;br /&gt;-- without using storage for each one; they all point to the same&lt;br /&gt;-- structure&lt;br /&gt;data Rotation = Rot Int [Char] deriving Eq&lt;br /&gt;instance Show Rotation where&lt;br /&gt;    show (Rot k l) = (drop k l) ++ ['@'] ++ (take k l)&lt;br /&gt;instance Ord Rotation where&lt;br /&gt;     compare (Rot a as) (Rot b bs) = compHighEol (drop a as) (drop b bs)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- List of all possible rotations of a string     &lt;br /&gt;allrots str = [ Rot i str | i &lt;- range(0, length str) ]&lt;br /&gt;&lt;br /&gt;-- The actual output of this algorithm is a string with a flag&lt;br /&gt;-- embedded in the middle of it, which can't be a character.  So&lt;br /&gt;-- we introduce a type for this purpose that&lt;br /&gt;-- allows for an EOF symbol.  Which by the way, sorts after&lt;br /&gt;-- all other characters, to help with decoding&lt;br /&gt;&lt;br /&gt;data FlaggedChar = FC Char | FC_EOF deriving Eq&lt;br /&gt;&lt;br /&gt;instance Show FlaggedChar where&lt;br /&gt;     show FC_EOF = "@"&lt;br /&gt;     show (FC x) = show x&lt;br /&gt;     &lt;br /&gt;instance Ord FlaggedChar where&lt;br /&gt;     compare FC_EOF FC_EOF = EQ &lt;br /&gt;     compare _ FC_EOF      = LT&lt;br /&gt;     compare FC_EOF _      = GT&lt;br /&gt;     compare (FC x) (FC y) = compare x y&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- BWT encoding: make all rotations, sort them, and take the last&lt;br /&gt;-- character of each.&lt;br /&gt;encode str = map lastchar (sort (allrots str))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- lastchar just pulls the last character out of the&lt;br /&gt;-- rotated string, or FC_EOF if that's the last item&lt;br /&gt;lastchar (Rot 0 xs) = FC_EOF&lt;br /&gt;lastchar (Rot ix xs) = FC (head (drop (ix-1) xs))&lt;br /&gt;&lt;br /&gt;-- The rest of this stuff is for decoding the [FlaggedChar]&lt;br /&gt;-- list we made above&lt;br /&gt;--------------------------&lt;br /&gt;&lt;br /&gt;-- Given a list (of anything), return a list of Ints&lt;br /&gt;-- showing where the elements of the list would end up&lt;br /&gt;-- if sorted.&lt;br /&gt;--&lt;br /&gt;-- We do that by tagging each element with an integer, sorting&lt;br /&gt;-- those tagged items, and&lt;br /&gt;-- collecting the tags afterwards to see where they ended up&lt;br /&gt;sortPermutation xs =&lt;br /&gt;   map snd ( sortBy compfst (zip xs [0..]))&lt;br /&gt;   where compfst x y = compare (fst x) (fst y)&lt;br /&gt;&lt;br /&gt;-- Turn that into a cycle by cycling through it once&lt;br /&gt;getCycle xs = &lt;br /&gt;    take (length xs) &lt;br /&gt;         ((iterate ((sortPermutation xs) !!) . fromInteger ) 0)&lt;br /&gt;&lt;br /&gt;-- apply the permutation to the encoded item&lt;br /&gt;-- and rotate the result so the end of string flag comes at the end&lt;br /&gt;applyCycle cycle encoded = &lt;br /&gt;    fCtoString $&lt;br /&gt;    tail $&lt;br /&gt;        dropWhile (/= FC_EOF) answer ++ takeWhile (/= FC_EOF) answer&lt;br /&gt;        where answer = map (encoded !!) cycle  -- Oops: fixed typo 9/2008&lt;br /&gt;&lt;br /&gt;fCtoString :: [FlaggedChar] -&gt; [Char]&lt;br /&gt;fCtoString [] = ""&lt;br /&gt;fCtoString ((FC c):cs) = [c] ++ (fCtoString cs)&lt;br /&gt;fCtoString ((FC_EOF):ds) = fCtoString ds -- ignore FS_EOF&lt;br /&gt;    &lt;br /&gt;-- Finally the decode function puts it all together&lt;br /&gt;decode xs = applyCycle (getCycle xs) xs&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-9196289788262015277?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/9196289788262015277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=9196289788262015277&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/9196289788262015277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/9196289788262015277'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/01/burrows-wheeler-transform-in-haskell' title='Burrows-Wheeler Transform in Haskell'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-2672055264234652672</id><published>2007-01-07T16:11:00.000-08:00</published><updated>2007-01-07T17:49:08.510-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='currying'/><category scheme='http://www.blogger.com/atom/ns#' term='program transformation'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Abstract Refactoring</title><content type='html'>This week I had a subroutine, let's call it Bedrock, whose functionality I needed to expand to handle a new situation.  I won't bore you with the details, but the short story is that it created and handled exceptions from an object, Fred, and now I needed the same thing done with a very similar object, Wilma, which has almost, but not quite, the same behavior.&lt;br /&gt;&lt;br /&gt;Of course, there's always this dilemma: is it clearer to just throw a little logic in the function to handle the two cases, something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sub bedrock(bool need_caveman) {&lt;br /&gt;  Caveperson c;&lt;br /&gt;  if (need_caveman) { c = new Fred(); }&lt;br /&gt;  else              { c = new Wilma(); }&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;    c.bang_on_rocks();&lt;br /&gt;   } catch (Exception e) {&lt;br /&gt;       if (need_caveman) { printf("Fred can't find a rock\n"); }&lt;br /&gt;       else              { c.call_betty(); }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;...or is it better to separate the whole thing into separate functions:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sub bedrock(bool need_caveman) {&lt;br /&gt;  if (need_caveman) { bedrock_fred(); }&lt;br /&gt;  else              { bedrock_wilma(); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub bedrock_fred() {&lt;br /&gt;  Caveperson c = new Fred();&lt;br /&gt;  try {&lt;br /&gt;     c.bang_on_rocks();&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;     printf("Fred can't find a rock");&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub bedrock_wilma() {&lt;br /&gt;  Caveperson c = new Wilma();&lt;br /&gt;  try {&lt;br /&gt;    c.bang_on_rocks();&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;    c.call_betty();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;(the latter case further invites us to make &lt;code&gt;bedrock()&lt;/code&gt; a virtual function in the superclass of Fred and Wilma so the dispatching function is handled more discreetly, but that's an optimization for another day).&lt;br /&gt;&lt;br /&gt;In my case, sitting there in my IDE, I wasn't sure which would be clearer.  I knew what needed to be done, but I couldn't quite visualize which way would be easier to read until I typed it out.  (I have to admit I'm not much of a flowcharty, UML-y kind of thinker; I have to type out code, or at least pseudocode, to see what it looks like, then refactor from there and draw diagrams after the fact.)&lt;br /&gt;&lt;br /&gt;The thing is, there's no functional difference between these two options, outside of some extremely trivial performance issues (the second one uses one more stack frame than the first -- whoop-de-doo).  Why do I have to decide at all?&lt;br /&gt;&lt;br /&gt;The first code example has the virtue of showing you clearly the relationship between Fred and Wilma -- where their needs differ, you have an explicit if statement.  Its flaw is that if you want to know just about Wilma, you have to read past the clutter of irrelevant stuff about Fred.  The second example obviously has the converse strength and weakness.&lt;br /&gt;&lt;br /&gt;I'd like my IDE or revision control system to know about this trade-off, and be able to display the underlying functionality in either manner.  Think of it as something like &lt;a href="http://en.wikipedia.org/wiki/Currying"&gt;currying&lt;/a&gt;.  Currying, if you're not familiar with it, is where you take a function with two arguments, fill in one of them, and treat that half-filled-in function call as a new function of just one parameter.  For example, "+" takes two arguments, as in 3+4 = 7.  If you curry it with a "3", you get a new function, "3+_", taking one argument and returning that number plus three.&lt;br /&gt;&lt;br /&gt;Now in my bedrock example, looking at the first function where I have everything all lumped together; suppose you curried it with the value &lt;code&gt;need_bedrock = true&lt;/code&gt;.  In two places you'd end up with:&lt;br /&gt;&lt;pre&gt;if (true) then { foo foo foo }&lt;br /&gt;else           { bar bar bar }&lt;br /&gt;&lt;/pre&gt;which a smart IDE ought to be able to display simply as:&lt;br /&gt;&lt;pre&gt;foo foo foo&lt;br /&gt;&lt;/pre&gt;Much clearer, no?&lt;br /&gt;&lt;br /&gt;In general, then, I'd like to have some kind of odd IDE modality that was like a debugger, in that I could play with variable values, but in which I could mutate the code to show what it would reduce to under current conditions.  If I can rule out somehow that Wilma isn't relevant to the bug I'm tracking down, then the code logic can be automatically simplified for me.&lt;br /&gt;&lt;br /&gt;What would be really cool would be if I could even edit the deWilmafied "curried" code, and it would be able to merge my changes back to the canonical codebase, just as changes to conflicting revisions in a source control system are merged.  That could get messy though, so much careful treading would be in order.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-2672055264234652672?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/2672055264234652672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=2672055264234652672&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2672055264234652672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/2672055264234652672'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2007/01/abstract-refactoring' title='Abstract Refactoring'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-1428456232489749205</id><published>2006-12-17T22:48:00.000-08:00</published><updated>2006-12-18T22:26:06.753-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='polynomials'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>Questions on Haskell Style (and Polynomials redux)</title><content type='html'>Someone posted, on the Haskell "Blow your Mind" page, a &lt;a href="http://www.haskell.org/haskellwiki/Blow_your_mind#Polynomials"&gt;much more concise&lt;/a&gt; implementation of Polynomials as Numbers than I managed to come up with.  There are a couple things I learned by comparing it with &lt;a href="http://sambangu.blogspot.com/2006/12/polynomials-as-numbers"&gt;my version&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use of &lt;code&gt;zipWith (+)&lt;/code&gt; instead of &lt;span style="font-family:courier new;"&gt;map (\v -&gt; (fst v + snd v)) zip&lt;/span&gt;; obviously I need to get to know the libraries better&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;zipWith'&lt;/code&gt; is introduced to zipWith two lists together, padding the shortest one with zeroes.   &lt;a href="http://www.comlab.ox.ac.uk/oucl/people/jeremy.gibbons.html"&gt;Jeremy Gibbons&lt;/a&gt; suggested the same thing, calling it &lt;code&gt;longzipwith&lt;/code&gt;, and this is parallel to what I did without the "with" in my &lt;code&gt;zipLong&lt;/code&gt; function.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;They had the same questions I did about what to do with the required &lt;code&gt;signum&lt;/code&gt; and &lt;code&gt;abs&lt;/code&gt; functions.  Mikael suggested in a comment that I should use the &lt;a href="http://darcs.haskell.org/numericprelude/docs/html/NumericPrelude.html"&gt;NumericPrelude&lt;/a&gt; library instead of the standard one, for a more sensible generic definition of a number.&lt;/li&gt;&lt;li&gt;Jeremy and Blow-your-mind both used one less line in their zip function definition than I did: they manage to define it without explicitly handling the case where both lists are null.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;And here are some questions I have -- please comment if you have any ideas!&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Blow-your-mind version uses &lt;code&gt;[a]&lt;/code&gt; instead of &lt;code&gt;Poly [a]&lt;/code&gt; as its polynomial type.  My feeling is that an explicit constructor and data type like &lt;code&gt;Poly&lt;/code&gt; is better, because a polynomial is not the most obvious way to interpret a list of numbers.  However, my functions ended up being a lot wordier, pulling that constructor on and off the list all the time.  What's the better style choice here?&lt;/li&gt;&lt;li&gt;The multiplication function has me scratching my head.  It seems terser, but less communicative to me.  If you're got more experience with functional programming than I do: is the Blow-your-mind version much more clear or efficient, and is it worth it?  Is mine only clearer to me because I'm not used to FP style yet?   Or maybe tight APL-like gnomishness is part of the point of the Blow-your-mind page.  (Here they are again if you don't want to follow all the links).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;My version:&lt;br /&gt;&lt;pre&gt;&gt; scalarPolyMult :: (Floating a) =&gt; a -&gt; Poly a -&gt; Poly a&lt;br /&gt;&gt; scalarPolyMult c (Poly rs) = Poly $ map (*c) rs&lt;br /&gt;&lt;br /&gt;&gt; multByUnknown (Poly rs) = Poly (0:rs)&lt;br /&gt;&lt;br /&gt;&gt; multPoly :: (Floating a) =&gt; (Poly a) -&gt; (Poly a) -&gt; (Poly a)&lt;br /&gt;&gt; multPoly (Poly []) cs = Poly []&lt;br /&gt;&gt; multPoly (Poly (b:bs)) cs =&lt;br /&gt;&gt;     addPoly&lt;br /&gt;&gt;         (scalarPolyMult b cs)&lt;br /&gt;&gt;         (multPoly (Poly bs) (multByUnknown cs))&lt;br /&gt;&lt;/pre&gt;Blow-your-mind version:&lt;br /&gt;&lt;pre&gt;  xs &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:."&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;*&lt;/span&gt;&lt;/a&gt; ys = &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:foldl1"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;foldl1&lt;/span&gt;&lt;/a&gt; &lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:."&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;+&lt;/span&gt;&lt;/a&gt;&lt;span style="color:black;"&gt;)&lt;/span&gt; &lt;span style="color:black;"&gt;(&lt;/span&gt;padZeros partialProducts&lt;span style="color:black;"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 153);"&gt;where&lt;/span&gt;&lt;br /&gt;  partialProducts = &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;map&lt;/span&gt;&lt;/a&gt; &lt;span style="color:black;"&gt;(&lt;/span&gt;\x &lt;span style="color: rgb(0, 0, 153);"&gt;-&gt;&lt;/span&gt; &lt;span style="color:black;"&gt;[&lt;/span&gt;x*y | y &lt;span style="color: rgb(0, 0, 153);"&gt;&lt;-&lt;/span&gt; ys&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:black;"&gt;)&lt;/span&gt; xs&lt;br /&gt;  padZeros = &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;map&lt;/span&gt;&lt;/a&gt; &lt;span style="color:black;"&gt;(&lt;/span&gt;\&lt;span style="color:black;"&gt;(&lt;/span&gt;z,zs&lt;span style="color:black;"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;-&gt;&lt;/span&gt; replicate z &lt;span style="color: rgb(0, 51, 0);"&gt;0&lt;/span&gt; &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:."&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;++&lt;/span&gt;&lt;/a&gt; zs&lt;span style="color:black;"&gt;)&lt;/span&gt; &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:."&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;.&lt;/span&gt;&lt;/a&gt; &lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:zip"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;zip&lt;/span&gt;&lt;/a&gt; &lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 51, 0);"&gt;0&lt;/span&gt;.&lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:."&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;.&lt;/span&gt;&lt;/a&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:black;"&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(102, 102, 102);"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-1428456232489749205?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/1428456232489749205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=1428456232489749205&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/1428456232489749205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/1428456232489749205'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/questions-on-haskell-style-and' title='Questions on Haskell Style (and Polynomials redux)'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-356071848839816250</id><published>2006-12-13T22:46:00.000-08:00</published><updated>2006-12-13T23:14:13.437-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='program transformation'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Automatic Spaghetti Refactoring</title><content type='html'>I wonder under what conditions it would be possible to take a working body of spaghetti code and automatically &lt;a href="http://www.refactoring.com/"&gt;refactor&lt;/a&gt; it to pull out all references to one specific resource, or some other definable subset of the program's activity.  Afterwards, your code would be as bad as before, or worse, in terms of organization, but it would at least be semantically equivalent.&lt;br /&gt;&lt;br /&gt;If you could do this quickly, on demand, you could present the object to a programmer in some kind of constrained editor for modification, then re-inline the changes back into the original structure of the code.  This would let a programmer pretend a design was nicely modular and object-oriented for the sake of conceptual simplicity in making a change, but without requiring the code to actually be organized at all.&lt;br /&gt;&lt;br /&gt;Why bother doing this?  It could be that the code is already organized according to some orthogonal concern that you don't want to mess up; or it's truly messy spaghetti code that you don't understand; or maybe more interestingly, it's represented internally as a dataflow graph or something, where there may be no linear or hierarchical structure to it by nature.&lt;br /&gt;&lt;br /&gt;I know refactoring gets done piecemeal by menu options in some IDE's, and I know something similar is done within compilers as optimization steps, for example &lt;a href="http://en.wikipedia.org/wiki/Inlining"&gt;inlining&lt;/a&gt;, and loop unrolling, but I haven't heard of large scale, temporary changes just for the purposes of presentation.&lt;br /&gt;&lt;br /&gt;The idea of making a transformation, applying a change, then reversing the transformation, puts me in mind of the notion of "conjugation" from group theory.  However I haven't gotten to that chapter yet in my Algebra book, so I don't really know if there are any monkeys in that tree.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-356071848839816250?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/356071848839816250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=356071848839816250&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/356071848839816250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/356071848839816250'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/automatic-spaghetti-refactoring' title='Automatic Spaghetti Refactoring'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4976090111544689702</id><published>2006-12-07T09:35:00.000-08:00</published><updated>2006-12-07T09:44:22.619-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DB2'/><category scheme='http://www.blogger.com/atom/ns#' term='anaphora'/><category scheme='http://www.blogger.com/atom/ns#' term='iSeries'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Awkward db2 SQL syntax</title><content type='html'>I'm continually frustrated by the awkwardness of SQL syntax in DB2 (I do database work on an IBM iSeries).  You can't do an update on a joined table; you can only update one table, so you have to do a subselect, typically expressing exactly the same subselect in two places in the same query.  See &lt;a href="http://weblogs.sqlteam.com/brettk/archive/2004/10/20/2243.aspx"&gt;Brett Kaiser's&lt;/a&gt; helpful example.  I keep shying away from doing them this way because it seems so wrong, but I keep coming back to it as my best alternative.  A language should not make you say the same complicated thing twice in once sentence.  &lt;a href="http://en.wikipedia.org/wiki/Anaphora_%28linguistics%29"&gt;Anaphora&lt;/a&gt; is your friend, IBM!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4976090111544689702?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4976090111544689702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4976090111544689702&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4976090111544689702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4976090111544689702'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/awkward-db2-sql-syntax' title='Awkward db2 SQL syntax'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-252634560149831512</id><published>2006-12-05T07:53:00.000-08:00</published><updated>2006-12-05T07:54:35.467-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>Simonyi on Comments in Algol-60</title><content type='html'>Check out this &lt;a href="http://www.datamuseum.dk/site_dk/20040213/cs/img0.html"&gt;fascinating slideshow&lt;/a&gt; by Charles Simonyi about how the language Algol-60 was originally used in practice -- as a language for comments.   He observes that good code comments can be a good source of ideas for new programming language constructs, since comments are where programmers express ideas that they feel can't currently be made clear or concise in the code itself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-252634560149831512?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/252634560149831512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=252634560149831512&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/252634560149831512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/252634560149831512'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/simonyi-on-comments-in-algol-60' title='Simonyi on Comments in Algol-60'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-5534759511169603263</id><published>2006-12-04T21:05:00.000-08:00</published><updated>2006-12-04T22:16:03.588-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zen'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='Eckhart Tolle'/><category scheme='http://www.blogger.com/atom/ns#' term='referential transparency'/><title type='text'>The Zen of Referential Transparency</title><content type='html'>Here's another interesting connection between Buddhist philosophy and math: &lt;a href="http://sequence.complete.org/node/234"&gt;this blog post by metaperl&lt;/a&gt; draws a connection between Haskell's lack of state variables, and Eckhard Tolle's belief that "the only thing that is real is the present moment."&lt;br /&gt;&lt;br /&gt;I'm not familiar with Tolle, but this is a part of Zen thinking as well.  You could choose to look at the past and future only as memories and projections that exist now, rather than as independent realities.  I'm not claiming to know something that arcane about the universe.   But it makes sense, using category theory as a metaphor, that you could choose to view the past and present and future as three real objects; or you could choose to look at the currently existing traces of the past, and currently existing precursors of the future as categorical arrows, and merely define the past and future in terms of those.&lt;br /&gt;&lt;br /&gt;A pure function will return the same value every time it is called with the same arguments; this is convenient because it makes them timeless in a sense.  If you define some function&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    f(x) = x+4,&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;you can say that f(2) = 6; and it's always true.  If f(2) gets called 10 times during a program's execution, you only have to really do the addition once; after that you know it as a timeless fact.  Even calculating it the once is bending to necessity; after all, it was already &lt;span style="font-style: italic;"&gt;true&lt;/span&gt; before we calculated it.&lt;br /&gt;&lt;br /&gt;But if we have some other function, g(), and we pass the result of f into it &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    g(x) = x * 7&lt;br /&gt;    print g(f(2))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well, g(6) = 42 no matter what, and g(f(2)) = 42 no matter what.  They're both universal timeless facts about this little system.  But in practice the computer has to calculate f(2) in order to know what to feed to g, so that g(f()) relationship works like time.  f is "before" g, even though they're both mathematically fixed, static, and unchanging.&lt;br /&gt;&lt;br /&gt;My feeble understanding of Zen is that one can learn, among other things, to experience time as an artificial construct of this sort, and not as something fundamental.  It's a pretty hard to nail down what's concretely different in this perspective, though, because it's probably isomorphic to the more conventional view of time as a mighty river, but supposedly there is a psychospiritual benefit to changing one's perspective in this way.&lt;br /&gt;&lt;br /&gt;Some links:&lt;br /&gt;&lt;a href="http://www.dogensangha.org.uk/PDF/reality.pdf"&gt;An article about Zen, Time, and Bohm's interpretation of quantum physics&lt;/a&gt;&lt;br /&gt;&lt;a href="http://sambangu.blogspot.com/2006/09/buddhism-and-category-theory.html"&gt;A prior post of mine on dependent origination and category theory&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-5534759511169603263?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/5534759511169603263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=5534759511169603263&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5534759511169603263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/5534759511169603263'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/zen-of-referential-transparency' title='The Zen of Referential Transparency'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-67011484981499964</id><published>2006-12-03T21:35:00.000-08:00</published><updated>2006-12-03T21:37:42.893-08:00</updated><title type='text'>Moving to new URL</title><content type='html'>Hi,&lt;br /&gt;&lt;br /&gt;I'm moving to &lt;a href="http://sambangu.blogspot.com"&gt;http://sambangu.blogspot.com&lt;/a&gt;.  Please update your feed!  I was doing an FTP upload from blogger.com to my ISP, but the comments never worked, and it just doesn't seem worth the trouble to do it that way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-67011484981499964?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/67011484981499964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=67011484981499964&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/67011484981499964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/67011484981499964'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/moving-to-new-url' title='Moving to new URL'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-4784589849197709838</id><published>2006-12-03T19:50:00.000-08:00</published><updated>2006-12-03T21:16:23.560-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell polynomials'/><title type='text'>Polynomials as numbers</title><content type='html'>So, I was trying to learn category theory, having gathered it was a good thing to know for people interested in programming language theory.  I kind of got bogged down though -- it's castles built on castles built on castles in the air, and I was losing track of reality in all the abstractions.  My book would talk about a category of Groups, for example, so I'd go looking up Groups in my faithful Wikipedia.  I'd get the concept, it's not that tricky in itself, but obviously understanding the definition of a group does not make one a group theorist.&lt;br /&gt;&lt;br /&gt;So, I finally declared "mission accomplished" brought the troops home to a ticker-tape parade, and started in on a group theory textbook instead (Knapp's Basic Algebra).  I'm enjoying it a lot more -- it starts up where I left off with math classes, so I don't feel like I'm a freshman in a senior-level class.&lt;br /&gt;&lt;br /&gt;Anyway, &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; book starts with a kind of review of polynomials, simultaneous equations, matrices, vector spaces, etc. that is stuff I've seen before, but with a more theoretical spin, that either was missing from my high school algebra or I've simply forgotten it.  The book points out that factoring integers into products of smaller integers, is very much like factoring polynomials into products of polynomials of smaller degree, and a prime number is like a polynomial you can't factor any further (like say x&lt;sup&gt;2&lt;/sup&gt;+9 = 0, when you're dealing with Reals).   Of course you can also add, subtract, multiply, and divide polynomials, and the result is always still a polynomial.  If a topologist can't tell a coffee cup from a doughnut, then a group theorist can't tell a polynomial from an integer.&lt;br /&gt;&lt;br /&gt;Well, maybe she can; obviously integers and polynomials have some different properties.  But I'm tickled enough with the idea that a polynomial is a kind of number, that I created a polynomial instance of Num in Literate Haskell as an exercise, reproduced below for your edification.&lt;br /&gt;&lt;br /&gt;Since I'm also still learning Haskell, I welcome any critiques you might have of my code.  I like the fact that the data structure I used (just a list of coefficients) turned out to make for short code; but it doesn't come out very readable.  The fact that prepending a 0 to a list multiplies the polynomial by X seems as cryptic as it is convenient.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; module Main where&lt;br /&gt;&gt; main = print testP&lt;br /&gt;&lt;br /&gt;I represent a polynomial as a list of its coefficients,&lt;br /&gt;with the constant first, then the X, the X^2, etc.  So&lt;br /&gt;3x^2 - 4 would be Poly [-4,0,3].&lt;br /&gt;&lt;br /&gt;&gt; data Floating a =&gt; Poly a = Poly [a] deriving (Eq)&lt;br /&gt;&lt;br /&gt;Now we evaluate by filling in the unknown.  Note that&lt;br /&gt;ax2 + bx + c evaluated at x is the same as&lt;br /&gt;(ax + b)x + c, so you can evaluate it by taking the constant&lt;br /&gt;term, popping it off the list, then multiplying x by the&lt;br /&gt;polynomial interpretation of the rest of the list.&lt;br /&gt;&lt;br /&gt;&gt; evalPoly :: (Floating a) =&gt; (Poly a) -&gt; a -&gt; a&lt;br /&gt;&gt; evalPoly (Poly []) x = 0&lt;br /&gt;&gt; evalPoly (Poly (c:cs)) x = c + x*(evalPoly (Poly cs) x)&lt;br /&gt;&lt;br /&gt;To add two polynomials, add corresponding coefficients.  If&lt;br /&gt;one is shorter than the other, you want to use zeroes.  I don't&lt;br /&gt;know how to do this beautifully with standard functions, because&lt;br /&gt;zip cuts off when the shortest list runs out.  So I defined&lt;br /&gt;a helper function zipLong, that keeps going till the longest&lt;br /&gt;list is done, filling in a default value.&lt;br /&gt;&lt;br /&gt;10 Points to whoever emails me with a shorter, cleaner,&lt;br /&gt;idiomatic way to do this.&lt;br /&gt;&lt;br /&gt;&gt; addPoly :: (Floating a) =&gt; (Poly a) -&gt; (Poly a) -&gt; (Poly a)&lt;br /&gt;&gt; addPoly (Poly r) (Poly s) = Poly $ map (\v -&gt; (fst v + snd v)) (zipLong r s 0)&lt;br /&gt;&lt;br /&gt;&gt; zipLong [] [] d = []&lt;br /&gt;&gt; zipLong (x:xs) [] d = (x,d):(zipLong xs [] d)&lt;br /&gt;&gt; zipLong [] (y:ys) d = (d,y):(zipLong [] ys d)&lt;br /&gt;&gt; zipLong (x:xs) (y:ys) d = (x,y):(zipLong xs ys d)&lt;br /&gt;&lt;br /&gt;Multiply a polynomial by a scalar.  I have a feeling this&lt;br /&gt;could be defined somehow under an instance of Num so that&lt;br /&gt;the * operator is automatically overloaded.  Not sure how.&lt;br /&gt;&lt;br /&gt;&gt; scalarPolyMult :: (Floating a) =&gt; a -&gt; Poly a -&gt; Poly a&lt;br /&gt;&gt; scalarPolyMult c (Poly rs) = Poly $ map (*c) rs&lt;br /&gt;&lt;br /&gt;Since (ax^2 + bx + c)x = ax^3 + bx^2 + cx,&lt;br /&gt;then Poly [c b a] * x = Poly [0 c b a]&lt;br /&gt;&lt;br /&gt;&gt; multByUnknown (Poly rs) = Poly (0:rs)&lt;br /&gt;&lt;br /&gt;To multiply two polynomials, P1 * P2, where P2 = (dx^2 + ex + f),&lt;br /&gt;rewrite as  f*P1 + P1*x*(dx + e); the first term is a scalar multiplication&lt;br /&gt;and the second has one less degree, so we can recurse on it.  The&lt;br /&gt;(Poly bs) term below is (dx + e) in this example.&lt;br /&gt;&lt;br /&gt;&gt; multPoly :: (Floating a) =&gt; (Poly a) -&gt; (Poly a) -&gt; (Poly a)&lt;br /&gt;&gt; multPoly (Poly []) cs = Poly []&lt;br /&gt;&gt; multPoly (Poly (b:bs)) cs =&lt;br /&gt;&gt;     addPoly&lt;br /&gt;&gt;         (scalarPolyMult b cs)&lt;br /&gt;&gt;         (multPoly (Poly bs) (multByUnknown cs))&lt;br /&gt;&lt;br /&gt;Define a polynomial as a number.  I'm cheating a little by&lt;br /&gt;picking a dumb definition of signum; really a polynomial&lt;br /&gt;with an unknown isn't positive or negative before a number&lt;br /&gt;is plugged into it, so I'm just defining it as the sign of&lt;br /&gt;the constant term.&lt;br /&gt;&lt;br /&gt;&gt; instance (Floating a) =&gt; Num (Poly a) where&lt;br /&gt;&gt;     s + t  = addPoly s t&lt;br /&gt;&gt;     negate (Poly cs) = Poly $ map (\q -&gt; -q) cs&lt;br /&gt;&gt;     s * t = multPoly s t&lt;br /&gt;&gt;     abs s&lt;br /&gt;&gt;        | signum s == -1   = negate s&lt;br /&gt;&gt;        | signum s /= -1   = s&lt;br /&gt;&gt;     signum (Poly [])  = Poly []&lt;br /&gt;&gt;     signum (Poly (c:cs)) = Poly [signum c]&lt;br /&gt;&gt;     fromInteger i = Poly [fromInteger i]&lt;br /&gt;&lt;br /&gt;And define a cheesy way to print out a polynomial&lt;br /&gt;&lt;br /&gt;&gt; instance Floating a =&gt; Show (Poly a) where&lt;br /&gt;&gt;     show (Poly [])     = "null"&lt;br /&gt;&gt;     show (Poly cs)     = concatMap&lt;br /&gt;&gt;          (\c -&gt; " + " ++ (show (fst c)) ++ "X^" ++ (show (snd c)))&lt;br /&gt;&gt;          (reverse (zip  cs  [0..length(cs)-1] ))&lt;br /&gt; &lt;br /&gt;Define some examples and some tests. &lt;br /&gt;&lt;br /&gt;&gt; p = Poly [2,0,1,2] -- 2x^3 + x + 2&lt;br /&gt;&gt; q = Poly [0,0,0,3,4]   -- 4x^4 + 3x^3&lt;br /&gt;&lt;br /&gt;&gt; testP = (p * q == Poly [0,0,0,6,8,3,10,8]) &amp;&amp;amp;&lt;br /&gt;&gt;         (p + q == Poly [2,0,1,5,4]) &amp;&amp;amp;&lt;br /&gt;&gt;         (evalPoly p 3 == 65.0 ) &amp;&amp;amp;&lt;br /&gt;&gt;         (3 * p == Poly [6,0,3,6]) &amp;&amp;amp;&lt;br /&gt;&gt;         (show p == " + 2.0X^3 + 1.0X^2 + 0.0X^1 + 2.0X^0")&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-4784589849197709838?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/4784589849197709838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=4784589849197709838&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4784589849197709838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/4784589849197709838'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/12/polynomials-as-numbers' title='Polynomials as numbers'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-6982253509869146113</id><published>2006-11-17T14:19:00.000-08:00</published><updated>2006-11-17T14:24:32.027-08:00</updated><title type='text'>SOAP: follow-up</title><content type='html'>Here's a &lt;a href="http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/"&gt;fantastic dialog&lt;/a&gt; that exactly captures my experiences with SOAP.  (via &lt;a href="http://anarchaia.org/"&gt;Anarchaia&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-6982253509869146113?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/6982253509869146113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=6982253509869146113&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/6982253509869146113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/6982253509869146113'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/11/soap-follow-up' title='SOAP: follow-up'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-116183851293766794</id><published>2006-10-25T21:52:00.000-07:00</published><updated>2006-10-25T21:55:12.950-07:00</updated><title type='text'>Follow up on kanji coding method: Wuji</title><content type='html'>Turns out there is a &lt;a href="http://en.wikipedia.org/wiki/Five_Stroke_method"&gt;character input method&lt;/a&gt; like the one I described in my &lt;a href="http://www.quetzal.com/sambangu/2006/08/keystroke-coding-system-for-kanji.html"&gt;previous post&lt;/a&gt;.&lt;br /&gt;  Sounds like it turns out to be kind of awkward to use.  Ah well...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-116183851293766794?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/116183851293766794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=116183851293766794&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116183851293766794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116183851293766794'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/10/follow-up-on-kanji-coding-method-wuji.html' title='Follow up on kanji coding method: Wuji'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-116093328140756650</id><published>2006-10-15T09:45:00.000-07:00</published><updated>2006-10-15T10:35:34.400-07:00</updated><title type='text'>Ban the dangling else!</title><content type='html'>I was just reading through Niklaus Wirth's paper, &lt;a href="http://www.cs.inf.ethz.ch/%7Ewirth/Articles/GoodIdeas_origFig.pdf"&gt;"Good Ideas, Through the Looking Glass"&lt;/a&gt; (found through &lt;a href="http://lambda-the-ultimate.org/node/1773"&gt;Lambda the Ultimate&lt;/a&gt;, of course!) where he talks about the &lt;a href="http://en.wikipedia.org/wiki/Dangling_else"&gt;Dangling Else&lt;/a&gt; problem.&lt;br /&gt;&lt;br /&gt;Some programming languages have statements of the form:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;code&gt;if X then Y&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;and&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;code&gt;if X then Y else Z&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;with no &lt;code&gt;end&lt;/code&gt; keyword or bracket, leading to the problem of how to interpret:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote&gt;&lt;code style="font-weight: bold;"&gt;if&lt;/code&gt; it's Saturday &lt;code style="font-weight: bold;"&gt;then if&lt;/code&gt; it's sunny &lt;code style="font-weight: bold;"&gt;then&lt;/code&gt; have a picnic &lt;code style="font-weight: bold;"&gt;else&lt;/code&gt; see a movie&lt;br /&gt;&lt;/blockquote&gt;Do we see a movie if it's not Saturday, or if it is Saturday, but it's cloudy?&lt;br /&gt;&lt;br /&gt;Natural languages have exactly the same sort of problem (example from the &lt;i&gt;AP Press Guide to News Writing&lt;/i&gt;, quoted in &lt;a href="http://itre.cis.upenn.edu/%7Emyl/languagelog/archives/001174.html"&gt;Language Log&lt;/a&gt;):&lt;br /&gt;&lt;blockquote&gt;We spent most of our time sitting on the back porch watching the   cows playing Scrabble and reading.&lt;br /&gt;&lt;/blockquote&gt;It reads funny in English, but we resolve it easily because we know the context.   Obviously context is not as helpful for a compiler.&lt;br /&gt;&lt;br /&gt;How does Language Log suggest fixing that problem in English?  They give two suggestions:&lt;br /&gt;&lt;blockquote&gt;We spent most of our time sitting on the back porch watching the   cows, playing Scrabble and reading.  &lt;/blockquote&gt;or&lt;br /&gt;&lt;blockquote&gt;Playing Scrabble and reading, we spent most of our time sitting on   the back porch watching the cows.  &lt;/blockquote&gt;The first suggestion corresponds approximately to Wirth's preference for an &lt;code&gt;end&lt;/code&gt; keyword; the comma signals a break of some kind, and the obvious interpretation is that the cows and the scrabble shouldn't be too closely associated.  It's not nearly so rigorous as &lt;code&gt;end&lt;/code&gt;, of course.&lt;br /&gt;&lt;br /&gt;The other suggestion is a bit more interesting; they rework the entire ordering of the sentence.  Although the two examples aren't really parallel, it does suggest another way to rework our if-then-if-then-else, if we intend the final else to correspond to the &lt;span style="font-style: italic;"&gt;first&lt;/span&gt; if-then:&lt;br /&gt;&lt;br /&gt;&lt;code style="font-weight: bold;"&gt;if&lt;/code&gt; it's not Saturday &lt;code style="font-weight: bold;"&gt;then&lt;/code&gt; see a movie &lt;code style="font-weight: bold;"&gt;else if&lt;/code&gt; it's sunny &lt;code style="font-weight: bold;"&gt;then&lt;/code&gt; have a picnic.&lt;br /&gt;&lt;br /&gt;In other words, we're punting -- not solving the original ambiguity but wording around to avoid the issue.&lt;br /&gt;&lt;br /&gt;I think that's actually a better strategy from a human reader's standpoint.  We do not have much in the way of "closing braces" in natural language: they tend to lead to &lt;a href="http://en.wikipedia.org/wiki/Center_embedding"&gt;center embedding&lt;/a&gt; issues which our brains just aren't equipped to deal with.  So maybe a good policy would be for a compiler to simply disallow the "if-then-if-then-else" construction with either interpretation, and force the user to rework their logic a little.  Such a restriction looks like an ugly hack to a computer scientist, but I think its necessary if we take seriously the idea that programs should be human languages as well as computer languages.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a href="http://en.wikipedia.org/wiki/language" rel="tag"&gt;language&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Programming+Languages" rel="tag"&gt;Programming Languages&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/HCI" rel="tag"&gt;HCI&lt;/a&gt;, &lt;a href="http://technorati.com/tag/dangling+modifiers" rel="tag"&gt;dangling modifiers&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-116093328140756650?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/116093328140756650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=116093328140756650&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116093328140756650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116093328140756650'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/10/ban-dangling-else.html' title='Ban the dangling else!'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-116036535688416736</id><published>2006-10-08T20:37:00.000-07:00</published><updated>2006-10-08T20:48:56.720-07:00</updated><title type='text'>Metalanguage for Software Development</title><content type='html'>Every software developer uses a variety of languages to develop a program.  It may seem like you're developing something purely in Perl or Java or VB or whatever, in fact you're using a lot of mini-languages to manage the development process:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;   Shell: if you're using a command line, you have to know shell commands for managing files and directories, invoking the compiler, etc.&lt;/li&gt;&lt;li&gt;   IDE: On the other hand if you're using an IDE, you could kind of consider it language-like; you invoke series of drop down menus and click options on and off&lt;/li&gt;&lt;li&gt;   source control: whether it's IDE-based or command-line based, you're describing and querying a specialized model encompassing time, files, directories, versions, and maybe different user identities&lt;/li&gt;&lt;li&gt;   deployment: you use FTP commands, or something equivalent, to put files on a server, configure the server to run your programs at the appropriate time, etc.&lt;/li&gt;&lt;li&gt;   building and linking: Like makefiles or visual studio "projects"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;   profiling: turning a profiler on or off, configuring it, and interpreting its output, is a language-like interaction&lt;/li&gt;&lt;li&gt;   debugging: another model of the program, where you communicate with the debugger about variable values and code structures&lt;/li&gt;&lt;li&gt;   SQL: typically any interaction with a database within your program, is done from within a walled-off sublanguage; maybe SQL built into strings, or maybe a specialized, but usually somewhat awkward, object or function call model.&lt;/li&gt;&lt;li&gt;   Database configuration: setting up tables and so forth is often done with a combination of SQL or database management configuration IDE manipulation&lt;/li&gt;&lt;/ul&gt;   When programmers think about the development process, we have an integrated mental model of all these aspects of the process, and from that figure out how to use them all together to do what needs to be done.  It would be interesting to have a single, consistent meta-language for software development that encompassed all these tasks.&lt;br /&gt;&lt;br /&gt;The closest thing we have to that, I think, is the command-line shell.  The simpler "languages", such as the compiler settings language, are encapuslated as command-line arguments, so technically from the same prompt you are doing diverse tasks like compiling your program or renaming files.  But useful as it is, it's kind of a gimmick.  You can't easily pull together information from, say, the profiler, the debugger, and some unit test results, and ask questions that cut across these different domains.&lt;br /&gt;&lt;br /&gt;For example, suppose you made a change to a procedure last week, and now you think it may be running too slow on a particular dataset.  A test of that is easy to express in English: run the current version of the procedure X against dataset Y and note how long it takes; also run X against Y using the version of X that was current last Thursday.  Implementing it would take a little work; we'd have to check out two versions, compile them in separate directories, run them both under a profiler, and know how to interpret the profiler results.  Speaking for myself, I'd probably make a mistake the first time through -- I'd check out the wrong version of the code, or run the compiler with different optimization flags or something.&lt;br /&gt;&lt;br /&gt;There oughtta be a language that has standard terminology for all these sorts of tools, and some easy way to build little modules onto the front end of a tool, that translates this language into the tool's configuration settings, and translates its results or error messages back into the language.&lt;br /&gt;&lt;br /&gt;The trick is you'd have to have a pretty smart front end that could pull apart commands or queries that involved multiple tools and figure out what commands to pass along to the individual tools; then integrate the results it gets back.  This would not be a trivial problem, but it would be a good start just to make this kind of task *expressible*, and require a lot of user guidance at first.&lt;br /&gt;&lt;br /&gt;Tag: &lt;a href="http://www.technorati.com/tags/programminglanguages" rel="tag"&gt;ProgrammingLanguages&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-116036535688416736?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/116036535688416736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=116036535688416736&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116036535688416736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/116036535688416736'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/10/metalanguage-for-software-development.html' title='Metalanguage for Software Development'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115767378335242531</id><published>2006-09-07T16:43:00.000-07:00</published><updated>2006-09-07T17:03:03.366-07:00</updated><title type='text'>Buddhism and Category Theory</title><content type='html'>In my previous post today I mused about using standard ontologies in programs as a way of grounding the web of connections between your objects in a framework of common terminology. &lt;br /&gt;&lt;br /&gt;There is a concept in Buddhist metaphysics called &lt;a href="http://en.wikipedia.org/wiki/Dependent_origination" rel="tag"&gt;Dependent Origination&lt;/a&gt;, which states that nothing exists on its own, but only manifests itself through its connections with everything else in its environment.  One illustration of the concept is &lt;a href="http://en.wikipedia.org/wiki/Indra%27s_Net"&gt;Indra's Net&lt;/a&gt;, an infinite spider web with little silver balls at all the junctions, each reflecting all the others in a way that would gum up any &lt;a href="http://en.wikipedia.org/wiki/Ray_tracer"&gt;ray tracer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A program that doesn't refer to much of anything external to itself is like that -- you can define data structures and pointers and files that all point to each other, but it's all meaningless without the interpretation that a programmer or user gives to it in the data they feed to it and their interpretation of its output.&lt;br /&gt;&lt;br /&gt;I'd say that &lt;a href="http://en.wikipedia.org/wiki/Category_theory" rel="tag"&gt;Category Theory&lt;/a&gt; is a mathematical restatement of Dependent Origination.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a href="http://www.technorati.com/tags/categorytheory" rel="tag"&gt;CategoryTheory&lt;/a&gt;, &lt;a href="http://www.technorati.com/tags/dependentorigination" rel="tag"&gt;DependentOrigination&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115767378335242531?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115767378335242531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115767378335242531&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115767378335242531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115767378335242531'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/09/buddhism-and-category-theory.html' title='Buddhism and Category Theory'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115767200353979504</id><published>2006-09-07T15:13:00.000-07:00</published><updated>2006-09-07T16:42:30.403-07:00</updated><title type='text'>Organizing programs by their invariants</title><content type='html'>It seems to me that natural langauge program specifications tend to consist of a lot of statements which are all independently true, and only dependent on context for &lt;a href="http://en.wikipedia.org/wiki/Deixis"&gt;deictic&lt;/a&gt; references (i.e. pronouns and pronoun-like references to concepts in surrounding sentences).  In other words, I'd claim, you could make sense of a good proportion of a scrambled specification if:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sentences remained intact&lt;/li&gt;&lt;li&gt;Deictic references were replaced by full references to global names of entities or processes&lt;/li&gt;&lt;/ul&gt;Now obviously, not everything in such a document will behave that way; for example an ordered list of steps will have their ordering and context lost.   But I think my claim is more true of an English-language spec, then, say, a large FORTRAN program.  If you have a spec you're working with closely, you might have sticky notes on different pages, and individual sentences highlighted, which you can turn to and refer to instantly without necessarily reading for context.    An old-skool not-very-modular FORTRAN program, on the other hand, is meant to be executed in one fell swoop.  A programmer might turn to a particular page of a printout and look for some information, but will require a lot more scanning around and reasoning to come up with an answer to their question about what's going on in the program.&lt;br /&gt;&lt;br /&gt;A Java program might fall somewhere in between English and Fortran in that regard -- Java tends to be written with lots of smallish functions, each of which might be comprehended on its own. &lt;br /&gt;&lt;br /&gt;Another reason a natural-language spec is easier to read in a random order, is that the words in an English sentence are more likely to be standard vocabulary not defined in the spec; and the ones that are defined in the spec are likely to be motivated* narrowings or metaphors of standard terminology.  In all the programming languages I'm familiar with, almost all the entities defined in a particular system can be freely named: a there may be conventions telling a programmer what sort of thing a WidgetWindowHandlerFactory is, but the compiler doesn't care; it could be a synonym for Integer.&lt;br /&gt;&lt;br /&gt;So this habit of natural language helps make randomly-chosen sentences more comprehensible on their own.  That in turn makes it easier for us short-attention-span programmers to digest the piles of paper our managers and user groups churn out.&lt;br /&gt;&lt;br /&gt;This suggests a couple interesting features for programming languages:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Structurally organize programs around a series of declared &lt;a href="http://en.wikipedia.org/wiki/Invariant_%28computer_science%29"&gt;invariants&lt;/a&gt;, with the compiler (when possible) or the programmer (the rest of the time) filling in associated code to ensure the invariant remains true.  This could be done in a lot of different ways depending on the need -- type systems, aspects, agents.&lt;/li&gt;&lt;li&gt;Create a large and varied, but standard and fixed, &lt;a href="http://en.wikipedia.org/wiki/Ontology_%28computer_science%29"&gt;ontology&lt;/a&gt; of types that the user should almost always derive from.  Give them all short names and require user-defined types and variables to end with those type names.  This would have to be done carefully to avoid javaStyleWordiness(), and it would also be a larger learning curve/burden on the programmer.  I'm picturing something vaguer and more flexible than a standard library; rather than providing a bunch of standard implementations, the ontology would provide standard invariants.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;* "motivated" -- I got this term from &lt;a href="http://en.wikipedia.org/wiki/George_Lakoff"&gt;George Lakoff&lt;/a&gt;'s book "&lt;a href="http://www.amazon.com/Women-Dangerous-Things-George-Lakoff/dp/0226468046"&gt;Women, Fire, and Dangerous Things"&lt;/a&gt; where he talks about how new uses for old words are &lt;span style="font-style: italic;"&gt;motivated&lt;/span&gt; by metaphorical relations with older meanings, but not &lt;span style="font-style: italic;"&gt;predictable&lt;/span&gt; from those meanings.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a href="http://en.wikipedia.org/wiki/ontology" rel="tag"&gt;ontology&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/language" rel="tag"&gt;language&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Programming+Languages" rel="tag"&gt;Programming Languages&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115767200353979504?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115767200353979504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115767200353979504&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115767200353979504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115767200353979504'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/09/organizing-programs-by-their.html' title='Organizing programs by their invariants'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115605060164058643</id><published>2006-08-19T21:14:00.000-07:00</published><updated>2006-08-19T22:10:01.676-07:00</updated><title type='text'>Saponomancy</title><content type='html'>This week I was asked to write some code to mimic a &lt;a href="http://en.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt; service.  How hard could that be?  It was a very simple service, just a couple remote procedure calls, one of which could return a large binary file.&lt;br /&gt;&lt;br /&gt;Of course, the original one was implemented in Delphi, to run under &lt;a href="http://en.wikipedia.org/wiki/IIS"&gt;IIS&lt;/a&gt;, and the new one needed to run on a UNIX-like system, but SOAP is intended on making all this easy, right?  How much did I need to know?&lt;br /&gt;&lt;br /&gt;Well, a lot, it turns out.   I played with a couple different toolkits for creating SOAP services, and they kept coming up with slight variations, none of which seemed to interoperate out of the box.  Little things would be different in the XML message, like whether namespaces were mentioned in the tags, or how the attachment was referenced and sent.  It was easy to see and understand the problem by looking at the dumps of the XML and MIME stuff going over the wire, but much harder to plow through the documentation of the various API's to see what flags needed to be set in their object model, or what objects needed to be created, or who was responsible for allocating and freeing memory, etc.&lt;br /&gt;&lt;br /&gt;In the end, I realized that since this was an internal service, and I controlled both endpoints, I could easily make a case to management for just &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;using the raw HTTP protocol&lt;/a&gt;, and in fact as I played with that solution, it turned out to be cleaner, lighter, more maintainable, and easier to document.  I'm changing my party affiliation to REST, even though it's too late to vote in the primaries.&lt;br /&gt;&lt;br /&gt;Well, that's fine; I'm sure there must be cases where SOAP is a better solution, but it got me to thinking about why it is that the raw XML is so much easier to debug than the supposedly labor-saving frameworks built on top of it.  I guess it's just that what goes across a line is easier to capture and pin down -- I can run two services, capture their input and output, and just compare the logs of them.  But I can't compare the operations of their object models, because they're different.&lt;br /&gt;&lt;br /&gt;What would be very cool, is if there were a formal way to specify a relationship between all the possible operations of an object model, and the grammar of its input and output streams.  Then I could point to a rule in the grammar that I wanted to come out a certain way, and ask "what sequences of user-accessible object operations can cause this".  The closest thing I've seen to this is the &lt;a href="http://www.cs.cmu.edu/%7Emarmalade/whyline.html"&gt;Whyline&lt;/a&gt; from project Marmelade at CMU.  The Whyline is a thingy that looks like it's geared towards helping a programmer find bugs in their code, by tracing out why a particular condition was arrived at in code execution.  Seems like it could be just as useful for prying apart the mysteries of someone else's prepackaged API, especially if it was closed-source, if somehow the Whyline could still operate without showing you precious vendor secrets.&lt;br /&gt;&lt;br /&gt;Unfortunately the Whyline is still a research project built into a research language called Alice, not a handy button on my Visual Studio menubar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115605060164058643?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115605060164058643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115605060164058643&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115605060164058643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115605060164058643'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/08/saponomancy.html' title='Saponomancy'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115561612815325536</id><published>2006-08-14T21:17:00.000-07:00</published><updated>2006-08-14T21:28:48.173-07:00</updated><title type='text'>Abstracting Bubblesort</title><content type='html'>In my &lt;a href="/sambangu/2006/08/how-we-talk-about-algorithms_04.html"&gt;August 4th entry&lt;/a&gt; I conjectured that monads might be a good way to abstract away the question of whether a bubblesort was done over time or laid out across memory as a sequence of permutations.&lt;br /&gt;&lt;br /&gt;I thought that was a good exercise for me to brush up on Haskell monads, so here's the program I wrote.  It's "literate haskell", so you can take this whole posting, save it as an whatever.lhs, and it should compile.&lt;br /&gt;&lt;br /&gt;I especially relied on a &lt;a href="http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html"&gt;monad tutorial&lt;/a&gt; at &lt;a href="http://sigfpe.blogspot.com/"&gt;A Neighborhood of Infinity&lt;/a&gt;, that Sigfpe happened to post just as I was in need of it.  Thanks, Sigfpe!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;I'll be using the State, List, and IO monads.  Eek, trial by fire.&lt;br /&gt;To start with, State has to be imported:&lt;br /&gt;&lt;br /&gt;&gt;import Control.Monad.State&lt;br /&gt;&lt;br /&gt;So here's my generic bubblesort to start out with.  It sets everything&lt;br /&gt;up without actually having the list available yet; all it needs is the&lt;br /&gt;length for now.&lt;br /&gt;&lt;br /&gt;The cf and swap parameters are functions that compare and swap elements,&lt;br /&gt;respectively.  Actually, they just take the indexes of the element(s)&lt;br /&gt;and return a function which will be responsible for testing and permuting&lt;br /&gt;anything the caller wants, however they want.  cf x y should compare elements&lt;br /&gt;x and y (whatever that may mean), and swap x should swap the xth and (x+1)th&lt;br /&gt;elements.&lt;br /&gt;&lt;br /&gt;So this function cycles through pairs of adjacent indices in bubblesorty&lt;br /&gt;fashion, and builds a list of functions, each of which is responsible&lt;br /&gt;for testing, and maybe swapping, a pair of elements, with those &lt;br /&gt;user-supplied comparison and swapping functions.&lt;br /&gt;&lt;br /&gt;&gt;bubblesort cf swap theLen = do&lt;br /&gt;&gt;                       i &lt;- reverse [0..theLen]&lt;br /&gt;&gt;                       j &lt;- [0..(i-2)]&lt;br /&gt;&gt;                       [do&lt;br /&gt;&gt;                            i &lt;- cf j (j+1)&lt;br /&gt;&gt;                            if i&lt;br /&gt;&gt;                                 then swap j &lt;br /&gt;&gt;                                 else return ()]&lt;br /&gt;&lt;br /&gt;Now here's a simple comparison function: it assumes that the &lt;br /&gt;list will be just an ordinary list, with elements instances of&lt;br /&gt;Ord (so that &gt; works).  What it returns is (State [a] Bool),&lt;br /&gt;which is actually another function, taking one list [a]&lt;br /&gt;and returning the same unchanged list [a] and a Boolean.&lt;br /&gt;&lt;br /&gt;&gt;cf1 :: Ord a =&gt; Int -&gt; Int -&gt; (State [a] Bool)&lt;br /&gt;&gt;cf1 i j = do&lt;br /&gt;&gt;            ls &lt;- get&lt;br /&gt;&gt;            return $ (ls!!i) &gt; (ls!!j)&lt;br /&gt;&lt;br /&gt;And here's the corresponding swap function.  It returns a&lt;br /&gt;function which takes a list, and returns a list with the&lt;br /&gt;jth and (j+1)th elements swapped.&lt;br /&gt;&lt;br /&gt;&gt;swap1 :: Int -&gt; (State [a] ())&lt;br /&gt;&gt;swap1 j = do&lt;br /&gt;&gt;            theList &lt;- get&lt;br /&gt;&gt;            put $ (take j theList) ++ &lt;br /&gt;&gt;                 [theList!!(j+1)] ++ [theList!!j] ++ drop (j+2) theList&lt;br /&gt;&lt;br /&gt;Let's look at another pair of swapping/comparison functions,&lt;br /&gt;before putting everything together:&lt;br /&gt;&lt;br /&gt;This set has a more complicated state -- it's an ordered pair,&lt;br /&gt;of the current permutation [a], and a list of strings [[Char]]&lt;br /&gt;representing the &lt;a href="/sambangu/plinko.txt"&gt;Plinko&lt;/a&gt; toy that &lt;br /&gt;would produce the sort so far.&lt;br /&gt;&lt;br /&gt;&gt;cf2 :: Ord a =&gt; Int -&gt; Int -&gt; (State ([a],[[Char]]) Bool)&lt;br /&gt;&gt;cf2 i j = do&lt;br /&gt;&gt;            (theList, history) &lt;- get&lt;br /&gt;&gt;            return $ (theList!!i) &gt; (theList!!j)&lt;br /&gt;&lt;br /&gt;And here's the corresponding swap function:&lt;br /&gt;&lt;br /&gt;&gt;swap2 j = do&lt;br /&gt;&gt;            (theList, history) &lt;- get&lt;br /&gt;&gt;            let newList = (take j theList) &lt;br /&gt;&gt;                          ++ [theList!!(j+1)] &lt;br /&gt;&gt;                          ++ [theList!!j] &lt;br /&gt;&gt;                          ++ drop (j+2) theList in&lt;br /&gt;&gt;                let newHistory = (( (replicate j '|') &lt;br /&gt;&gt;                              ++ "&gt;&lt;" &lt;br /&gt;&gt;                              ++ (replicate ((length theList)-j-1) '|')) &lt;br /&gt;&gt;                                  : history) in&lt;br /&gt;&gt;                    put (newList, newHistory)&lt;br /&gt;&lt;br /&gt;In this second example, the state is more than just the&lt;br /&gt;list, so we need a function to create the original ([a], [[Char]])&lt;br /&gt;structure:&lt;br /&gt;&lt;br /&gt;&gt;buildstate2 :: [a] -&gt; ([a], [[a]])&lt;br /&gt;&gt;buildstate2 a = (a, [[]])&lt;br /&gt;&lt;br /&gt;And one to get our plinko toy out after we're done sorting:&lt;br /&gt;&lt;br /&gt;&gt;getresult2 :: (Show a) =&gt; ([a], [[a]]) -&gt; [Char]&lt;br /&gt;&gt;getresult2 (_, b) = foldl (++) "" $ map (\b -&gt; "\n" ++ show(b) ) b&lt;br /&gt;&lt;br /&gt;I skipped the equivalent functions before for the straightforward&lt;br /&gt;sorting example because they are straightforward:&lt;br /&gt;&lt;br /&gt;&gt;buildstate1 :: [a] -&gt; [a]&lt;br /&gt;&gt;buildstate1 a = a&lt;br /&gt; &lt;br /&gt;&gt;getresult1 :: (Show a) =&gt; [a] -&gt; [Char]&lt;br /&gt;&gt;getresult1 a = show a&lt;br /&gt;&lt;br /&gt;So now we're ready to call this contraption.  dosort takes&lt;br /&gt;the four functions that relate to our state: buildstate, getresult,&lt;br /&gt;swap, and cf; along with the string to be sorted (I call it string,&lt;br /&gt;but it could have been a list of anything in Ord, really).&lt;br /&gt;&lt;br /&gt;The "sequence" function links up that list of functions that&lt;br /&gt;bubblesort created, and execState is what runs them, when supplied&lt;br /&gt;with the output of buildstate.&lt;br /&gt;&lt;br /&gt;&gt;dosort buildstate cf swap getresult string = &lt;br /&gt;&gt;           let sorter = bubblesort cf swap $ length string in&lt;br /&gt;&gt;               getresult $ execState (sequence sorter) (buildstate string)&lt;br /&gt;&lt;br /&gt;Here are some test functions which call both suites on the same string:&lt;br /&gt;&lt;br /&gt;&gt;test1 = dosort buildstate1 cf1 swap1 getresult1 "sambangu!"&lt;br /&gt;&gt;test2 = dosort buildstate2 cf2 swap2 getresult2 "sambangu!"&lt;br /&gt;&gt;&lt;br /&gt;&gt;main = do&lt;br /&gt;&gt;        putStrLn test1&lt;br /&gt;&gt;        putStrLn test2&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'm certain I'm not doing this in a very elegant way.  It appears that those four characteristic functions belong together in a class declaration, and somehow different execution types would be instances of that class, but I was unable to get it to compile that way.  Could be my syntax was wrong, or more likely, fuzzy thinking, which Haskell seems to be pretty (justifiably) intolerant of.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115561612815325536?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115561612815325536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115561612815325536&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115561612815325536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115561612815325536'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/08/abstracting-bubblesort.html' title='Abstracting Bubblesort'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115560686231159102</id><published>2006-08-14T18:39:00.000-07:00</published><updated>2006-08-14T18:54:22.330-07:00</updated><title type='text'>Keystroke coding system for Kanji</title><content type='html'>I was thinking about ways of entering Chinese characters, and wishing there were a more intuitive way to do it.  So here's a scheme I came up with.  Obviously a lot of people have been thinking about how to type kanji for a long time, so it's probably been thought of and (implemented | dismissed) before, but anyway, it seems to me like it could work:&lt;br /&gt;&lt;br /&gt;In this system each character is represented by a sequence of the letters b, n, m, and k.  Each letter represents a stroke or part of a stroke:&lt;br /&gt;&lt;br /&gt;   b = diagonal downwards to left&lt;br /&gt;   n = downwards&lt;br /&gt;   m = diagonal downwards to right&lt;br /&gt;   k = horizontal&lt;br /&gt;&lt;br /&gt;So for every stroke you type a letter, and if the stroke changes directions, you type the new letter, making no distinction between strokes and parts of strokes.  I wonder how many ambiguities there would be?  Are there any kanji with disputed stroke orders, or is it totally standardized?&lt;br /&gt;&lt;br /&gt;Here are the numbers 1 - 10:&lt;br /&gt;&lt;br /&gt;一  k&lt;br /&gt;二  kk&lt;br /&gt;三  kkk&lt;br /&gt;四  nknknbnk    &lt;br /&gt;五  knknk&lt;br /&gt;六  nkbm&lt;br /&gt;七  knk&lt;br /&gt;八  bkm&lt;br /&gt;九  bknk&lt;br /&gt;十  kn&lt;br /&gt;&lt;br /&gt;There would have to be some standard rules about how to represent the little hooks (like the last strokes of 四 and 九) and the ones that kind of curve from one heading to another (like the first stroke of 九).&lt;br /&gt;&lt;br /&gt;It seems like a person adept at writing kanji might be able to kind of mentally translate their mechanical skill of writing into these keystrokes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115560686231159102?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115560686231159102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115560686231159102&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115560686231159102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115560686231159102'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/08/keystroke-coding-system-for-kanji.html' title='Keystroke coding system for Kanji'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-115473371785511985</id><published>2006-08-04T16:17:00.000-07:00</published><updated>2006-08-04T16:21:57.880-07:00</updated><title type='text'>How we talk about algorithms</title><content type='html'>It's often the case that a programmer can quickly state the algorithm they want to use to solve a problem, but it takes significantly more time to cobble together the implementation.  There are lots of good reasons why it has to be that way -- explaining something in English presumes an intelligent listener, but the computer you're programming to is not intelligent.  But still, I'm wonder if part of the mental transformation that takes place is a conceptual restrucuring, that wouldn't be necessary if a computer language were structured differently.&lt;br /&gt;&lt;br /&gt;A good way to look at this might be to examine some programs along with descriptions of their algorithms, and see if we can discern any structural differences, and propose new computer language structures that are closer to the human abstraction mechanisms.&lt;br /&gt;&lt;br /&gt;So I want to take as a particular example the "BLACK" problem from this year's &lt;a href="http://www.icfpcontest.org/index.shtml"&gt;ICFP 2006 programming contest&lt;/a&gt;.  After the end of the contest, participants discussed their solutions to some of the problems, and in some cases posted their code, in a &lt;a href="http://lists.andrew.cmu.edu/pipermail/icfpcontest-discuss/Week-of-Mon-20060724/thread.html"&gt;public discussion list&lt;/a&gt;.  As this was a problem I spent some time with (and didn't solve) I decided to look at the algorithms that other teams used.&lt;br /&gt;&lt;h4&gt;Spoiler alert&lt;/h4&gt;The contest puzzle was an amazing construction that I'd highly recommend working on, even though the contest is over.  I'll be giving away the problem description here (which is a good piece of work just to get to), and some solution algorithms.&lt;br /&gt;&lt;h4&gt;The Problem&lt;/h4&gt;&lt;a href="http://www.quetzal.com/sambangu/plinko.txt"&gt;The problem is described here&lt;/a&gt;; basically you're doing a permutation of an ordered list, in steps, where each step can exchange pairs of adjacent items.  When a step shifts any item to the right, there is a "plink" sound.  There's no sound when shifting to the left.  The task is to recreate the steps needed, given an ending permutation and the number of plinks each item would experience in tracing through the steps.  So the first problem they provide looks like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;* x -&amp;gt; (y,z)&lt;br /&gt;* Means that if you drop a marble into pipe x, it comes out pipe y,&lt;br /&gt;* and you hear z plinks&lt;br /&gt;0 -&amp;gt; (3,4)&lt;br /&gt;1 -&amp;gt; (2,3)&lt;br /&gt;2 -&amp;gt; (0,1)&lt;br /&gt;3 -&amp;gt; (1,1)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And one solution is this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;gt;&amp;lt;||&lt;br /&gt;|&amp;gt;&amp;lt;|&lt;br /&gt;&amp;gt;&amp;lt;&amp;gt;&amp;lt;&lt;br /&gt;|&amp;gt;&amp;lt;|&lt;br /&gt;&amp;gt;&amp;lt;&amp;gt;&amp;lt;&lt;br /&gt;&amp;gt;&amp;lt;&amp;gt;&amp;lt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Where the &amp;gt;&amp;lt;'s represent swaps, and the |'s represent items that don't change in that step.  The problem set started with this puzzle of width 4, and also included problems of width 10, 20, 30, 40, 50, 100, 200, 300, 400, and 500.  Your score was based on submitting solutions; the code was not considered -- solving by hand was perfectly legal, if impractical for the larger problems.&lt;br /&gt;&lt;h4&gt;Notation&lt;/h4&gt;I'll use this notation in the discussion below:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In{st}[x]: the xth hole going into step {st} of the machine (numbering starting with 0)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Out{st}[x]: the xth hole coming out of step {st}.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Target{st}[x]: the desired destination of a marble placed at In{st}[x]&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Plinks{st}[x]: the plink count of a marble found at In{st}[x]&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Plinktarget{st}[x]: the desired plink count of a marble found at In{st}[x]&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Step{st}: The string of |'s, &amp;lt;'s, and &amp;gt;'s representing step #st of the machine&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Solution Strategies&lt;/h4&gt;I studied the descriptions of solutions on the mailing list, and on the web pages of participants if they were linked from the &lt;a href="http://lists.andrew.cmu.edu/pipermail/icfpcontest-discuss/Week-of-Mon-20060724/thread.html"&gt;list archive&lt;/a&gt;.&lt;br /&gt;&lt;h4&gt;Divide and Conquer&lt;/h4&gt;The first insight that most solvers shared was a division into two sequential phases.  As stated by Alain Frisch:&lt;br /&gt;&lt;br /&gt;&lt;quote&gt;&lt;/quote&gt;&lt;blockquote&gt;&lt;quote&gt;All the puzzles in the contest had a lot of plinks, [...] and it was indeed possible to first bubble sort the wires and then start from the identical permutation. That's what our team's solver does. &lt;/quote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Jed Davis wrote: &lt;quote&gt;&lt;/quote&gt;&lt;blockquote&gt;&lt;quote&gt;Mine likewise -- it first does the usual selection sort, then figures&lt;br /&gt;out what combination of maneuvers like that pictured above (moving a&lt;br /&gt;ball N places to one side and then back) need to be placed after the&lt;br /&gt;sort to reduce the remaining needed plinks to a form that can be handled&lt;br /&gt;by appending only double-swaps.&lt;/quote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Marcin Mucha wrote: &lt;blockquote&gt;&lt;quote&gt; I guess you know that, be some puzzles do have solutions, but you can't decompose any solution as a sequence of a bubblesort and a solution starting from an identical permutation.&lt;/quote&gt;&lt;/blockquote&gt;&lt;quote&gt;&lt;/quote&gt;It's interesting that they all emphasize the sequentiality; the two phases can' t be done in parallel.  Frisch says "to first xxxxxx and then yyyy"; Davis wrote "first xxxxxxx, then yyyyyy".  Mucha uses the word "sequence".   In your typical imperative language, simply listing two steps in order is sufficient to say "do one, then do the other"; this explicit statement of ordering suggests that sequentiality is not necessarily the default in English.&lt;br /&gt;&lt;h4&gt;The Bubblesort&lt;/h4&gt;In two of the three quotes above, the posters mention &lt;a href="http://en.wikipedia.org/wiki/Bubble_sort"&gt;bubblesort&lt;/a&gt; with the implied presumption that its application is obvious.  Bubble sort is an apt description of an algorithm realizable by this type of machine, since every swap is done between adjacent elements.  Here is the code Wikipedia gives for bubblesort:&lt;br /&gt;&lt;pre&gt;function bubblesort (A : list[1..n]) {&lt;br /&gt; var int i, j;&lt;br /&gt; for i from n downto 1 {&lt;br /&gt;     for j from 1 to i-1 {&lt;br /&gt;         if (A[j] &amp;gt; A[j+1])&lt;br /&gt;             swap(A[j], A[j+1])&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;A reasonably adept programmer should be able to read the description of the problem, and the vague advice to "apply a bubblesort", and implement it with some thought, but without any further clarification.  They are making a conceptual mapping like this:&lt;br /&gt;&lt;br /&gt;&lt;dl style=compact&gt;&lt;br /&gt;&lt;dt&gt;List parameter A&lt;br /&gt;&lt;dd&gt;Mapping from exit hole# of current step to exit hole# of final step&lt;br /&gt;&lt;dt&gt;n&lt;br /&gt;&lt;dd&gt;The number of pipes in the machine&lt;br /&gt;&lt;dt&gt;A[j] &gt; A[j+1]&lt;br /&gt;&lt;dd&gt;Pipe at j at this step is destined to a place further to the right of pipe at j+1&lt;br /&gt;&lt;dt&gt;swap(A[j], A[j+1])&lt;br /&gt;&lt;dd&gt;A pipe crossing is added&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;...so substituting the notation above, we have something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function bubblesort (Dest{st}) {&lt;br /&gt; var int i, j;&lt;br /&gt; st = 0&lt;br /&gt; for i from n downto 1 {&lt;br /&gt;     for j from 1 to i-1 {&lt;br /&gt;         if (Target{st}[j] &gt; Target{st}[j+1]) {&lt;br /&gt;             Target{st+1}[j] := Target{st}[j+1]&lt;br /&gt;             Target{st+1}[j+1] := Target{st}[j]&lt;br /&gt;             st ++&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is an interesting mapping because the paradigmatic bubblesort involves mutable storage, but this version builds a list of successively refined permutations.  Wikipedia of course doesn't define bubblesort this way. Programmers can make this leap with some thought.  Can the concept of "bubblesort" be defined such that something so fundamental is abstracted away?  I'm still wrapping my brain around monads, but I think this is what they are good for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-115473371785511985?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/115473371785511985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=115473371785511985&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115473371785511985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/115473371785511985'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/08/how-we-talk-about-algorithms_04.html' title='How we talk about algorithms'/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-113800107820646531</id><published>2006-01-22T22:12:00.000-08:00</published><updated>2006-01-22T23:25:08.513-08:00</updated><title type='text'></title><content type='html'>A Different Implementation of Relation-Chaining&lt;br /&gt;&lt;br /&gt;OK, I wasn't really happy with the implemenation the relation-chaining thing I did last week, so I rewrote it.  This won't make a lot of sense if you haven't read last week's installment, so go read it if you haven't yet...&lt;br /&gt;&lt;br /&gt;This time I have the forward-linking operator sort of equivalent to the python "." operator.  If &lt;span style="font-weight: bold;"&gt;romulus.father == mars&lt;/span&gt;, then &lt;span style="font-weight: bold;"&gt;romulus &gt;&gt; father == rset([mars])&lt;/span&gt;; in other words, the set containing &lt;span style="font-weight: bold;"&gt;mars&lt;/span&gt;.  &lt;span style="font-weight: bold;"&gt;rset&lt;/span&gt; is a class derived from set.  It's convenient to work with sets, because in the case of the reverse-linking operator, there could be more than one result, and I wanted some symmetry between the two cases.&lt;br /&gt;&lt;br /&gt;To do the reverse linking, I use gc.get_objects(), which is python's garbage collector's master list of all the objects in the system.  I guess that's not very efficient for a large program.  In a large program I'd recommend creating a "universe" dictionary, put the objects you really care about it in it, then search that instead of get_objects().&lt;br /&gt;&lt;br /&gt;A nice result of using sets is shown in the brother() function; the set operator "-" means to remove items from a set, so &lt;span style="font-weight: bold;"&gt;(x &gt;&gt; "father" &lt;&lt; "father") - x&lt;/span&gt; means: find the &lt;span style="font-weight: bold;"&gt;father&lt;/span&gt; of &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt;, then find the people &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; is a &lt;span style="font-weight: bold;"&gt;father&lt;/span&gt; to, then subtract &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; from that set, leaving only the siblings.&lt;br /&gt;&lt;br /&gt;The only reason I create my own set class, or my own &lt;span style="font-weight: bold;"&gt;relational_object&lt;/span&gt; class, is to get the syntax of &lt;span style="font-weight: bold;"&gt;&lt;&lt;&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;&gt;&gt;&lt;/span&gt; to work.  Really, this is a demonstration of a feature I think could be central to a language, and in that hypothetical language you'd build this feature in so it could be used on any objects.&lt;br /&gt;&lt;br /&gt;Well, here's the code.  I promise I'll move on to something different next week!  I just had to get this out of my system.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/local/bin/python2.4&lt;br /&gt;from gc import get_objects&lt;br /&gt;&lt;br /&gt;class relational_object(object):&lt;br /&gt;  def __repr__(self):&lt;br /&gt;      return "&lt;relational_object:&gt;"&lt;br /&gt;&lt;br /&gt;  def get_conv_gen(self, att):&lt;br /&gt;      for other in get_objects():&lt;br /&gt;          try:&lt;br /&gt;              if other.__dict__[att] == self:&lt;br /&gt;                  yield other&lt;br /&gt;          except Exception, e: pass&lt;br /&gt;&lt;br /&gt;  def get_conv_any(self, att): return self.get_conv_gen(att).next()&lt;br /&gt;  def get_conv_all(self, att): return rset([ x for x in self.get_conv_gen(att)])&lt;br /&gt;&lt;br /&gt;  def __rshift__(self, att):  return rset([self.__dict__[att]])&lt;br /&gt;  def __lshift__(self, att):  return rset(self.get_conv_all(att))&lt;br /&gt;&lt;br /&gt;class rset(set):&lt;br /&gt;  def __rshift__(self, att):&lt;br /&gt;      result = rset()&lt;br /&gt;      for x in self:&lt;br /&gt;          result = result | rset([x.__dict__[att]])&lt;br /&gt;      return result&lt;br /&gt;  def __lshift__(self, att):&lt;br /&gt;      result = rset()&lt;br /&gt;      for x in self:&lt;br /&gt;          result = result | x.get_conv_all(att)&lt;br /&gt;      return result&lt;br /&gt;&lt;br /&gt;class person(relational_object):&lt;br /&gt;  def __init__(self, theName):&lt;br /&gt;      self.name = theName&lt;br /&gt;  def __repr__(self): return "&lt;&gt;"&lt;br /&gt;&lt;br /&gt;mars = person("mars")&lt;br /&gt;romulus = person("romulus")&lt;br /&gt;remus = person("remus")&lt;br /&gt;assert mars == mars&lt;br /&gt;assert mars != remus&lt;br /&gt;&lt;br /&gt;romulus.father = mars&lt;br /&gt;remus.father = mars&lt;br /&gt;&lt;br /&gt;assert mars &lt;&lt; "father" == rset([romulus, remus])   &lt;span style="font-family:Georgia,serif;"&gt;&lt;/span&gt;&lt;/relational_object:&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-113800107820646531?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/113800107820646531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=113800107820646531&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/113800107820646531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/113800107820646531'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/01/different-implementation-of-relation.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-113728033862876484</id><published>2006-01-14T15:11:00.000-08:00</published><updated>2006-01-14T15:35:53.566-08:00</updated><title type='text'></title><content type='html'>Relation-chaining gimmick in Python&lt;br /&gt;&lt;br /&gt;This is just a piece of a whole idea, but I thought you might find it amusing.&lt;br /&gt;&lt;br /&gt;There is an &lt;a href="http://www.w3.org/RDF/"&gt;RDF&lt;/a&gt; notation called &lt;a href="http://www.w3.org/DesignIssues/Notation3.html"&gt;N3&lt;/a&gt; that has an interesting syntax for quickly describing a chain of relations linking one node to another.&lt;br /&gt;&lt;br /&gt;Here are some examples from the N3 paper:&lt;br /&gt;&lt;pre&gt;:joe!fam:mother!loc:office!loc:zip   Joe's mother's office's zipcode&lt;br /&gt;:joe!fam:mother^fam:mother           Anyone whose mother is Joe's mother.&lt;br /&gt;&lt;/pre&gt;:joe ("Colon Joe" -- sounds like a brand of medicinal coffee, doesn't it?) is an RDF node.  The other strings with colons in them, fam:mother, loc:office, and loc:zip, represent binary relations.  I think the part before the colon tells you the namespace it's from, but ignore that for now.&lt;br /&gt;&lt;br /&gt;The ! is like the "." operator in most object-oriented languages.  :joe!fam:mother means "Joe's Mother", and you might say this as joe.mother in some language like Python or C.&lt;br /&gt;&lt;br /&gt;The ^ is the converse of !; so if joe!mother == sue, then sue^mother == joe.  You can think of !mother as meaning "mother" and ^mother as meaning "child".  ^employer means employee, ^owner means possession.  "hello, world"!length == 12, so 12^length == "hello, world" (among many other strings).&lt;br /&gt;&lt;br /&gt;My mind was brought back to this when I was working on a project with a bunch of related objects in Python, and I was looking for a clean way of expressing complicated queries among them.  In my day job I do a lot of ad-hoc SQL querying, and while I don't love SQL, it is nice to be able to fluently, readably, ask some complex questions of a bunch of relations.  I'd read that list comprehensions were more or less isomorphic to SQL, but I found when playing with them that my queries were inefficient and not very readable; they were no better than just writing explicit code to traverse the object tree and collect the information I wanted.&lt;br /&gt;&lt;br /&gt;I'm not sure if these N3-style paths will be useful in practice, yet, but it was worth playing around with them.  The biggest hurdle with them, as I see it, is that there's no easy way when presented with 12^length to know what string is wanted, so you have to have a well-defined universe of objects to work with, and be willing to accept multiple results from every query.&lt;br /&gt;&lt;br /&gt;So anyway, here's some code to give you an idea what I've come up with so far:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import pprint&lt;br /&gt;&lt;br /&gt;class relation:&lt;br /&gt; def __init__(self):&lt;br /&gt;     self.forward = dict()&lt;br /&gt;     self.backward = dict()&lt;br /&gt;&lt;br /&gt; def add(self, arg1, arg2):&lt;br /&gt;     if not self.forward.has_key(arg1):&lt;br /&gt;         self.forward[arg1] = dict()&lt;br /&gt;     if not (arg2 in self.forward[arg1]):&lt;br /&gt;         self.forward[arg1][arg2] = True&lt;br /&gt;     if not self.backward.has_key(arg2):&lt;br /&gt;         self.backward[arg2] = dict()&lt;br /&gt;     if not (arg1 in self.backward[arg2]):&lt;br /&gt;         self.backward[arg2][arg1] = True&lt;br /&gt;&lt;br /&gt; def __call__(self, arg1, arg2):&lt;br /&gt;     try:&lt;br /&gt;         return self.forward[arg1][arg2]&lt;br /&gt;     except Exception, e:&lt;br /&gt;         return false&lt;br /&gt;&lt;br /&gt; def get_all_keys(self, hash, key):&lt;br /&gt;     try:&lt;br /&gt;         return hash[key].keys()&lt;br /&gt;     except Exception, e:&lt;br /&gt;         return []&lt;br /&gt;&lt;br /&gt; def __rlshift__(self, other):&lt;br /&gt;     result = []&lt;br /&gt;     for item in other:&lt;br /&gt;        result = result + self.get_all_keys(self.forward, item)&lt;br /&gt;     return result&lt;br /&gt;&lt;br /&gt; def __rrshift__(self, other):&lt;br /&gt;     result = []&lt;br /&gt;     for item in other:&lt;br /&gt;        result = result + self.get_all_keys(self.backward, item)&lt;br /&gt;     return result&lt;br /&gt;&lt;br /&gt;father = relation()&lt;br /&gt;phone = relation()&lt;br /&gt;&lt;br /&gt;class frank: pass&lt;br /&gt;class jeff: pass&lt;br /&gt;class chris: pass&lt;br /&gt;class andy: pass&lt;br /&gt;&lt;br /&gt;father.add(frank, jeff)&lt;br /&gt;father.add(jeff, chris)&lt;br /&gt;father.add(jeff, andy)&lt;br /&gt;phone.add(andy, "101-555-1249")&lt;br /&gt;assert [chris] &gt;&gt; father == [jeff]&lt;br /&gt;assert [jeff] &lt;&lt; father == [chris, andy]&lt;br /&gt;assert [chris] &gt;&gt; father == [jeff]&lt;br /&gt;assert [jeff] &lt;&lt; father == [chris, andy]&lt;br /&gt;assert [andy] &lt;&lt; phone == ["101-555-1249"]&lt;br /&gt;assert [chris] &lt;&lt; phone == []&lt;br /&gt;assert [andy, chris] &lt;&lt; phone == ["101-555-1249"]&lt;br /&gt;assert (([chris] &gt;&gt; father) &lt;&lt; father) &lt;&lt; phone == ["101-555-1249"]&lt;br /&gt;assert [chris] &gt;&gt; father &lt;&lt; father &lt;&lt; phone == ["101-555-1249"]&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Some things to note about this implementation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I used classes like "jeff" and "chris" for nodes.  You could use any Python objects; the "class X: pass" syntax is just a cheesy quick way to create a dummy object to play around with.  In Python a class is a kind of object.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I used &gt;&gt; and &lt;&lt;&gt;&lt;li&gt;nstead of the RDF "node", I use a list with one or more python objects in it, in this case strings.  I'm using a list as kind of a half-assed &lt;a href="http://en.wikipedia.org/wiki/Monads_in_functional_programming"&gt;monad&lt;/a&gt;.  Since a &gt;&gt; or &lt;&lt;&gt;&lt;li&gt;I define a relation object which holds all its pairs of related things in hashes.  It's probably not very efficient.  I originally thought I'd just use the members of objects as the relations, so that the natural joe.mother would be the basis for the relation joe &gt;&gt; mother.   But that didn't fit in very well with the list thing.  If Heather has two mommies, you can have:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mother("Ann", "Heather")&lt;br /&gt;mother("Patricia", "Heather")&lt;br /&gt;assert ["Heather"] &gt;&gt; mother == ["Ann", "Patricia"]&lt;br /&gt;&lt;/pre&gt;as opposed to&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;heather.mother = ann&lt;br /&gt;heather.mother = patricia&lt;br /&gt;&lt;/pre&gt;where Patricia just overwrites Ann.  This makes Ann sad.&lt;br /&gt;&lt;p&gt;Maybe there's a better way around this.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;I'm not sure I've got the precedence the same as N3 has it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It should be sets, not lists.  ["Ann", "Patricia"] should be considered the same result as ["Patricia", "Ann"].&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Next time I'll try to apply this to a more interesting problem to see if it holds up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-113728033862876484?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/113728033862876484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=113728033862876484&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/113728033862876484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/113728033862876484'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2006/01/relation-chaining-gimmick-in-python.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108695952053701085</id><published>2004-06-11T06:07:00.000-07:00</published><updated>2004-06-11T06:12:00.536-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.paulgraham.com"&gt;Paul Graham&lt;/a&gt; also has some pie-in-the-sky thoughts about computer languages; see his articles, &lt;a href="http://www.paulgraham.com/hundred.html"&gt;Hundred-year language&lt;/a&gt; and his work on a new dialect of Lisp, &lt;a href="http://www.paulgraham.com/arc.html"&gt;Arc&lt;/a&gt;.  Arc is a little more down-to-earth than the Tunes HLL, and he appears to have done some work on it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108695952053701085?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108695952053701085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108695952053701085&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108695952053701085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108695952053701085'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/06/paul-graham-also-has-some-pie-in-sky.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108695911156617075</id><published>2004-06-11T06:02:00.000-07:00</published><updated>2004-06-11T06:07:19.683-07:00</updated><title type='text'></title><content type='html'>The &lt;a href="http://tunes.org/"&gt;Tunes&lt;/a&gt; project has some requirements for an unnamed "&lt;a href="http://tunes.org/HLL/"&gt;High Level Language&lt;/a&gt;" for their project, which has a lot of good ideas init.  As far as I can tell looking at the web page, it's kind of vaporware at this point.  And maybe doomed to remain vaporware, since the requirements seem so abstract and idealistic.  But anyway, some of their ideas have crossed my mind too, and they might at least server as a thoughtful critique of how current programming langauges feel inadequate to people.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108695911156617075?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108695911156617075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108695911156617075&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108695911156617075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108695911156617075'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/06/tunes-project-has-some-requirements.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108511564889093015</id><published>2004-05-20T21:37:00.000-07:00</published><updated>2004-05-20T22:00:48.890-07:00</updated><title type='text'></title><content type='html'>Two good articles by Cory Doctorow (&lt;a href="http://www.well.com/~doctorow/metacrap.htm"&gt;Metacrap&lt;/a&gt;) and Clay Shirky (&lt;a href="http://www.shirky.com/writings/semantic_syllogism.html"&gt;The Semantic Web, Syllogism, and Worldview&lt;/a&gt;), expressing skepticism about the &lt;a href="http://www.w3.org/2001/sw/"&gt;Semantic Web&lt;/a&gt;.  &lt;br /&gt;&lt;p&gt;&lt;br /&gt;Shirky says most human thought isn't deduction from syllogisms, it's much more fuzzy and heuristic than that.  Doctorow points out lots of good reasons why metadata will be crap in practice.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;These ideas relate to better programming languages too.  There's an impedance mismatch between human concepts and the way computer software systems tend to classify things.  We just don't think as rigidly about things as computers do.  We get frustrated with how software will go mindlessly clanking down the wrong path (for example happily cranking out copies of a virus and emailing them to all your friends), but when we try to build smarts into it, we're frustrated by just how &lt;i&gt;dumb&lt;/i&gt; those smarts turn out to be.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Human computer interfaces, from GUIs to languages to development and testing environments, need to help our squishy minds navigate the bizarre tinkertoy syllogismatrons we're forced to build.  While we frantically look for ways to teach software to think more like we do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108511564889093015?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108511564889093015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108511564889093015&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108511564889093015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108511564889093015'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/05/two-good-articles-by-cory-doctorow.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108294009809321262</id><published>2004-04-25T17:39:00.000-07:00</published><updated>2004-04-25T17:49:29.466-07:00</updated><title type='text'></title><content type='html'>I just stumbled on a weblog about programming languages and their design, called &lt;a href="http://lambda.weblogs.com"&gt;Lambda the Ultimate&lt;/a&gt;.  Similar to what I want to do here, although I want to focus more specifically on languages that bridge the gap in some interesting way between natural human languages and traditional computer languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108294009809321262?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108294009809321262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108294009809321262&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108294009809321262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108294009809321262'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/04/i-just-stumbled-on-weblog-about.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108267546988996680</id><published>2004-04-22T15:51:00.000-07:00</published><updated>2004-04-22T16:15:17.890-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.perl.com/pub/a/2004/04/16/a12.html"&gt;Apocalypse 12&lt;/a&gt; is out.&lt;br /&gt;&lt;br /&gt;In case you live in a cave, the Apocalypses are Larry Wall's occasional manifestos (manifesti?) about how some aspect of Perl 6 will work.  I read them with great interest because I like how Wall thinks, and I'm an avid user of Perl, and Perl 6 has some great ideas in it.  I like hyperoperators and the new regular expression syntax.  That being said, I'm getting kind of worried that Perl 6 is going to be too crufty.  Look at what you can do with subroutine signatures.  It seems unnecessarily complex and cryptic.&lt;br /&gt;&lt;br /&gt;Of course I thought that back when I was learning Old Perl, but now I know it well and can use pretty efficiently, so I'll withhold judgment on Perl 6 until I get a chance to use it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108267546988996680?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108267546988996680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108267546988996680&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108267546988996680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108267546988996680'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/04/apocalypse-12-is-out.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108239797072032295</id><published>2004-04-19T10:53:00.000-07:00</published><updated>2004-04-19T11:10:14.373-07:00</updated><title type='text'></title><content type='html'>What this blog is about&lt;br /&gt;&lt;br /&gt;The last post was mostly a test.  What I want to do here is review computer languages that bridge the gap between computer language and human language in some interesting way.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.lojban.org"&gt;Lojban&lt;/a&gt; is an attempt to make a human language somewhat more approachable by computers -- it has a yacc-parseable grammar that is syntactically unambiguous.  In practice so far it has been used for communication between humans, not to specify or constrain a computer's behavior in any way.  But it's a good example of an effort to think about some of  the differences between the two kinds of language and find halfway points.&lt;br /&gt;&lt;br /&gt;I do think that someday computers will be able to cope with human language.  For programming I think we'll always need something a little more precise (like the language used in human legal contracts, maybe) to avoid some ambiguity.&lt;br /&gt;But that day could be a ways off; why not meet the machine halfway for now?  High-level languages have come a long way from raw machine code in doing this; I'm interested in seeing in what other ways computer languages can be more human without requiring outright artificial intelligence in the computer that uses them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108239797072032295?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108239797072032295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108239797072032295&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108239797072032295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108239797072032295'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/04/what-this-blog-is-about-last-post-was.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6687315.post-108051759420368407</id><published>2004-03-28T15:28:00.000-08:00</published><updated>2004-03-28T15:50:38.686-08:00</updated><title type='text'></title><content type='html'>Kevo was an object-oriented language where classes were derived from objects rather than the other way around: a "family" of objects are ones that have the same signature.  Families change dynamically as object properties are changed at runtime.&lt;br /&gt;&lt;br /&gt;I haven't been able to find much detail about Kevo; it looks like it emerged around 1993 and its author is &lt;a href="http://www.cs.tut.fi/~taivalsa/"&gt;Antero Taivalsaari&lt;/a&gt; who has since done a lot of work since then on Mobile Java (J2ME).  Here's an interesting paper that mentions Kevo: &lt;br /&gt;&lt;a href="http://www.helsinki.fi/~jppesone/papers/kandi.html"&gt;Psychological criticism of the Prototype-Based OO-Languages&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6687315-108051759420368407?l=sambangu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sambangu.blogspot.com/feeds/108051759420368407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6687315&amp;postID=108051759420368407&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108051759420368407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6687315/posts/default/108051759420368407'/><link rel='alternate' type='text/html' href='http://sambangu.blogspot.com/2004/03/kevo-was-object-oriented-language.html' title=''/><author><name>Chris Bogart</name><uri>http://www.blogger.com/profile/08163342331118448067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://www.quetzal.com/sambangu.jpg'/></author><thr:total>0</thr:total></entry></feed>
