<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
 <channel>
  <title>Posts tagged "Hacker-School"</title>
  <description>Posts tagged "Hacker-School"</description>
  <link>https://www.greghendershott.com/tags/Hacker-School.rss.xml</link>
  <atom:link href="https://www.greghendershott.com/tags/Hacker-School.rss.xml" rel="self" type="application/rss+xml"></atom:link>
  <lastBuildDate>Sat, 06 Dec 2014 01:00:00 UT</lastBuildDate>
  <pubDate>Sat, 06 Dec 2014 01:00:00 UT</pubDate>
  <ttl>1800</ttl>
  <item>
   <title>Blogging catch-up</title>
   <link>https://www.greghendershott.com/2014/12/blogging-catch-up.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-12-blogging-catch-up.html</guid>
   <pubDate>Sat, 06 Dec 2014 01:00:00 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Blogging catch-up&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-12-05" pubdate="true"&gt;2014-12-05&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;It&amp;rsquo;s been a few weeks since I&amp;rsquo;ve blogged. Bad me. This is a catch-up post.&lt;/p&gt;
  &lt;p&gt;Hacker School has a tool called &lt;a href="https://github.com/sursh/blaggregator"&gt;Blaggregator&lt;/a&gt; created by Sasha Laundy. We can submit feeds for our blogs. Blaggregator provides an aggregate page, and puts new-post messages on Zulip, the chat tool.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;Awhile ago I noticed a bug with time zones in the RSS feed generated by &lt;a href="https://github.com/greghendershott/frog"&gt;Frog&lt;/a&gt;. I was concerned that fixing the feed would change date-times, and that &lt;em&gt;might&lt;/em&gt; cause Blaggregator to flood Zulip with &amp;ldquo;new post!&amp;rdquo; notifications. Which would be embarrassing. So I unsubscribed my feed, fixed the problem, and subscribed again. All went well, but Sasha pinged me on Zulip today to follow up and make sure.&lt;/p&gt;
  &lt;p&gt;That prompted me to check out Sasha&amp;rsquo;s profile page and list of projects. That led me to &lt;a href="http://blog.sashalaundy.com/blog/2013/03/25/on-rakefiles-and-rabbit-holes/"&gt;On Rakefiles and Rabbit Holes&lt;/a&gt;. This is such a classic Hacker School type of post &amp;mdash; where someone takes the time to follow the trail wherever it leads, and learn cool new things.&lt;/p&gt;
  &lt;p&gt;Sasha&amp;rsquo;s mention of &lt;code&gt;stty -echo&lt;/code&gt; reminded me of a mild annoyance in Emacs&amp;rsquo; shell-mode. Sometimes &amp;mdash; but not always &amp;mdash; it starts echoing my input, as if I had typed &lt;code&gt;stty echo&lt;/code&gt;. Sasha&amp;rsquo;s post this reminded me I could type &lt;code&gt;stty -echo&lt;/code&gt; to turn it off. But how and why does it turned on in the first place? I searched and found a Stack Overflow question, &lt;a href="http://stackoverflow.com/questions/19246065/python-in-emacs-shell-mode-turns-on-stty-echo-and-breaks-c-d"&gt;Python in Emacs shell-mode turns on stty echo and breaks C-d&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;Aha. As it says:&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;OS X ships with the BSD-licensed editline rather than the GPL-licensed readline, so this would explain why the behaviour is different on OS X from other Unixes. The same thing happens with other interactive interpreters. I find that the Lua, Ruby and Sqlite3 command-line interpreters also turn on terminal echo when run inside Emacs. So it seems to be some kind of &amp;ldquo;feature&amp;rdquo; of the editline library.&lt;/p&gt;&lt;/blockquote&gt;
  &lt;p&gt;Yes. A fresh 
   &lt;kbd&gt;M-x&lt;/kbd&gt; &lt;code&gt;shell&lt;/code&gt; is fine, until I run (say) &lt;code&gt;python&lt;/code&gt; or &lt;code&gt;racket&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Anyway, Sasha&amp;rsquo;s Zulip message managed to nudge me into writing a blog post.&lt;/p&gt;
  &lt;h2 id="so-what-have-i-been-up-to"&gt;So what &lt;em&gt;have&lt;/em&gt; I been up to?&lt;/h2&gt;
  &lt;p&gt;My first six weeks here, I mostly spent multiple weeks at a time on things like getting hands-on with Clojure and then Haskell, or pairing a full week on a web service.&lt;/p&gt;
  &lt;p&gt;Whereas so far in the second half, I&amp;rsquo;ve been doing a variety of smaller projects &amp;mdash; which I haven&amp;rsquo;t blogged about one by one. Here&amp;rsquo;s a quick overview:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;Help some people who were pairing to create a lean web framework in  Python. We got to see first-hand how cookies are a way to provide  state for a multi-page form application.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Work through the &lt;a href="http://doc.rust-lang.org/guide.html"&gt;Rust Guide&lt;/a&gt; hands-on.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Pair with someone working on a Python web app that shows you if it&amp;rsquo;s  Shabbat in the location of someone you want to call. They wanted to  refactor the code to be less repetitive.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Participate in Zach Allaun&amp;rsquo;s hands-on workshop about configuring and  developing using ClojureScript.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Fix a bug in &lt;a href="https://github.com/greghendershott/racket-mode"&gt;racket-mode&lt;/a&gt; on Windows.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Pair with someone who is vastly more experienced in Haskell than me,  to learn how to use Template Haskell for my Haskell port of wffi.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Fix some issues with a couple of my Racket packages, &lt;a href="https://github.com/greghendershott/aws"&gt;aws&lt;/a&gt; and  &lt;a href="https://github.com/greghendershott/http"&gt;http&lt;/a&gt;, that are now being used by Racket&amp;rsquo;s DrDr continuous  integration tool.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Pair with someone who is getting started with Racket and wanted to  use racket-mode on Emacs.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Start to learn about microKanren from looking at &lt;a href="http://pobox.com/~oleg/ftp/Scheme/sokuza-kanren.scm"&gt;sokuza-kanren.scm&lt;/a&gt;  and a couple papers including  &lt;a href="http://webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdf"&gt;μKanren: A Minimal Functional Core for Relational Programming&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Start to work through the &lt;a href="http://cryptopals.com/"&gt;Matasano crypto challenges&lt;/a&gt;.&lt;sup&gt;&lt;a href="#blogging-catch-up-footnote-1-definition" name="blogging-catch-up-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;In most of these cases, I didn&amp;rsquo;t feel like I had an entire interesting blog post to write. I did take notes and had some fantastic experiences both learning and teaching.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="blogging-catch-up-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;All the friends and family who think I&amp;rsquo;m learning cracking here at Hacker School? This is the closest I&amp;rsquo;ve come so far.&amp;nbsp;&lt;a href="#blogging-catch-up-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hacker school week 6</title>
   <link>https://www.greghendershott.com/2014/11/hacker-school-week-6.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-11-hacker-school-week-6.html</guid>
   <pubDate>Fri, 14 Nov 2014 18:42:14 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hacker school week 6&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-11-14" pubdate="true"&gt;2014-11-14&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;I&amp;rsquo;m at the end of week 6 at Hacker School, which marks the halfway point. There are overlapping 12-week batches. As a result, the previous batch never-graduated yesterday.&lt;/p&gt;
  &lt;p&gt;My early weeks here included &lt;em&gt;some&lt;/em&gt; pairing, and it was fun, but I spent more time learning and coding solo. My previous week was nearly the opposite. I spent most of my time pairing with Sumana Harihareswara.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;Her project idea was a web service that would help people find vulnerabilities in C code, and return a report card itemizing the issues and giving a score&lt;sup&gt;&lt;a href="#hacker-school-week-6-footnote-1-definition" name="hacker-school-week-6-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
  &lt;p&gt;Writing a static code analyzer from scratch seemed like it would be too ambitious for the time available. So for version 0.1 we decided to have our web service wrap existing tools like &lt;a href="http://clang-analyzer.llvm.org/"&gt;Clang Static Analyzer&lt;/a&gt; and &lt;a href="http://cppcheck.sourceforge.net/"&gt;Cppcheck&lt;/a&gt;. Someone can use the analyzers without needing to install them.&lt;/p&gt;
  &lt;p&gt;We installed and got familiar with &lt;code&gt;clang&lt;/code&gt;&amp;rsquo;s &lt;code&gt;scan-build&lt;/code&gt;. I wrote some C code with deliberate problems, and we saw what was reported.&lt;/p&gt;
  &lt;p&gt;For our web server, we decided to make something using Python. We started to look at our choices for frameworks, like Django, Flask, and several dozen others. But then we realized, hey &amp;mdash; our web service is really simple. It has one resource. A request will be:&lt;/p&gt;
  &lt;div class="brush: http"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/api/analyze&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;42&lt;/span&gt;

/* my awful C code */
main () {
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Our response body will be &lt;code&gt;scan-build&lt;/code&gt; output parsed into some sort of JSON.&lt;/p&gt;
  &lt;p&gt;Do we need any framework at all?&lt;/p&gt;
  &lt;p&gt;We decided no. We derived from &lt;code&gt;BaseHTTPServer&lt;/code&gt;, overriding &lt;code&gt;do_POST&lt;/code&gt;. This became a great opportunity to look at how HTTP requests and responses work.&lt;/p&gt;
  &lt;p&gt;Of course, if our web service were to grow, we would find ourselves copying and pasting a bunch of code. We would DRY it into some helper functions. One day we&amp;rsquo;d say, &amp;ldquo;Let&amp;rsquo;s share this with the world!&amp;rdquo;. And voila, the world would have another framework.&lt;/p&gt;
  &lt;p&gt;Or better yet, we&amp;rsquo;d say, &amp;ldquo;OK, now let&amp;rsquo;s use some existing framework. Now we know what problems it&amp;rsquo;s solving for us. Now we have a reasonable mental model for how it probably works; it&amp;rsquo;s not some magical black box.&amp;rdquo;&lt;/p&gt;
  &lt;p&gt;When it came time to parse the &lt;code&gt;scan-build&lt;/code&gt; output into JSON, I found it quicker to write that in Racket than in Python. Which was fine, because that was something we needed done, as opposed to something we wanted to learn about.&lt;/p&gt;
  &lt;p&gt;At this point we had a reasonably well-working application that ran&amp;hellip; on our laptops. We wanted to deploy it on a Digital Ocean droplet. Putting one web service on one droplet isn&amp;rsquo;t difficult. But we opted to pretend that our web service would become wildly popular and we&amp;rsquo;d need to scale it across multiple machines. A couple people had asked if we were going to try Docker. We did.&lt;/p&gt;
  &lt;p&gt;It took us awhile to wrap our head around the concepts. Eventually we understood that an &lt;em&gt;image&lt;/em&gt; is a read-only thing created from a &lt;code&gt;Dockerfile&lt;/code&gt;. It is built from a base image, e.g. Ubuntu, plus additional packages that you install, and other programs that you run and settings that you configure. Thereafter you launch &lt;em&gt;containers&lt;/em&gt; for an image. These have a read/write layer and are a kind of lightweight VM in which your application runs. You can &lt;code&gt;docker run -d
&amp;lt;image&amp;gt;&lt;/code&gt; to detach these and they run in the background; you &lt;code&gt;docker
logs &amp;lt;container&amp;gt;&lt;/code&gt; to see their output. You can &lt;code&gt;docker stop
&amp;lt;container&amp;gt;&lt;/code&gt; to stop one. After stopped it still exists. You can see all these with &lt;code&gt;docker ps -a&lt;/code&gt;, or just the running ones with &lt;code&gt;docker
ps&lt;/code&gt;. You can delete a stopped container with &lt;code&gt;docker rm &amp;lt;container&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Therefore we wanted to create an image based on Ubuntu, install some packages like &lt;code&gt;git&lt;/code&gt; and Racket 6.1, and finally do a &lt;code&gt;git clone&lt;/code&gt; of our app code.&lt;/p&gt;
  &lt;p&gt;A couple issues that slowed us down briefly:&lt;/p&gt;
  &lt;ol&gt;
   &lt;li&gt;
    &lt;p&gt;&lt;code&gt;apt-get&lt;/code&gt; wouldn&amp;rsquo;t work until we changed &lt;code&gt;/etc/default/docker/&lt;/code&gt; to  un-comment the line saying to use Google&amp;rsquo;s DNS servers.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;How to set an environment variable in our &lt;code&gt;Dockerfile&lt;/code&gt;, that would  survive into the container&amp;rsquo;s environment. Doing &lt;code&gt;RUN export
   PATH=$PATH:/new/path&lt;/code&gt; did not work. Turned out we needed &lt;code&gt;ENV&lt;/code&gt;, as  in &lt;code&gt;ENV PATH $PATH:/new/path&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
  &lt;p&gt;In the end we got things working.&lt;/p&gt;
  &lt;p&gt;The final day we made a simple web &lt;em&gt;site&lt;/em&gt; to go along with our web &lt;em&gt;service&lt;/em&gt;. So as a human you can visit a page, type C code in a form or do a file upload, and get the report card on a web page rather than as raw JSON. Although we didn&amp;rsquo;t learn a whole lot by doing this part, it was a satisfying way to wrap up the project.&lt;/p&gt;
  &lt;p&gt;I enjoyed the project because I got a chance to:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;Try more Python coding in a week than I&amp;rsquo;ve done, ever.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Understand Docker hands-on.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Exercise developer teamwork skills.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Validate my understanding of HTTP mechanics by explaining them  effectively.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;For my second half of Hacker School, I&amp;rsquo;m looking forward to doing more pairing. After all, I can study things solo anytime. Now is when I have so many great opporunities to pair.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="hacker-school-week-6-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;Silicon Valley has its &amp;ldquo;Weisman Score&amp;rdquo;. Well &lt;em&gt;this&lt;/em&gt; is a &amp;ldquo;Hendershott-Harihareswara Score&amp;rdquo;. Really rolls off the tongue, doesn&amp;rsquo;t it?&amp;nbsp;&lt;a href="#hacker-school-week-6-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hands-on with Haskell week 1</title>
   <link>https://www.greghendershott.com/2014/11/hands-on-with-haskell.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-11-hands-on-with-haskell.html</guid>
   <pubDate>Mon, 03 Nov 2014 15:51:21 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hands-on with Haskell week 1&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-11-03" pubdate="true"&gt;2014-11-03&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Haskell.html"&gt;Haskell&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;Last week I decided to pivot from Clojure hands-on to Haskell hands-on.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;h1 id="rewiring-brain-from-lisp-to-haskell"&gt;Rewiring brain from Lisp to Haskell&lt;/h1&gt;
  &lt;p&gt;Prior to this, I had spent some time working through examples in &lt;a href="http://learnyouahaskell.com/"&gt;Learn You a Haskell&lt;/a&gt; and armchair browsing &lt;a href="http://book.realworldhaskell.org/"&gt;Real World Haskell&lt;/a&gt;. Also I&amp;rsquo;d spent some time using Typed Racket and was already sold on the benefits of having a &amp;ldquo;real&amp;rdquo; type system, especially for certain sorts of programs. So this wasn&amp;rsquo;t starting from scratch. However I soon discovered there were some things about Haskell that I&amp;rsquo;d forgotten and needed to re-learn. Also I suffered from a Lisp brain configuration.&lt;/p&gt;
  &lt;h2 id="sections"&gt;Sections&lt;/h2&gt;
  &lt;p&gt;One example was sections. On Zulip I saw a code fragment like this:&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nf"&gt;primes&lt;/span&gt; &lt;span class="ow"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;takeWhile&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;primes&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;With the comment that the &lt;code&gt;(&amp;lt;= i)&lt;/code&gt; was equivalent to &lt;code&gt;(\j -&amp;gt; (j &amp;lt;= i))&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Wait. Why not &lt;code&gt;(\j -&amp;gt; (i &amp;lt;= j))&lt;/code&gt;?&lt;/p&gt;
  &lt;p&gt;The answer is that a section behaves differently when used with an infix operator. The argument is applied on the missing side. In other words &lt;code&gt;(/ 10)&lt;/code&gt; and &lt;code&gt;(10 /)&lt;/code&gt; are different.&lt;/p&gt;
  &lt;p&gt;So &lt;code&gt;(&amp;lt; 1) 2&lt;/code&gt; is &lt;code&gt;False&lt;/code&gt; but &lt;code&gt;(1 &amp;lt;) 2&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;. And &lt;code&gt;(compare 1) 2&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;In Haskell it&amp;rsquo;s &lt;em&gt;not&lt;/em&gt; the case that &lt;code&gt;(&amp;lt; 1)&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt; partially applied to the &lt;code&gt;&amp;lt;&lt;/code&gt; function, waiting to take a &amp;ldquo;right&amp;rdquo; argument.&lt;sup&gt;&lt;a href="#hands-on-with-haskell-footnote-1-definition" name="hands-on-with-haskell-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;h2 id="commas"&gt;Commas&lt;/h2&gt;
  &lt;p&gt;In working through &lt;a href="http://learnyouahaskell.com/"&gt;Learn You a Haskell&lt;/a&gt; I wanted to make an example input to try with &lt;code&gt;nub&lt;/code&gt;. I wanted a long list containing duplicates, that I didn&amp;rsquo;t have to type in by hand. To do so I wanted to do a Racket &lt;code&gt;flatten&lt;/code&gt; of a Haskell &lt;code&gt;replicate&lt;/code&gt; of a short list. It seemed like &lt;code&gt;foldr1&lt;/code&gt; with &lt;code&gt;++&lt;/code&gt; would be the way to do the &lt;code&gt;flatten&lt;/code&gt;. So I tried something like:&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;interactive&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="mi"&gt;107&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;Couldn&amp;#39;t&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;`[&lt;/span&gt;&lt;span class="n"&gt;a0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;
                &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;`(&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&amp;#39;&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="p"&gt;`(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;, namely `foldr&lt;/span&gt;&lt;span class="sc"&gt;1&amp;#39;&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;equation&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;it&amp;#39;&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Oops. Let&amp;rsquo;s try something simpler, first.&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;interactive&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="mi"&gt;245&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;Couldn&amp;#39;t&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;`[&lt;/span&gt;&lt;span class="n"&gt;a0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;
                &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;`(&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a1&amp;#39;&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="p"&gt;`(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;, namely `foldr&lt;/span&gt;&lt;span class="sc"&gt;1&amp;#39;&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;equation&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;it&amp;#39;&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Huh. Oh right. The &lt;code&gt;++&lt;/code&gt; is infix. Needs to go in parens. Try again:&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;interactive&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="mi"&gt;246&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;The&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="p"&gt;`[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt; is applied to one argument,&lt;/span&gt;
    &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;its&lt;/span&gt; &lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="p"&gt;`[&lt;/span&gt;&lt;span class="n"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt; has none&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;foldr1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;namely&lt;/span&gt; &lt;span class="p"&gt;`[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;&lt;/span&gt;
    &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="kt"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Bzzzt. Tried to decipher the error message. Finally remembered, dang, I need to separate list items with commas:&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;OK. And building back up again to what I&amp;rsquo;d wanted originally:&lt;/p&gt;
  &lt;div class="brush: hs"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nub&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;foldr1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replicate&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;In Lisps I&amp;rsquo;ve grown accustomed to &amp;mdash; and really love &amp;mdash; being able to separate list items with whitespace. Needing to use commas feels a bit weird. Also it&amp;rsquo;s a bit weird that you only use them for things like lists and tuples, but not in function applications. Oh well.&lt;/p&gt;
  &lt;h2 id="other-tiny-things"&gt;Other tiny things&lt;/h2&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;I keep making the mistake of typing &lt;code&gt;data MyType = _&lt;/code&gt; instead of  &lt;code&gt;data MyType = MyType _&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Racket &lt;code&gt;struct&lt;/code&gt;s define accessor functions prefixed with the name of  the struct. So &lt;code&gt;(struct person (name))&lt;/code&gt; defines a &lt;code&gt;person-name&lt;/code&gt;  accessor function. In Haskell, &lt;code&gt;data Person = Person {name ::
  String}&lt;/code&gt; defines an accessor &lt;code&gt;name&lt;/code&gt; &amp;mdash; no prefix. Problem being,  what if you have a couple types that have fields called &lt;code&gt;name&lt;/code&gt;? I  guess you have to do prefix the field names explicitly yourself,  e.g. &lt;code&gt;data Person = Person {personName :: String}&lt;/code&gt;?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;None of these observations are intended as a critique of Haskell. It&amp;rsquo;s an observation how the tiny things can trip you up when learning a new language. Even after a couple days, I&amp;rsquo;ve developed a sort of subconscious checklist of rookie mistakes to consider before trying to understand the Haskell error message.&lt;/p&gt;
  &lt;h1 id="nice-things"&gt;Nice things&lt;/h1&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;I like how creating a simple Haskell &amp;ldquo;project&amp;rdquo; (just for local use)  is as simple as creating a &lt;code&gt;.hs&lt;/code&gt; file. I also like this in Racket.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;I like having an actual, mature module system with clear best  practices (as in Racket).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;h1 id="my-first-hands-on-with-cabal"&gt;My first hands-on with Cabal&lt;/h1&gt;
  &lt;p&gt;I used Cabal for the first time, to install Pandoc. This took&amp;hellip; awhile. Finally I got a weird version error:&lt;/p&gt;
  &lt;pre&gt;&lt;code&gt;Configuring pandoc-1.13.1...
setup: At least the following dependencies are missing:
http-client &amp;gt;=0.3.2 &amp;amp;&amp;amp; &amp;lt;0.4 &amp;amp;&amp;amp; ==0.4.2.2
Updating documentation index /Users/greg/Library/Haskell/doc/index.html
cabal: Error: some packages failed to install:
pandoc-1.13.1 failed during the configure step. The exception was:
ExitFailure 1&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;After puzzling this over for awhile, and reading up on Cabal versioning, I didn&amp;rsquo;t have any great ideas. Finally I decided to try running &lt;code&gt;cabal install pandoc&lt;/code&gt; a second time. And this time, it worked. Shrug. Onward.&lt;/p&gt;
  &lt;h1 id="porting-wffi-to-haskell"&gt;Porting wffi to Haskell&lt;/h1&gt;
  &lt;p&gt;So after some &amp;ldquo;warm-up&amp;rdquo; I decided to dive in and try to port wffi to Haskell. This turned out to be a good-sized project when I was hands-on with Clojure &amp;mdash; not too small, not too big. Implementing it requires parsing markdown, parsing HTTP request templates, making HTTP requests, using higher-order functions, and so on.&lt;/p&gt;
  &lt;p&gt;I forged ahead and got the wffi port of Haskell working to the point that I could successfully make a request to &lt;a href="http://horseebooksipsum.com/"&gt;http://horseebooksipsum.com/&lt;/a&gt;. I had a little confusion at first about how &lt;code&gt;HTTP.Network.simpleHTTP&lt;/code&gt; returns &lt;code&gt;IO (Either String
String)&lt;/code&gt;. Basically, I didn&amp;rsquo;t anticipate where the IO vs. pure &amp;ldquo;boundary&amp;rdquo; would need to be in my program. But once I realized that, it made sense and was easy to sort out.&lt;/p&gt;
  &lt;p&gt;I pushed my commits to a GitHub public &lt;a href="https://github.com/greghendershott/haskell-wffi"&gt;repo&lt;/a&gt;, even though I&amp;rsquo;m sure the code smells pretty badly. My normal instinct is to spend more time with code &amp;mdash; beyond the &amp;ldquo;it&amp;rsquo;s amazing that the dancing bear dances at all&amp;rdquo; stage &amp;mdash; before pushing to public. But I&amp;rsquo;m at Hacker School, this isn&amp;rsquo;t professional coding, and I shouldn&amp;rsquo;t be so cautious. In fact, by pushing early, I could get some feedback.&lt;/p&gt;
  &lt;h2 id="surprisingly-easy"&gt;Surprisingly easy&lt;/h2&gt;
  &lt;p&gt;I was surprised by how quickly the port to Haskell went, compared to the port to Clojure. I would have guessed the opposite, because Clojure seems like it would be &amp;ldquo;closer to&amp;rdquo; Racket. I think there are two reasons why it was faster.&lt;/p&gt;
  &lt;p&gt;One is that I hadn&amp;rsquo;t worked on wffi for a year, so part of the Clojure port was actually reminding myself how things worked. In other words I&amp;rsquo;ve been &amp;ldquo;practicing&amp;rdquo; porting wffi, and the Haskell port got the benefit of that.&lt;/p&gt;
  &lt;p&gt;But also, I simply found Haskell easier to use than I expected. Sure, I frequently alternated between 10 minutes of smooth sailing and 5 minutes of trying to decipher a type error message. However, this felt different from being stalled on a Clojure build/environment/package issue. The Haskell type error messages felt like they turned out to be useful information about my reasoning about my program. Resolving them was sometimes a matter of fixing a simple mistake. Sometimes it entailed fixing a problem with my thinking and my design.&lt;sup&gt;&lt;a href="#hands-on-with-haskell-footnote-2-definition" name="hands-on-with-haskell-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;p&gt;My early days with Haskell have been more satisfying than those with Clojure. Whether that continues remains to be seen. So far so good.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="hands-on-with-haskell-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;It&amp;rsquo;s also not the case in Racket or Clojure. You&amp;rsquo;d have to say &lt;code&gt;(curry &amp;lt; 1)&lt;/code&gt; or &lt;code&gt;(partial &amp;lt; 1)&lt;/code&gt;. But &lt;em&gt;if&lt;/em&gt; those languages did automatic partial application, it would look like &lt;code&gt;(&amp;lt; 1)&lt;/code&gt;. At least that&amp;rsquo;s what my Lisp brain misunderstood at first.&amp;nbsp;&lt;a href="#hands-on-with-haskell-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
    &lt;li id="hands-on-with-haskell-footnote-2-definition" class="footnote-definition"&gt;
     &lt;p&gt;This is an experience I also had with Typed Racket.&amp;nbsp;&lt;a href="#hands-on-with-haskell-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Applicable symbols</title>
   <link>https://www.greghendershott.com/2014/10/applicable-symbols.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-applicable-symbols.html</guid>
   <pubDate>Mon, 27 Oct 2014 16:29:15 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Applicable symbols&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-27" pubdate="true"&gt;2014-10-27&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;Here are my notes about being puzzled about some Clojure code and diving into the implementation to figure it out. Although I figured it out the hard way, the exploration turned out to be interesting for me.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;As I was reading &lt;a href="http://www.zephyrizing.net/blog/2014/10/14/adventures-with-clojure-macros/"&gt;Geoff Shannon&amp;rsquo;s blog post&lt;/a&gt;, I was thinking, &amp;ldquo;Oh, maybe this will turn out to be a mixup between compile time and run time&amp;rdquo;. (At least, in my experience writing macros, it can be challenging to keep that straight.)&lt;/p&gt;
  &lt;p&gt;Instead, what confused me was line 103 in the last example (here I&amp;rsquo;ve changed the symbol from &lt;code&gt;'+&lt;/code&gt; to &lt;code&gt;'x&lt;/code&gt;):&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Huh? I don&amp;rsquo;t understand. Why does this return &lt;code&gt;2&lt;/code&gt;, instead of raising an error?&lt;/p&gt;
  &lt;p&gt;First, let&amp;rsquo;s factor out &lt;code&gt;apply&lt;/code&gt; and confirm the same result for a direct application:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;;=&amp;gt; 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Same result. Same mystery.&lt;/p&gt;
  &lt;p&gt;Let&amp;rsquo;s explore some examples:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;;=&amp;gt; ArityException Wrong number of args (0) passed to: Symbol  clojure.lang.AFn.throwArity (AFn.java:429)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;;=&amp;gt; nil  ???&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;;=&amp;gt; 2    ???&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; ArityException Wrong number of args (3) passed to: Symbol  clojure.lang.AFn.throwArity (AFn.java:429)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; clojure.lang.Symbol&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;There&amp;rsquo;s another mystery &amp;mdash; the arity 1 case of &lt;code&gt;('x 1)&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;To summarize so far: It appears that it is not an error to use a symbol in the function position of an application if the arity is 1 or 2.&lt;/p&gt;
  &lt;p&gt;I&amp;rsquo;m aware that Clojure collections are applicable. And I&amp;rsquo;m aware that Clojure tends to &lt;code&gt;nil&lt;/code&gt; pun. So the arity 1 case might be less surprising&amp;hellip; except that neither &lt;code&gt;'x&lt;/code&gt; nor &lt;code&gt;1&lt;/code&gt; is a collection, so this seems like it should raise an exception, not evaluate to &lt;code&gt;nil&lt;/code&gt;. And I don&amp;rsquo;t understand the arity 2 case.&lt;sup&gt;&lt;a href="#applicable-symbols-footnote-1-definition" name="applicable-symbols-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;What to do? I could ask for help. But let&amp;rsquo;s take this as an opportunity to go spelunking in some Clojure implementation code I&amp;rsquo;ve never seen before.&lt;/p&gt;
  &lt;p&gt;From looking at &lt;a href="https://github.com/clojure/clojure/blob/201a0dd9701e1a0ee3998431241388eb4a854ebf/src/jvm/clojure/lang/AFn.java"&gt;the source for clojure.lang.AFn&lt;/a&gt;, it seems that all &lt;code&gt;invoke&lt;/code&gt; members call &lt;code&gt;throwArity&lt;/code&gt;. It&amp;rsquo;s been some years since I did C++, and I&amp;rsquo;m not up-to-speed on Java. But if I understand correctly, &lt;code&gt;AFn&lt;/code&gt; is a sort of default class that always errors. Applicable things (functions, keywords, collections) probably derive from &lt;code&gt;AFn&lt;/code&gt; and override &lt;code&gt;invoke&lt;/code&gt; members to do something other than error. Somehow such a class is created for the symbol &lt;code&gt;'x&lt;/code&gt;, and I&amp;rsquo;m guessing that it overrides the arity 1 and 2 variants of &lt;code&gt;invoke&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;That seems plausible. So, how to find this in the Clojure source? Instead of searching the code on GitHub, let&amp;rsquo;s &lt;code&gt;git clone&lt;/code&gt; the source locally and use Emacs &lt;code&gt;rgrep&lt;/code&gt; to search for &lt;code&gt;invoke&lt;/code&gt;. I&amp;rsquo;m sure there are Java source navigation tools, but probably not worth choosing/installing/learning for something this straightforward. Yes &lt;code&gt;rgrep&lt;/code&gt; returns 1200+ matches, but flipping through them quickly there are some obvious patterns &amp;mdash; huge swaths that seem OK to ignore, and a few names that pop out.&lt;/p&gt;
  &lt;p&gt;For example in &lt;code&gt;APersistentMap.java&lt;/code&gt; I see arity 1 and 2 definitions of &lt;code&gt;invoke&lt;/code&gt;:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;valAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;valAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;That sure seems how &lt;code&gt;({:key val} :key)&lt;/code&gt; and &lt;code&gt;({:key val} :key
default)&lt;/code&gt; would work. &lt;code&gt;valAt&lt;/code&gt; is a core member function that does the lookup of a key and value in the map.&lt;/p&gt;
  &lt;p&gt;OK. Next let&amp;rsquo;s try to find a class that might correspond to a symbol like &lt;code&gt;'x&lt;/code&gt; and examine its &lt;code&gt;invoke&lt;/code&gt; member(s).&lt;/p&gt;
  &lt;p&gt;And bingo, here&amp;rsquo;s a file called &lt;code&gt;Symbol.java&lt;/code&gt;, also defining arity 1 and 2 variants of &lt;code&gt;invoke&lt;/code&gt;:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RT&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RT&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;So this seems to explain why arities 1 and 2 are special. Next question: What is &lt;code&gt;RT.get&lt;/code&gt;? In C++ this would mean a static &lt;code&gt;get&lt;/code&gt; member of an &lt;code&gt;RT&lt;/code&gt; class. That seems to be the case here, looking in &lt;code&gt;RT.java&lt;/code&gt;. &lt;code&gt;get&lt;/code&gt; comes in both arity 1 and 2 flavors (not counting the first argument; this is a static member so the implicit &lt;code&gt;this&lt;/code&gt; argument is explicit). First here&amp;rsquo;s arity 1:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;ILookup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ILookup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;valAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;getFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Which of the two paths here would &lt;code&gt;'x&lt;/code&gt; take? I&amp;rsquo;m going to make a guess that a symbol probably isn&amp;rsquo;t an instance of &lt;code&gt;ILookup&lt;/code&gt;, and what&amp;rsquo;s happening is the call to &lt;code&gt;getFrom&lt;/code&gt;. Which is defined in &lt;code&gt;RT.java&lt;/code&gt; as:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;IPersistentSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="n"&gt;IPersistentSet&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPersistentSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isArray&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;intValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nth&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;

	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;My guess is that all of the conditional branches fail for a symbol like &lt;code&gt;'x&lt;/code&gt;, and &lt;code&gt;getFrom&lt;/code&gt; returns Java &lt;code&gt;null&lt;/code&gt;. Which becomes Clojure &lt;code&gt;nil&lt;/code&gt;. First mystery solved.&lt;/p&gt;
  &lt;p&gt;How about arity 2? This is the case where a &amp;ldquo;not-found&amp;rdquo; value is supplied:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;ILookup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ILookup&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;valAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;getFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;getFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
	&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;IPersistentSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="n"&gt;IPersistentSet&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPersistentSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
		&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
			&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isArray&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
		&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;intValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
		&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;nth&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
	&lt;span class="o"&gt;}&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Aha. &lt;code&gt;('x 1 2)&lt;/code&gt; is being treated as, &amp;ldquo;Look up &lt;code&gt;1&lt;/code&gt; in &lt;code&gt;'x&lt;/code&gt; and if not found return &lt;code&gt;2&lt;/code&gt;&amp;rdquo;.&lt;/p&gt;
  &lt;h1 id="editorializing"&gt;Editorializing&lt;/h1&gt;
  &lt;p&gt;It makes sense to support a symbol in the function position of an application to enable doing this:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;key&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;    &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;key&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;key&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;        &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Of course. That&amp;rsquo;s awesome.&lt;/p&gt;
  &lt;p&gt;But when the second element is &lt;em&gt;not&lt;/em&gt; a collection? It should error. Looking up a key in an integer doesn&amp;rsquo;t make any sense. It is the result of a mistake. Clojure should tell you it&amp;rsquo;s an error. Returning something here is as bad as silent coercions in Javascript.&lt;/p&gt;
  &lt;h1 id="postscript"&gt;Postscript&lt;/h1&gt;
  &lt;p&gt;For what it&amp;rsquo;s worth, here&amp;rsquo;s how this works in &lt;a href="https://github.com/greghendershott/rackjure"&gt;&lt;code&gt;rackjure&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
  &lt;div class="brush: racket"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;rackjure&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;           &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;#:else&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;        &lt;span class="kd"&gt;#:else&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; 42&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;key&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;; applicable-dict: No dict? supplied&lt;/span&gt;
&lt;span class="c1"&gt;; in: (&amp;#39;key 1)&lt;/span&gt;
&lt;span class="c1"&gt;; Context:&lt;/span&gt;
&lt;span class="c1"&gt;;  /tmp/foo.rkt:1:1 [running body]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;One difference is that arity 3 means &lt;code&gt;assoc&lt;/code&gt;. If you want to supply an explicit default, you use an &lt;code&gt;#:else&lt;/code&gt; keyword argument.&lt;/p&gt;
  &lt;p&gt;The main difference is that a nonsense application results in an error.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="applicable-symbols-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;Spoiler: By the end of this, I remember there&amp;rsquo;s an optional not-found argument.&amp;nbsp;&lt;a href="#applicable-symbols-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hacker School day 15</title>
   <link>https://www.greghendershott.com/2014/10/hacker-school-day-15.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-hacker-school-day-15.html</guid>
   <pubDate>Sat, 25 Oct 2014 15:03:17 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hacker School day 15&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-25" pubdate="true"&gt;2014-10-25&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;I spent most of late Thursday and Friday working on open source projects that pre-date Hacker School.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;ul&gt;
   &lt;li&gt;Racket wanted to accept a &lt;a href="https://github.com/plt/racket/pull/756"&gt;pull request&lt;/a&gt; from me to fix a bug with  small bit-vectors. But because I had stumbled around before finding  the correct solution, and discussion on the PR, I&amp;rsquo;d accumulated  about 8 commits on the PR branch that needed to be squashed. Also,  the PR had been open for about 8 weeks, so I needed to fetch Racket  HEAD and build in order to test properly. Finally I needed to wait  for Travis CI to finish (the full builds of Racket there take ~30  minutes). In all, a fair amount of busywork, but that&amp;rsquo;s an important  part of the process.&lt;/li&gt;&lt;/ul&gt;
  &lt;ul&gt;
   &lt;li&gt;I fixed a &lt;a href="https://github.com/greghendershott/frog/issues/106"&gt;bug&lt;/a&gt; in my markdown parser. After boiling  it down to the minimal example, the problem was obvious; the parser  was sometimes returning an x-expression at a stage where a raw  &lt;code&gt;string?&lt;/code&gt; was expected &amp;mdash; in the case of an &lt;code&gt;&amp;lt;!-- HTML comment --&amp;gt;&lt;/code&gt;  inside a list item. The fix was simply deleting the check for the  HTML comment. Which made me suspicious. Had there been some intent  behind the check, even though it now seemed crazy? Or had the check  just been a brain fart? I decided it was the latter, after thinking  it through, and also seeing that all the unit tests (of which I have  many) still passed. So I added the fix, plus a couple regression  tests, &lt;a href="https://github.com/greghendershott/markdown/commit/0c2e8f8a4b1aa8df2d3ed2955f16553628ac4e08"&gt;committed&lt;/a&gt;, pushed, and commented/closed the issue on GitHub.&lt;/li&gt;&lt;/ul&gt;
  &lt;ul&gt;
   &lt;li&gt;I fixed a &lt;a href="https://github.com/greghendershott/racket-mode/issues/54"&gt;bug&lt;/a&gt; in my racket-mode for Emacs. Turns  out it wasn&amp;rsquo;t treating Unicode characters as symbol constituents,  causing a problem with some paredit operations. Fortunately I had  inherited the problem from scheme-mode, and knew that the problem  did &lt;em&gt;not&lt;/em&gt; occur in lisp-mode. As a result, it was straightforward to  track down. The fix was simply setting &lt;code&gt;multibyte-syntax-as-symbol&lt;/code&gt;  to &lt;code&gt;t&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;
  &lt;ul&gt;
   &lt;li&gt;I reviewed a &lt;a href="https://github.com/greghendershott/rackjure/pull/46"&gt;pull request for &lt;code&gt;#lang rackjure&lt;/code&gt;&lt;/a&gt; regarding how a  Racket &lt;code&gt;#lang&lt;/code&gt; could install a readtable for the REPL, without  doinking the readtable for other modules.&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;Of the three bugs, two turned out to be one-line fixes &amp;mdash; even though they took some time to figure out and to do &amp;ldquo;paperwork&amp;rdquo; like bug trackers and regression tests. On the one hand, such bugs feel like a low signal:noise ratio. On the other hand, they&amp;rsquo;re satisfying because they make you feel like the overall design/assumptions were good.&lt;/p&gt;
  &lt;p&gt;Also I did some work implementing Racket variants of some Clojure map-related functions like &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;get-in&lt;/code&gt;, &lt;code&gt;assoc-in&lt;/code&gt;, &lt;code&gt;update-in&lt;/code&gt;, &lt;code&gt;partition&lt;/code&gt;, &lt;code&gt;take&lt;/code&gt;,&lt;sup&gt;&lt;a href="#hacker-school-day-15-footnote-1-definition" name="hacker-school-day-15-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; and &lt;code&gt;juxt&lt;/code&gt;. More trivially, alias things like &lt;code&gt;every?&lt;/code&gt;, &lt;code&gt;some&lt;/code&gt;, &lt;code&gt;assoc&lt;/code&gt;, and &lt;code&gt;dissoc&lt;/code&gt; to their Racket equivalents. Although I haven&amp;rsquo;t yet pushed these to &lt;code&gt;#lang rackjure&lt;/code&gt; I may do so over the weekend.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;That was day 15 of about 60. On the one hand, it feels like a very long 3 weeks (in a good way). On the other hand, I can&amp;rsquo;t believe I&amp;rsquo;m already 25% through.&lt;/p&gt;
  &lt;p&gt;Time perceptions, how do they work?&lt;sup&gt;&lt;a href="#hacker-school-day-15-footnote-2-definition" name="hacker-school-day-15-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="hacker-school-day-15-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;Unlike Racket&amp;rsquo;s, this doesn&amp;rsquo;t raise an exception when there are fewer than N elements left, it just returns them. Which IMHO is more useful; in the past I&amp;rsquo;d written a &lt;code&gt;take&amp;lt;=&lt;/code&gt;.&amp;nbsp;&lt;a href="#hacker-school-day-15-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
    &lt;li id="hacker-school-day-15-footnote-2-definition" class="footnote-definition"&gt;
     &lt;p&gt;Also: Magnets.&amp;nbsp;&lt;a href="#hacker-school-day-15-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Why macros?</title>
   <link>https://www.greghendershott.com/2014/10/why-macros.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-why-macros.html</guid>
   <pubDate>Tue, 21 Oct 2014 17:56:54 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Why macros?&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-21" pubdate="true"&gt;2014-10-21&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Racket.html"&gt;Racket&lt;/a&gt;, &lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;Yesterday a couple people asked me, &amp;ldquo;How and why do you use macros in a Lisp like Racket or Clojure?&amp;rdquo;.&lt;/p&gt;
  &lt;p&gt;I gave answers like:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;The compiler can do a search-and-replace on your code.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;You can make DSLs.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;They&amp;rsquo;re an &amp;ldquo;API for the compiler&amp;rdquo;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;Although all true, I wasn&amp;rsquo;t sure I was getting the full idea across.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;Worse, one time Peter Seibel was within earshot. Although I don&amp;rsquo;t know if he heard my explanation, I imagined him biting his tongue and politely remembering the &amp;ldquo;well, actually&amp;rdquo; rule. :)&lt;/p&gt;
  &lt;p&gt;Later I remembered Matthias Felleisen boiling down macros into three main categories:&lt;/p&gt;
  &lt;ol&gt;
   &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Binding forms&lt;/strong&gt;. You can make your own syntax for binding values to identifiers, including function definition forms. You may hear people say, in a Lisp you don&amp;rsquo;t have to wait for the language designers to add a feature (like &lt;code&gt;lambda&lt;/code&gt; for Java?). Using macros you can add it yourself. Binding forms is one example.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Changing order of evaluation&lt;/strong&gt;. Something like &lt;code&gt;or&lt;/code&gt; or &lt;code&gt;if&lt;/code&gt; can&amp;rsquo;t really be a function, because you want it to &amp;ldquo;short-circuit&amp;rdquo; &amp;mdash; if the first test evaluates to true, don&amp;rsquo;t evaluate the other test at all.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Abstractions like domain specific langagues (DSLs)&lt;/strong&gt;. You want to provide a special language, which is simpler and/or more task-specific than the full/raw Lisp you&amp;rsquo;re using. This DSL might be for users of your software, and/or it might be something that you use to help implement parts of your own program.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
  &lt;p&gt;Every macro is doing one of those three things. Only macros can really do the first two, at all&lt;sup&gt;&lt;a href="#why-macros-footnote-1-definition" name="why-macros-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;. Macros let you do the last one more elegantly.&lt;/p&gt;
  &lt;p&gt;I think the preceding is a better answer. However, maybe it&amp;rsquo;s still not the best way to get people from zero to sixty on, &amp;ldquo;Why macros?&amp;rdquo;.&lt;sup&gt;&lt;a href="#why-macros-footnote-2-definition" name="why-macros-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;p&gt;Maybe the ideal is a &amp;ldquo;teachable moment&amp;rdquo; &amp;mdash; facing a problem that macrology would solve.&lt;sup&gt;&lt;a href="#why-macros-footnote-3-definition" name="why-macros-footnote-3-return"&gt;3&lt;/a&gt;&lt;/sup&gt; That&amp;rsquo;s also good because you really really &lt;em&gt;really&lt;/em&gt; don&amp;rsquo;t want to use a macro when a normal function would suffice. So the goal isn&amp;rsquo;t to get people &lt;em&gt;so&lt;/em&gt; enthusiastic about macros that they go forth in search of nails to which to apply that new hammer. Macros often aren&amp;rsquo;t the right approach. But once in a while, they are the bestest approach ever.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="why-macros-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;A language like Haskell can choose lazy evaluation, and implement &lt;code&gt;if&lt;/code&gt; as a function. I&amp;rsquo;m saying that only a macro can futz with whatever the default evaluation order is, be it eager or lazy.&amp;nbsp;&lt;a href="#why-macros-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
    &lt;li id="why-macros-footnote-2-definition" class="footnote-definition"&gt;
     &lt;p&gt;Although I wrote a guide called &lt;a href="http://www.greghendershott.com/fear-of-macros/"&gt;Fear of Macros&lt;/a&gt;, it&amp;rsquo;s (a) specific to Racket macros and (b) much more about the &amp;ldquo;how&amp;rdquo; than the &amp;ldquo;why&amp;rdquo;.&amp;nbsp;&lt;a href="#why-macros-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
    &lt;li id="why-macros-footnote-3-definition" class="footnote-definition"&gt;
     &lt;p&gt;Certainly that&amp;rsquo;s my own optimal learning situation, as opposed to getting answers or solutions before I have the questions or problems.&amp;nbsp;&lt;a href="#why-macros-footnote-3-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hands-on with Clojure day 5</title>
   <link>https://www.greghendershott.com/2014/10/hands-on-with-clojure-day-5.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-hands-on-with-clojure-day-5.html</guid>
   <pubDate>Tue, 21 Oct 2014 17:54:46 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hands-on with Clojure day 5&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-21" pubdate="true"&gt;2014-10-21&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;So I&amp;rsquo;ve fallen behind on the blogging, for a few reasons. Time to catch up.&lt;/p&gt;
  &lt;p&gt;I&amp;rsquo;m calling this &amp;ldquo;day 5&amp;rdquo; as a useful fiction. It&amp;rsquo;s a distillation of what is closer to days 5&amp;ndash;7, or something like that.&lt;/p&gt;
  &lt;p&gt;As I mentioned before, this series of blog posts is going more directly from brain to web. Reflection and editing? Not so much.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;h1 id="clojure-port-of-wffi"&gt;Clojure port of wffi&lt;/h1&gt;
  &lt;p&gt;I finished what I think is a reasonable initial port of wffi from Racket to Clojure. Pushed at &lt;a href="https://github.com/greghendershott/clojure-wffi"&gt;clojure-wffi&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;The simplest possible example is, given a &lt;code&gt;horseebooks.md&lt;/code&gt; file like this:&lt;/p&gt;
  &lt;pre&gt;&lt;code&gt;# horseebooksipsum.com

Endpoint: http://horseebooksipsum.com

# Get

## Request
````
GET /api/v1/{paragraphs}
````&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;You can write:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defwrappers&lt;/span&gt; &lt;span class="s"&gt;"horseebooks.md"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;pprint&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:paragraphs&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Which prints:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:orig-content-encoding&lt;/span&gt; &lt;span class="s"&gt;"gzip"&lt;/span&gt;,
 &lt;span class="ss"&gt;:trace-redirects&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"http://horseebooksipsum.com/api/v1/2"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;,
 &lt;span class="ss"&gt;:request-time&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;,
 &lt;span class="ss"&gt;:status&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;,
 &lt;span class="ss"&gt;:headers&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="s"&gt;"text/plain"&lt;/span&gt;,
  &lt;span class="s"&gt;"Transfer-Encoding"&lt;/span&gt; &lt;span class="s"&gt;"chunked"&lt;/span&gt;,
  &lt;span class="s"&gt;"Connection"&lt;/span&gt; &lt;span class="s"&gt;"close"&lt;/span&gt;,
  &lt;span class="s"&gt;"Vary"&lt;/span&gt; &lt;span class="s"&gt;"Accept-Encoding"&lt;/span&gt;,
  &lt;span class="s"&gt;"Cache-Control"&lt;/span&gt; &lt;span class="s"&gt;"no-cache"&lt;/span&gt;,
  &lt;span class="s"&gt;"Server"&lt;/span&gt; &lt;span class="s"&gt;"Apache/2.2.22 (Debian)"&lt;/span&gt;,
  &lt;span class="s"&gt;"Date"&lt;/span&gt; &lt;span class="s"&gt;"Tue, 21 Oct 2014 18:07:16 GMT"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;,
 &lt;span class="ss"&gt;:body&lt;/span&gt;
 &lt;span class="s"&gt;"Principle to work to make more money while having more fun. Unlucky people.&lt;/span&gt;
&lt;span class="s"&gt; And practical explanations. Process from preparation, through to delivery.&lt;/span&gt;
&lt;span class="s"&gt; And practical explanations. Process from preparation, through to delivery.&lt;/span&gt;
&lt;span class="s"&gt; And practical explanations. And practical explanations. Process from&lt;/span&gt;
&lt;span class="s"&gt; preparation, through to delivery. And practical explanations. And practical&lt;/span&gt;
&lt;span class="s"&gt; explanations. And practical explanations.\n\nDon&amp;#39;t stubbornly. This is a&lt;/span&gt;
&lt;span class="s"&gt; very special technique that I have never seen. Don&amp;#39;t stubbornly. This is&lt;/span&gt;
&lt;span class="s"&gt; a very special technique that I have never seen. And practical explanations.&lt;/span&gt;
&lt;span class="s"&gt; Don&amp;#39;t stubbornly. Principle to work to make more money while having more fun.&lt;/span&gt;
&lt;span class="s"&gt; Unlucky people. Process from preparation, through to delivery. Don&amp;#39;t&lt;/span&gt;
&lt;span class="s"&gt; stubbornly. Process from preparation, through to delivery. And practical&lt;/span&gt;
&lt;span class="s"&gt; explanations. This is a very special technique that I have never seen.&lt;/span&gt;
&lt;span class="s"&gt; And practical explanations. And practical explanations.\n\n"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Of course this simple example doesn&amp;rsquo;t show much value-add. But real-world web services often have numerous parameters allocated among URL path segments, query parameters, and headers. With wffi, useful keyword wrapper functions are automatically generated from a markdown file that both documents and specifies the web service.&lt;/p&gt;
  &lt;p&gt;If I weren&amp;rsquo;t at Hacker School, I would spend much more time polishing and refining this. However this project is really just a means to the end of learning Clojure. So I&amp;rsquo;m going to force myself to task-switch to something else, next. I&amp;rsquo;ll return to this project if/when it seems like the best vehicle to learn more.&lt;/p&gt;
  &lt;h1 id="split-with-and-lazy-seqs"&gt;&lt;code&gt;split-with&lt;/code&gt; and lazy seqs&lt;/h1&gt;
  &lt;p&gt;Previously I posted that &lt;code&gt;split-with&lt;/code&gt; seems to have an inefficient implementation.&lt;/p&gt;
  &lt;p&gt;Needing something like Racket&amp;rsquo;s &lt;code&gt;splitf-at&lt;/code&gt;, I wrote a quick and dirty version in Clojure:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;split&lt;/span&gt;
  &lt;span class="s"&gt;"FIXME: This is the conceptual, inefficient implementation. Should&lt;/span&gt;
&lt;span class="s"&gt;  reimplement like Racket&amp;#39;s splitf-at."&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;take-while &lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;drop-while &lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;This isn&amp;rsquo;t great because it traverses the first portion of the collection twice.&lt;/p&gt;
  &lt;p&gt;Someone pointed out that Clojure already provides this. It&amp;rsquo;s called &lt;code&gt;split-with&lt;/code&gt;. Nice. But when I 
   &lt;kbd&gt;M-.&lt;/kbd&gt;, I see that its definition is my conceptual one, not the efficient one.&lt;/p&gt;
  &lt;p&gt;Racket defines &lt;code&gt;splitf-at&lt;/code&gt; like so:&lt;/p&gt;
  &lt;div class="brush: racket"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/list..rkt)._splitf-at))" style="color: inherit"&gt;splitf-at&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/ts-reference/Legacy_Forms.html#(form._((lib._typed-racket/base-env/base-types-extra..rkt)._pred))" style="color: inherit"&gt;pred&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket/private/letstx-scheme..rkt)._unless))" style="color: inherit"&gt;unless&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/procedures.html#(def._((quote._~23~25kernel)._procedure~3f))" style="color: inherit"&gt;procedure?&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/ts-reference/Legacy_Forms.html#(form._((lib._typed-racket/base-env/base-types-extra..rkt)._pred))" style="color: inherit"&gt;pred&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/exns.html#(def._((quote._~23~25kernel)._raise-argument-error))" style="color: inherit"&gt;raise-argument-error&lt;/a&gt;&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/list..rkt)._splitf-at))" style="color: inherit"&gt;splitf-at&lt;/a&gt;&lt;/span&gt; &lt;span class="s2"&gt;"procedure?"&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/ts-reference/Legacy_Forms.html#(form._((lib._typed-racket/base-env/base-types-extra..rkt)._pred))" style="color: inherit"&gt;pred&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let))" style="color: inherit"&gt;let&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pfx&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" style="color: inherit"&gt;if&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket/private/letstx-scheme..rkt)._and))" style="color: inherit"&gt;and&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._pair~3f))" style="color: inherit"&gt;pair?&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/ts-reference/Legacy_Forms.html#(form._((lib._typed-racket/base-env/base-types-extra..rkt)._pred))" style="color: inherit"&gt;pred&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._car))" style="color: inherit"&gt;car&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cdr))" style="color: inherit"&gt;cdr&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cons))" style="color: inherit"&gt;cons&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._car))" style="color: inherit"&gt;car&lt;/a&gt;&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;pfx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/values.html#(def._((quote._~23~25kernel)._values))" style="color: inherit"&gt;values&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/private/list..rkt)._reverse))" style="color: inherit"&gt;reverse&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;pfx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;&lt;a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" style="color: inherit"&gt;list&lt;/a&gt;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;I &amp;ldquo;ported&amp;rdquo; this to Clojure like so:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;efficient-split-with&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;loop &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ps&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;, &lt;span class="nv"&gt;coll&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;and &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;pred&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;conj &lt;/span&gt;&lt;span class="nv"&gt;ps&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ps&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;One neat thing is the use of &lt;code&gt;conj&lt;/code&gt; with a &lt;code&gt;vector&lt;/code&gt; means we don&amp;rsquo;t have to do the &lt;code&gt;reverse&lt;/code&gt; like we do in Racket, which should be even more efficient.&lt;/p&gt;
  &lt;p&gt;So why does Clojure implement &lt;code&gt;split-with&lt;/code&gt; the way it does? David Nolen pointed out that I was forgetting about laziness. Aha.&lt;/p&gt;
  &lt;p&gt;In connection with this I learned about &amp;ldquo;chunked sequences&amp;rdquo; in Clojure from a &lt;a href="http://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/"&gt;Fogus blog post&lt;/a&gt;. Chunked sequences were added as an optimization in v1.1. The force granularity was increased from 1 item to 32.&lt;/p&gt;
  &lt;p&gt;Someone else pointed out that, had transducers been a thing, maybe lazy seqs wouldn&amp;rsquo;t be needed. (At least not as a default policy. You could have something like Racket&amp;rsquo;s &lt;a href="http://docs.racket-lang.org/reference/streams.html"&gt;&lt;code&gt;racket/stream&lt;/code&gt;&lt;/a&gt;, with laziness and memoization.)&lt;/p&gt;
  &lt;p&gt;I already understood, in theory, that side effects expose the difference between eager and lazy evaluation. I learned, hands on, that this includes side effects like ad hoc debugging &lt;code&gt;println&lt;/code&gt;s.&lt;sup&gt;&lt;a href="#hands-on-with-clojure-day-5-footnote-1-definition" name="hands-on-with-clojure-day-5-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt; For example if you have:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6
7&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                  &lt;span class="c1"&gt;;; 0: some bug that will throw an exception&lt;/span&gt;
                  &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nv"&gt;_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="s"&gt;"Everything AOK thus far -- or maybe not!"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="c1"&gt;;; 1: use coll in way that forces the lazy seq&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;The error won&amp;rsquo;t occur at 0, it will only occur at 1. The progress &lt;code&gt;println&lt;/code&gt; will be misleading. At least it misled me, for awhile, about the actual location of a bug.&lt;/p&gt;
  &lt;p&gt;With Clojure and Haskell, I&amp;rsquo;ll need to keep in mind when and where laziness is used as the default policy. If I understand correctly, in Clojure that means lazy sequences, and in Haskell lazy evaluation generally.&lt;/p&gt;
  &lt;h1 id="load-vs-modules"&gt;Load vs. modules&lt;/h1&gt;
  &lt;p&gt;After about a week hands-on with Clojure one of the things I miss the most from Racket is modules. Not even Racket&amp;rsquo;s submodules. Just plain modules.&lt;/p&gt;
  &lt;p&gt;Clojure namespaces handle name collisions. But modules go further:&lt;/p&gt;
  &lt;ol&gt;
   &lt;li&gt;
    &lt;p&gt;Forward references are OK.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Redefinitions are flagged as errors.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Deleted definitions actually disappear from the environment on re-eval of the source file.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
  &lt;p&gt;In other words, Clojure seems to be like Racket&amp;rsquo;s &lt;code&gt;#lang racket/load&lt;/code&gt;, which isn&amp;rsquo;t recommended for general use.&lt;/p&gt;
  &lt;p&gt;An example scenario: I rename a function from &lt;code&gt;foo&lt;/code&gt; to &lt;code&gt;bar&lt;/code&gt;. I overlook updating a call site. Clojure doesn&amp;rsquo;t warn me with an error. Worse, I change &lt;code&gt;bar&lt;/code&gt;&amp;rsquo;s behavior. But old &lt;code&gt;foo&lt;/code&gt; still exists &amp;mdash; and is being used at the overlooked call site. Hilarity and gnashing of teeth ensues.&lt;/p&gt;
  &lt;p&gt;This isn&amp;rsquo;t a hypothetical example. It&amp;rsquo;s happened to me a couple times in not that many days of hands-on with Clojure. On the one hand, this seems like an insane programming workflow. On the other hand, I have already learned to &amp;ldquo;measure twice, cut once&amp;rdquo; when renaming &amp;mdash; and to bite the bullet and invest 10 seconds in a cider-restart. So if life had to be this way, I could cope.&lt;/p&gt;
  &lt;p&gt;But why does it have to be this way? I actually started to draft a &lt;a href="https://github.com/greghendershott/clojure-module"&gt;&lt;code&gt;module&lt;/code&gt;&lt;/a&gt; macro for Clojure. As I put in its README:&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;: This is a first draft by someone who&amp;hellip;&lt;/p&gt;
   &lt;ul&gt;
    &lt;li&gt;
     &lt;p&gt;has been hands-on with Clojure for just a week&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;
     &lt;p&gt;doesn&amp;rsquo;t necessarily appreciate how Clojure namespaces work&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;
     &lt;p&gt;doesn&amp;rsquo;t know the complete story behind Racket modules&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;
  &lt;p&gt;I can imagine Inigo Montoya telling me, &amp;ldquo;I do not think &lt;code&gt;module&lt;/code&gt; means what you seem to think it means&amp;rdquo;. Yeah. That&amp;rsquo;s probably me, with &lt;a href="https://github.com/greghendershott/clojure-module"&gt;this code&lt;/a&gt;. At the moment it&amp;rsquo;s an exercise in starting to think about what might be involved.&lt;/p&gt;
  &lt;h1 id="conclusions-and-next-steps"&gt;Conclusions and next steps&lt;/h1&gt;
  &lt;p&gt;There is a lot about Clojure that I really, really like and enjoy. At times I do wish it had better tooling and were built on a more-rigorous foundation.&lt;/p&gt;
  &lt;p&gt;I need to determine what to do next &amp;mdash; spend more time with Clojure, or move on to Haskell. Also I need and want to spend significantly more time pairing with people here &amp;mdash; which will at least partially entail working with a variety of other languages and platforms.&lt;/p&gt;
  &lt;p&gt;So it&amp;rsquo;s likely that I&amp;rsquo;ll take at least a brief break from Clojure. But I&amp;rsquo;ll return at some point.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="hands-on-with-clojure-day-5-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;Are &lt;code&gt;println&lt;/code&gt;s a sophisticated debugging technique? Nope. But some experienced programmers use them as a quick first resort (even when they&amp;rsquo;re willing and able to fire up a real debugger).&amp;nbsp;&lt;a href="#hands-on-with-clojure-day-5-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hands-on with Clojure day 4</title>
   <link>https://www.greghendershott.com/2014/10/hands-on-with-clojure-day-4.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-hands-on-with-clojure-day-4.html</guid>
   <pubDate>Tue, 14 Oct 2014 21:52:11 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hands-on with Clojure day 4&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-14" pubdate="true"&gt;2014-10-14&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;Overview:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;Spent time with &lt;a href="https://github.com/clojure-cookbook/clojure-cookbook"&gt;Clojure Cookbook&lt;/a&gt;.&lt;/li&gt;
   &lt;li&gt;Started a &lt;a href="https://github.com/greghendershott/racket-clojure-cheat-sheet"&gt;cheat sheet&lt;/a&gt; for Racket ↔ Clojure.&lt;/li&gt;
   &lt;li&gt;Looked at &lt;code&gt;split-with&lt;/code&gt;.&lt;/li&gt;
   &lt;li&gt;Started a port of &lt;a href="https://github.com/greghendershott/wffi"&gt;wffi&lt;/a&gt; from Racket to Clojure.&lt;/li&gt;
   &lt;li&gt;Confusion: Aggregates and generics.&lt;/li&gt;&lt;/ul&gt;&lt;!-- more--&gt;
  &lt;h1 id="clojure-cookbook"&gt;Clojure Cookbook&lt;/h1&gt;
  &lt;p&gt;I discovered &lt;a href="https://github.com/clojure-cookbook/clojure-cookbook"&gt;Clojure Cookbook&lt;/a&gt;, which describes itself as:&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;&lt;em&gt;Clojure Cookbook&lt;/em&gt; doesn&amp;rsquo;t just teach you Clojure, it also shows you how to use the language and many of its common libraries. The most difficult part of mastering any language is knowing how to apply it, in an idiomatic way, to tasks that real software developers encounter every day. This is especially true of Clojure.&lt;/p&gt;
   &lt;p&gt;With code recipes that teach you how to use the language in a variety of domains, &lt;em&gt;Clojure Cookbook&lt;/em&gt; goes beyond simply teaching Clojure syntax and semantics. It contains annotated example code with detailed analysis and explanation for hundreds of real programming tasks. You can read the book straight through to gain insights about Clojure, or use it as a reference to solve particular problems.&lt;/p&gt;&lt;/blockquote&gt;
  &lt;p&gt;You can &lt;code&gt;git clone&lt;/code&gt; the &lt;a href="https://github.com/clojure-cookbook/clojure-cookbook"&gt;Clojure Cookbook&lt;/a&gt; project and work with it in Emacs. This is a nice experience.&lt;/p&gt;
  &lt;p&gt;You can read each section in an &lt;code&gt;adoc-mode&lt;/code&gt; buffer, with cider-repl active. That way you can 
   &lt;kbd&gt;C-x C-e&lt;/kbd&gt; to see the result on the Emacs status bar (or if you prefer, paste or type directly in the the cider-repl buffer).&lt;/p&gt;
  &lt;p&gt;Plus you can bind a key like 
   &lt;kbd&gt;M-+&lt;/kbd&gt; to an Elisp function that finds and advances to the next section.&lt;/p&gt;
  &lt;p&gt;I found most sections to be helpful. Not only do they show how to do X, they get into the rationale of when and why should use a certain Clojure approach vs. another. Very good stuff.&lt;/p&gt;
  &lt;h1 id="racket--clojure-cheat-sheet"&gt;Racket ↔ Clojure Cheat Sheet&lt;/h1&gt;
  &lt;p&gt;As I&amp;rsquo;ve learned Clojure equivalents for Racket functions, I&amp;rsquo;ve jotted them down in notes. The notes got long enough that I moved them into org-mode tables &amp;mdash; resulting in this &lt;a href="https://github.com/greghendershott/racket-clojure-cheat-sheet"&gt;cheat sheet&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;The first part covers, given Racket function X, what&amp;rsquo;s the exact or close equivalent Clojure function Y? The second part is for the other direction, from Clojure to Racket.&lt;/p&gt;
  &lt;p&gt;Again, these are my rough working notes. Don&amp;rsquo;t rely on it. I wouldn&amp;rsquo;t be shocked if some of it is subtly &amp;mdash; or blatantly &amp;mdash; wrong.&lt;/p&gt;
  &lt;p&gt;I found that, as is often the case with taking notes, the act of taking them makes it less-likely to need to refer to them.&lt;/p&gt;
  &lt;h1 id="cheat-sheets-split-with"&gt;Cheat sheets, &lt;code&gt;split-with&lt;/code&gt;&lt;/h1&gt;
  &lt;p&gt;Speaking of cheat sheets, on &lt;code&gt;#clojure&lt;/code&gt; someone reminded me of the &lt;a href="http://clojure.org/cheatsheet"&gt;Clojure cheatsheet&lt;/a&gt;. This seems like something to keep open in a browser tab. Or, say, print and paste on the inside of my forehead.&lt;/p&gt;
  &lt;p&gt;I was on IRC asking if Clojure had some equivalent to Racket&amp;rsquo;s &lt;a href="http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Flist..rkt%29._splitf-at%29%29"&gt;&lt;code&gt;splitf-at&lt;/code&gt;&lt;/a&gt;, with an implementation faster than the conceptual one I was able to come up with:&lt;/p&gt;
  &lt;div class="brush: clojure"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;split&lt;/span&gt;
  &lt;span class="s"&gt;"FIXME: This is the conceptual, inefficient implementation. Should&lt;/span&gt;
&lt;span class="s"&gt;  re-implement like Racket&amp;#39;s splitf-at."&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;take-while &lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;drop-while &lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Someone pointed out &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L2698"&gt;&lt;code&gt;split-with&lt;/code&gt;&lt;/a&gt;, which I could have found on the cheat sheet.&lt;/p&gt;
  &lt;p&gt;So that&amp;rsquo;s cool. However 
   &lt;kbd&gt;M-.&lt;/kbd&gt; on &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L2698"&gt;&lt;code&gt;split-with&lt;/code&gt;&lt;/a&gt; shows an implementation that is&amp;hellip; the conceptual one. I guess that could be a micro-project &amp;mdash; write an implementation that doesn&amp;rsquo;t excessively traverse and create intermediate collections.&lt;/p&gt;
  &lt;h1 id="wffi-for-clojure"&gt;wffi for Clojure&lt;/h1&gt;
  &lt;p&gt;A couple years ago, I was reading so much Amazon Web Services documentation that included what were essentially HTTP request and response templates. Such as the following, albeit much more complicated than this:&lt;/p&gt;
  &lt;pre&gt;&lt;code&gt;GET /users/{user}/?key={val}
Header: {value}
  ...&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Eventually it dawned on me that it would awfully be nice if web service documentation like this could actually drive code generation. Both generate client wrappers to make requests to the service, and, generate API glue for the service&amp;rsquo;s server. That was the idea behind &lt;a href="https://github.com/greghendershott/webapi-markdown"&gt;webapi-markdown&lt;/a&gt;. For example, you could take some service&amp;rsquo;s documentation, run it through a tool, and voila, an &amp;ldquo;SDK&amp;rdquo; in your favorite language.&lt;/p&gt;
  &lt;p&gt;So &lt;a href="https://github.com/greghendershott/webapi-markdown"&gt;webapi-markdown&lt;/a&gt; is just a spec. The one implementation to-date is in Racket: &lt;a href="https://github.com/greghendershott/wffi"&gt;wffi&lt;/a&gt;. (The name implying both &amp;ldquo;web FFI&amp;rdquo; and &amp;ldquo;stinky&amp;rdquo;.)&lt;/p&gt;
  &lt;p&gt;In searching for a somewhat more challenging project to do in Clojure, I figured this might fit the bill.&lt;/p&gt;
  &lt;p&gt;So I spent the last day working on it. It&amp;rsquo;s been slow going, but so far I&amp;rsquo;ve had a chance to learn:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;How to use &lt;a href="https://github.com/yogthos/markdown-clj"&gt;markdown-clj&lt;/a&gt; for parsing markdown. Although it returns  an HTML string, which isn&amp;rsquo;t ideal, it&amp;rsquo;s easy enough to convert that  using &lt;code&gt;tagsoup&lt;/code&gt; into structured data. (I keep thinking of these as  &amp;ldquo;Clojure&amp;rsquo;s equivalent of x-expressions&amp;rdquo;. Is this known as &amp;ldquo;hiccup&amp;rdquo;?  Not sure.)&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;How to use &lt;a href="https://github.com/Engelberg/instaparse"&gt;Instaparse&lt;/a&gt;. I only got a couple hours into this, but so  far it seems pretty spiffy. It was fun to see the acknowledgment in  the README that Danny Yoo&amp;rsquo;s &lt;a href="https://www.hashcollision.org/ragg/"&gt;Ragg&lt;/a&gt; was the inspiration. It is  definitely nice to use in the same way that Ragg is, and more.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;And eventually this project will get into areas like:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;Code-generation via Clojure macros.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Generating docs (via doc strings, I suppose).&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Distributing a project on Clojars (if I take it that far).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;So I think that&amp;rsquo;s a pretty good chunk of real-world stuff, which makes it worth pursuing this, even if there&amp;rsquo;s no value in releasing it per se.&lt;/p&gt;
  &lt;p&gt;The code is still pretty raw, and my grammar for Instaparse needs work. So I&amp;rsquo;m making commits, but not confident enough to push stuff to GitHub quite yet.&lt;/p&gt;
  &lt;h1 id="aggregates-and-generics"&gt;Aggregates and generics&lt;/h1&gt;
  &lt;p&gt;One area I&amp;rsquo;m still confused by is Clojure&amp;rsquo;s variety of approaches to aggregate data types and polymorphism.&lt;/p&gt;
  &lt;p&gt;Coming from Racket, we have structs and generics. &lt;code&gt;struct&lt;/code&gt;s have compile-time defined fields. As a result:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;They&amp;rsquo;re fast: A field is a direct offset.&lt;/li&gt;
   &lt;li&gt;They&amp;rsquo;re strict:
    &lt;ul&gt;
     &lt;li&gt;You can&amp;rsquo;t accidentally add or omit a field.&lt;/li&gt;
     &lt;li&gt;Structs can inherit fields from other structs, strictly.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;Of course we also have dictionaries (hash tables and association lists) when we want runtime flexibility.&lt;/p&gt;
  &lt;p&gt;My current impression is that Clojurians would often use a &lt;code&gt;map&lt;/code&gt; instead of a &lt;code&gt;struct&lt;/code&gt; in many situations. I think?&lt;/p&gt;
  &lt;p&gt;Clojure does have things that seem to be in the same ballpark as &lt;code&gt;struct&lt;/code&gt;s. &lt;code&gt;defrecord&lt;/code&gt; sounds like it is about &lt;code&gt;struct&lt;/code&gt;s. Is it sugar for maps? &lt;code&gt;deftype&lt;/code&gt; is, erm&amp;hellip; I don&amp;rsquo;t know. Clojure Cookbook has a quote from Chas Emerick:&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;Is your class modeling a domain value&amp;mdash;thus benefiting from hash map-like functionality and semantics? Use &lt;code&gt;defrecord&lt;/code&gt;.&lt;/p&gt;
   &lt;p&gt;Do you need to define mutable fields? Use &lt;code&gt;deftype&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
  &lt;p&gt;Hmm. That&amp;rsquo;s not what I would have guessed from the name, &amp;ldquo;type&amp;rdquo;. Plus, I thought mutability was strongly discouraged in Clojure.&lt;/p&gt;
  &lt;p&gt;The docs for &lt;code&gt;defrecord&lt;/code&gt; and &lt;code&gt;deftype&lt;/code&gt; seem a bit terse and opaque to me: The words make sense but aren&amp;rsquo;t crisply connecting to concepts I already know.&lt;/p&gt;
  &lt;p&gt;So, clearly I need to learn more in this space.&lt;/p&gt;
  &lt;h1 id="requires-are-less-often-but-still-tricky"&gt;Requires are less often, but still, tricky&lt;/h1&gt;
  &lt;p&gt;Although it&amp;rsquo;s much better, I still seem to get confused by requires. Good example is clj-tagsoup. I kept trying to &lt;code&gt;:require&lt;/code&gt; &lt;code&gt;pl.danieljanus.tagsoup.core&lt;/code&gt;. But it&amp;rsquo;s just &lt;code&gt;pl.danieljanus.tagsoup&lt;/code&gt;. The classpath error message isn&amp;rsquo;t very helpful for me. If I go in &lt;code&gt;~/.m2&lt;/code&gt; and look, I don&amp;rsquo;t see source files. I need to go up on GitHub and view the source. That&amp;rsquo;s how I eventually noticed it&amp;rsquo;s &lt;code&gt;src/pl/danieljanus/tagsoup.clj&lt;/code&gt;. Not e.g. &lt;code&gt;src/pl/danieljanus/tagsoup/core.clj&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;To be fair, I suppose this is really about one library&amp;rsquo;s choice. And I&amp;rsquo;m new to Clojure. But I don&amp;rsquo;t seem to struggle with this in Racket. Especially when an installed package has Scribble-generated docs, the docs automatically show a &lt;code&gt;(require foo)&lt;/code&gt; that, well, just works the first time.&lt;/p&gt;
  &lt;h1 id="reflection-and-next-steps"&gt;Reflection and next steps&lt;/h1&gt;
  &lt;p&gt;Notwithstanding my whinge in the previous section, I&amp;rsquo;m hitting tooling and cider speed bumps much less frequently. I felt like yesterday was the first time I could actually focus on the code, without distraction, for solid hours at a time. Although I still don&amp;rsquo;t feel like I&amp;rsquo;ve figured out an optimal Clojure workflow, it is easier for me to imagine such a thing being possible someday.&lt;/p&gt;
  &lt;p&gt;Next up, I plan to keep working on the wffi port, and see how far I can take that this remainder of this week.&lt;/p&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hands-on with Clojure day 3</title>
   <link>https://www.greghendershott.com/2014/10/hands-on-with-clojure-day-3.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-hands-on-with-clojure-day-3.html</guid>
   <pubDate>Fri, 10 Oct 2014 15:13:34 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hands-on with Clojure day 3&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-10" pubdate="true"&gt;2014-10-10&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;Please see the usual disclaimers from my &lt;a href="http://www.greghendershott.com/2014/10/hands-on-with-clojure.html"&gt;previous&lt;/a&gt; &lt;a href="http://www.greghendershott.com/2014/10/hands-on-with-clojure-day-2.html"&gt;posts&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;As I mentioned yesterday, my next toy project is to write wrappers libraries for the new &lt;a href="https://github.com/HackerNews/API"&gt;Hacker News API&lt;/a&gt;. This seems like a good exercise because the REST API is very simple, and I have experience doing this sort of thing in Racket. In fact, I&amp;rsquo;ll do the same thing in both Racket and Clojure.&lt;/p&gt;
  &lt;p&gt;The result is &lt;a href="https://github.com/greghendershott/clacker-news"&gt;clacker-news&lt;/a&gt; and &lt;a href="https://github.com/greghendershott/racker-news"&gt;racker-news&lt;/a&gt;. Trademark registration application is in-process.&lt;sup&gt;&lt;a href="#hands-on-with-clojure-day-3-footnote-1-definition" name="hands-on-with-clojure-day-3-footnote-1-return"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;Although I knew this would be a simple project, it turned out to be simpler than I expected:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;The Hacker News API is just a half-dozen items, so that helps.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Both Racket and Clojure have easy ways to parse JSON into the  relevant idiomatic representations. (As you might imagine, Racket  is more &lt;code&gt;list&lt;/code&gt;y and Clojure is more &lt;code&gt;vector&lt;/code&gt;y, but they are pretty  similar. Because JSON.)&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;I didn&amp;rsquo;t try to do anything fancy with error-handling. If there&amp;rsquo;s an  HTTP-related exception, it&amp;rsquo;s going to bubble up to the user of my  library. I think this is probably fine.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;I didn&amp;rsquo;t try to do anything fancy with retries. This is probably  less-fine. Given response like say &lt;code&gt;429 Too Many Requests&lt;/code&gt;, it would  nice if my library would automatically retry some number of times  (with an exponential delay back-off). But it doesn&amp;rsquo;t.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;However, maybe it was unduly easy &amp;mdash; because I overlooked something important in Clojure (or about making REST API requests in general). If so, feel free to hit the comments.&lt;/p&gt;
  &lt;h1 id="redefinitions-and-the-top-level"&gt;Redefinitions and the top-level&lt;/h1&gt;
  &lt;p&gt;While doing some copy-pasta of the Racket source to Clojure, I accidentally ended up with two &lt;code&gt;defn&lt;/code&gt;s of the same function, &lt;code&gt;get-user&lt;/code&gt;. The thing is, Clojure did &lt;em&gt;not&lt;/em&gt; give me an error message. This really surprised me. In Racket, this would be a redefinition error.&lt;/p&gt;
  &lt;p&gt;I guess this is related to my observation in yesterday&amp;rsquo;s post about the need to use &lt;code&gt;declare&lt;/code&gt; for forward references. If I understand correctly, this means that Clojure&amp;rsquo;s evaluation model is closer to a simple &lt;code&gt;load&lt;/code&gt;: It is essentially equivalent to typing stuff at a top-level REPL prompt. Things are evaluated one s-expression &lt;code&gt;read&lt;/code&gt; at a time.&lt;/p&gt;
  &lt;p&gt;So for example it&amp;rsquo;s perfectly fine to redefine something at the top-level in the REPL.&lt;/p&gt;
  &lt;p&gt;And, if you &lt;code&gt;read&lt;/code&gt; things one s-expression at a time &amp;mdash; as opposed to an entire file and/or namespace &amp;mdash; you can&amp;rsquo;t know about something that isn&amp;rsquo;t defined yet. You need a hint like &lt;code&gt;declare&lt;/code&gt;: &amp;ldquo;Chill, I&amp;rsquo;m going to supply it later.&amp;rdquo;&lt;/p&gt;
  &lt;p&gt;What I&amp;rsquo;m used to from Racket is an actual module system. As I understand it, the first unit of evaluation is a module. And the &lt;code&gt;#lang&lt;/code&gt; business is a shorthand for &lt;code&gt;module&lt;/code&gt; forms. In other words:&lt;/p&gt;
  &lt;div class="brush: racket"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;#lang &lt;/span&gt;&lt;span class="nn"&gt;racket&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax/parse..rkt)._id))" style="color: inherit"&gt;id&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;is shorthand for:&lt;/p&gt;
  &lt;div class="brush: racket"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/module.html#(form._((quote._~23~25kernel)._module))" style="color: inherit"&gt;module&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;racket&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&lt;a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" style="color: inherit"&gt;define&lt;/a&gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;&lt;a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax/parse..rkt)._id))" style="color: inherit"&gt;id&lt;/a&gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;And in fact you will see older Racket files that use the &lt;code&gt;module&lt;/code&gt; form explicitly like that (as well as newer &lt;code&gt;#lang&lt;/code&gt; files that use &lt;code&gt;module&lt;/code&gt; forms within, i.e. for nested modules).&lt;/p&gt;
  &lt;p&gt;Maybe I&amp;rsquo;m misunderstanding, and the business about modules is orthogonal to the business about redefinitions and forward references. Maybe that&amp;rsquo;s really about &lt;code&gt;read&lt;/code&gt;-ing s-expressions one at a time like in a top-level REPL. In any case, I don&amp;rsquo;t love this aspect of Clojure.&lt;sup&gt;&lt;a href="#hands-on-with-clojure-day-3-footnote-2-definition" name="hands-on-with-clojure-day-3-footnote-2-return"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;h1 id="next-steps"&gt;Next steps&lt;/h1&gt;
  &lt;p&gt;I need an idea for a gradually more-complicated project to try, next.&lt;/p&gt;
  &lt;p&gt;Ideally it would exercise something special/strong about Clojure, such as the persistent immutable data structures, concurrency primitives, or so on.&lt;/p&gt;
  &lt;p&gt;(As a counter-example, I could explore macros in Clojure, but my expectation is that&amp;rsquo;s an area that might be disappointing compared to Racket. Instead I&amp;rsquo;d like to find something where I&amp;rsquo;m more likely to say, &amp;ldquo;Dang, I wish Racket did this.&amp;rdquo;)&lt;/p&gt;
  &lt;p&gt;If you have suggestions, let me know in the comments, and thanks in advance.&lt;/p&gt;
  &lt;div class="footnotes"&gt;
   &lt;ol&gt;
    &lt;li id="hands-on-with-clojure-day-3-footnote-1-definition" class="footnote-definition"&gt;
     &lt;p&gt;Kidding.&amp;nbsp;&lt;a href="#hands-on-with-clojure-day-3-footnote-1-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
    &lt;li id="hands-on-with-clojure-day-3-footnote-2-definition" class="footnote-definition"&gt;
     &lt;p&gt;Among Racketeers, a famous quote is, &lt;a href="https://gist.github.com/samth/3083053"&gt;&amp;ldquo;the top-level is hopeless&amp;rdquo;&lt;/a&gt;.&amp;nbsp;&lt;a href="#hands-on-with-clojure-day-3-footnote-2-return"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item>
  <item>
   <title>Hands-on with Clojure day 2</title>
   <link>https://www.greghendershott.com/2014/10/hands-on-with-clojure-day-2.html</link>
   <guid isPermaLink="false">urn:www-greghendershott-com:-2014-10-hands-on-with-clojure-day-2.html</guid>
   <pubDate>Thu, 09 Oct 2014 14:58:46 UT</pubDate>
   <dc:creator>Greg Hendershott</dc:creator>
   <description>
&lt;div&gt;
 &lt;article&gt;
  &lt;header&gt;
   &lt;h1&gt;Hands-on with Clojure day 2&lt;/h1&gt;
   &lt;p class="date-and-tags"&gt;
    &lt;time datetime="2014-10-09" pubdate="true"&gt;2014-10-09&lt;/time&gt; :: &lt;span class="tags"&gt;&lt;a href="/tags/Clojure.html"&gt;Clojure&lt;/a&gt;, &lt;a href="/tags/Hacker-School.html"&gt;Hacker School&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/header&gt;
  &lt;p&gt;As with &lt;a href="http://www.greghendershott.com/2014/10/hands-on-with-clojure.html"&gt;yesterday&amp;rsquo;s post&lt;/a&gt;, important disclaimers:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;I&amp;rsquo;ve used &lt;a href="http://www.racket-lang.org"&gt;Racket&lt;/a&gt; heavily but not Clojure.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Opinions expressed herein are not those of my employer, were I to have one.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;If indignation lasts more than four hours, please seek medical attention.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;Day 2 with Clojure was much more fun! I didn&amp;rsquo;t hit speed bumps with tooling and workflow, so frequently. I was able to focus mostly on the code itself, which was wonderful.&lt;/p&gt;
  &lt;p&gt;For a &lt;em&gt;slightly&lt;/em&gt; more realistic task, I decided to make a really simple function that, given a URL, would make a &lt;code&gt;GET&lt;/code&gt; request and return the value of the &lt;code&gt;Server&lt;/code&gt; response header (if any), and a list of URLs found on the page that are for &lt;em&gt;other&lt;/em&gt; servers. The idea being, you could crawl from some starting point and accumulate some data about web server technology.&lt;/p&gt;&lt;!-- more--&gt;
  &lt;p&gt;To do this, I needed to understand how to:&lt;/p&gt;
  &lt;ol&gt;
   &lt;li&gt;
    &lt;p&gt;Make HTTP requests.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Parse an HTTP response entity (the HTML document) in a way I could  walk it to look for &lt;code&gt;&amp;lt;a href="foo"&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Miscellaneous other things.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
  &lt;h1 id="making-http-get-requests"&gt;Making HTTP &lt;code&gt;GET&lt;/code&gt; requests&lt;/h1&gt;
  &lt;p&gt;I discovered &lt;code&gt;clj-http&lt;/code&gt;. Added it to &lt;code&gt;projects.clj&lt;/code&gt;, and added &lt;code&gt;(:require [clj-http.client :as client])&lt;/code&gt; to my &lt;code&gt;core.clj&lt;/code&gt;. I got errors in cider. It worked fine with &lt;code&gt;lein repl&lt;/code&gt; at the command line. I did a &lt;code&gt;cider-restart&lt;/code&gt; and eventually it started it working.&lt;/p&gt;
  &lt;p&gt;Take-away: I&amp;rsquo;m starting to learn how to supplicate the system reliably, with certain incantations. But I don&amp;rsquo;t yet have a good mental model for the statefulness of adding a lib to a project and using it, at least not with cider.&lt;/p&gt;
  &lt;p&gt;Using &lt;code&gt;clj-http&lt;/code&gt; was a joy. Returns a nice map with key/value pairs I&amp;rsquo;d expect.&lt;/p&gt;
  &lt;h1 id="parsing-and-walking-html"&gt;Parsing and walking HTML&lt;/h1&gt;
  &lt;p&gt;Next, how to parse and walk the HTML in the &lt;code&gt;:body&lt;/code&gt;?&lt;/p&gt;
  &lt;p&gt;In Racket we typically use what are called &lt;code&gt;x-expressions&lt;/code&gt; to represent XML and (well-formed) HTML:&lt;/p&gt;
  &lt;div class="brush: racket"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;html&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;head&lt;/span&gt; &lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;p&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;attr&lt;/span&gt; &lt;span class="s2"&gt;"val"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;attr2&lt;/span&gt; &lt;span class="s2"&gt;"val2"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
           &lt;span class="s2"&gt;"Some text "&lt;/span&gt; &lt;span class="ss"&gt;amp&lt;/span&gt; &lt;span class="s2"&gt;" some more."&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;In other words this is an s-expression that follows a convention: There is a list. The first element is a symbol for the element tag name. The second element is an association-list of attributes. The zero or more remaining elements are either plain data like strings or numbers or symbols, or, other x-expressions.&lt;/p&gt;
  &lt;p&gt;I searched around and read about Enliven. That seemed like a heavier tool than I needed. On StackOverflow someone mentioned &lt;code&gt;clj-tagsoup&lt;/code&gt;. That looked like exactly what I wanted &amp;mdash; or at least was familiar with. To me, these look like x-expressions, but using vectors instead of lists, and using maps instead of association lists.&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1
2
3
4
5&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:html&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:head&lt;/span&gt; &lt;span class="p"&gt;{}]&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:attr&lt;/span&gt; &lt;span class="s"&gt;"val"&lt;/span&gt;, &lt;span class="ss"&gt;:attr2&lt;/span&gt; &lt;span class="s"&gt;"val2"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="s"&gt;"Some text &amp;amp; some more."&lt;/span&gt;&lt;span class="p"&gt;]]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Wonderful.&lt;/p&gt;
  &lt;p&gt;Adding that to my &lt;code&gt;project.clj&lt;/code&gt; and requiring it in my &lt;code&gt;core.clj&lt;/code&gt; was again weird. From the GitHub README and from Clojars.org, I&amp;rsquo;m not always sure when to use an organization-id prefix, and if so, what to use. I must be confusing myself because this seems like it should be simpler. At this stage, I try things until it works. The only catch being, I might need to use &lt;code&gt;cider-restart&lt;/code&gt; each time, otherwise I might not realize I actually did get it correct.&lt;/p&gt;
  &lt;p&gt;Anyway, once added and required properly, &lt;code&gt;clj-tagsoup&lt;/code&gt; was also a joy to use.&lt;/p&gt;
  &lt;h1 id="parsing-urls"&gt;Parsing URLs&lt;/h1&gt;
  &lt;p&gt;Now that things were working, I noticed that the list of URLs included many links to the same server. There&amp;rsquo;s no point in crawling those &amp;mdash; presumably the same web site is using the same web server. Instead I want to filter these to be only URLs for &lt;em&gt;other&lt;/em&gt; sites, so we can go crawl those and discover what &lt;em&gt;they&lt;/em&gt; return for &lt;code&gt;Server:&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;To do this, I want to split the URL into its components, and look at the scheme (a.k.a. protocol like &amp;ldquo;http&amp;rdquo;), hostname, and port, but disregard the rest. In Racket I would use &lt;code&gt;string-&amp;gt;url&lt;/code&gt;, which would return a &lt;code&gt;url&lt;/code&gt; struct having fields for each of these. How to do this in Clojure?&lt;/p&gt;
  &lt;p&gt;I couldn&amp;rsquo;t find an answer in the Clojure docs. For a minute I thought about using a regular expression. But I&amp;rsquo;ve seen the regexp that Racket&amp;rsquo;s &lt;code&gt;string-&amp;gt;url&lt;/code&gt; uses. A &lt;em&gt;correct&lt;/em&gt; regexp is non-trivial. Anyway this seems like a wheel I should not be reinventing.&lt;/p&gt;
  &lt;p&gt;I asked on #clojure IRC. Justin Smith and David Nolen quickly helped me out, showing me I could use &lt;code&gt;(bean (java.net.URL.
"http://www.google.com"))&lt;/code&gt;, which returns a map, members of which include &lt;code&gt;:protocol&lt;/code&gt;, &lt;code&gt;:host&lt;/code&gt;, &lt;code&gt;:port&lt;/code&gt;. Perfect.&lt;/p&gt;
  &lt;p&gt;Then I looked again at the map:&lt;/p&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:path&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;,
 &lt;span class="ss"&gt;:protocol&lt;/span&gt; &lt;span class="s"&gt;"http"&lt;/span&gt;,
 &lt;span class="ss"&gt;:ref&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;,
 &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;HttpInputStream&lt;/span&gt; &lt;span class="nv"&gt;sun.net.www.protocol.http.HttpURLConnection$HttpInputStream&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="nv"&gt;e01e8a&amp;gt;&lt;/span&gt;,
 &lt;span class="ss"&gt;:authority&lt;/span&gt; &lt;span class="s"&gt;"www.google.com"&lt;/span&gt;,
 &lt;span class="ss"&gt;:file&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;,
 &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="mi"&gt;-1&lt;/span&gt;,
 &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="s"&gt;"www.google.com"&lt;/span&gt;,
 &lt;span class="ss"&gt;:class&lt;/span&gt; &lt;span class="nv"&gt;java.net.URL&lt;/span&gt;,
 &lt;span class="ss"&gt;:query&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;,
 &lt;span class="ss"&gt;:defaultPort&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;,
 &lt;span class="ss"&gt;:userInfo&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;Hmm, what&amp;rsquo;s up with that part, &lt;code&gt;:content #&amp;lt;HttpInputStream
sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@56e01e8a&amp;gt;&lt;/code&gt;. That sure looks like an open connection. I don&amp;rsquo;t want to open a connection for all of these &amp;mdash; just parse/split the URL string into its components.&lt;/p&gt;
  &lt;p&gt;It seems that &lt;code&gt;bean&lt;/code&gt; calls all of the accessor members, and &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/net/URL.html#getContent%28%29"&gt;Java.Net.URL.getContent()&lt;/a&gt; has a side-effect:&lt;/p&gt;
  &lt;div class="brush: java"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;1&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;openConnection&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getContent&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;p&gt;So that&amp;rsquo;s not good. Back on IRC, just as I was typing, &amp;ldquo;I wonder if I can call the methods directly instead of using &lt;code&gt;bean&lt;/code&gt;&amp;rdquo;, Justin Smith said the same. Turns out he&amp;rsquo;d already posted a benchmark of &lt;code&gt;bean&lt;/code&gt; vs. directly calling select members, which is just what I needed.&lt;/p&gt;
  &lt;p&gt;Of course on my first attempt I managed to forget the trailing &lt;code&gt;.&lt;/code&gt; in &lt;code&gt;(java.net.URL. url)&lt;/code&gt; &amp;mdash; but then figured that out.&lt;/p&gt;
  &lt;p&gt;Take-aways:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    &lt;p&gt;I needed to learn about Java interop earlier than I expected. The interop &lt;em&gt;per se&lt;/em&gt; seems simple enough, and I&amp;rsquo;ll re-read that part of &lt;em&gt;Joy of Clojure&lt;/em&gt; today.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;I&amp;rsquo;m a bit worried I don&amp;rsquo;t yet know the Java library ecosystem. How will I know what&amp;rsquo;s available? But I guess library discoverability is a challenge for every language and language-learner. Maybe for Clojure the steps will be:&lt;/p&gt;
    &lt;ol&gt;
     &lt;li&gt;Search Clojure docs.&lt;/li&gt;
     &lt;li&gt;Search Clojars.&lt;/li&gt;
     &lt;li&gt;Search Java docs.&lt;/li&gt;
     &lt;li&gt;Ask on #clojure. Preferably as step 4 not 0. :)&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Justin Smith suggested the  &lt;a href="https://chrome.google.com/webstore/detail/javadoc-search-frame/mfgkihmpcjjnijmkchojlbccbmhcdfcd?hl=en"&gt;javadoc-search-pane&lt;/a&gt;  browser add-on for Chrome and Firefox as a great way to explore Java  docs.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;
    &lt;p&gt;Justin Smith is incredibly helpful! Thanks!&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
  &lt;h1 id="forward-declarations"&gt;Forward declarations&lt;/h1&gt;
  &lt;p&gt;One thing I find slightly annoying in Clojure is the need to use &lt;code&gt;declare&lt;/code&gt;, which isn&amp;rsquo;t necessary in Racket. If you like your source code to be &amp;ldquo;bottom up&amp;rdquo;, building up ingredients to a dramatic finale at the end of the source file, it&amp;rsquo;s not an issue. However, if you like to be &amp;ldquo;top-down&amp;rdquo;, starting with the main public product, and working down into the supporting cast, it can be awkward.&lt;/p&gt;
  &lt;h1 id="code"&gt;Code&lt;/h1&gt;
  &lt;div class="brush: clj"&gt;
   &lt;table class="sourcetable"&gt;
    &lt;tbody&gt;
     &lt;tr&gt;
      &lt;td class="linenos"&gt;
       &lt;div class="linenodiv"&gt;
        &lt;pre&gt;  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
      &lt;td class="code"&gt;
       &lt;div class="source"&gt;
        &lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;ns &lt;/span&gt;&lt;span class="nv"&gt;web-client.core&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:require&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;clj-http.client&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="nv"&gt;client&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;clojure.test&lt;/span&gt; &lt;span class="ss"&gt;:refer&lt;/span&gt; &lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:use&lt;/span&gt; &lt;span class="nv"&gt;pl.danieljanus.tagsoup&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;server&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:headers&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"Server"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Grumble: Needing to use `declare` is annoying compared to Racket.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;declare &lt;/span&gt;&lt;span class="nv"&gt;body-elements&lt;/span&gt;
         &lt;span class="nv"&gt;hrefs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;urls&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;entity&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;tree&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parse-string&lt;/span&gt; &lt;span class="nv"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;bodies&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;body-elements&lt;/span&gt; &lt;span class="nv"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hrefs&lt;/span&gt; &lt;span class="nv"&gt;bodies&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;body-elements&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;some &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;children &lt;/span&gt;&lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;children &lt;/span&gt;&lt;span class="nv"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;hrefs&lt;/span&gt;
  &lt;span class="s"&gt;"Given a collection of body elements, and a predicate, return all of&lt;/span&gt;
&lt;span class="s"&gt;  the link URLs on the page satisfying the predicate. For example the&lt;/span&gt;
&lt;span class="s"&gt;  predicate might be if the URLs are for another hostname, i.e. a link&lt;/span&gt;
&lt;span class="s"&gt;  to some other web server. "&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;xs&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter &lt;/span&gt;&lt;span class="nv"&gt;pred&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;flatten&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;coll?&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tag&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:href&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hrefs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;children &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
                &lt;span class="nv"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; TODO: Move this test elsewhere.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;find-hrefs&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;:p&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="s"&gt;"par"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:href&lt;/span&gt; &lt;span class="s"&gt;"http://hi.com"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:p&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                     &lt;span class="s"&gt;"par"&lt;/span&gt;
                     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:href&lt;/span&gt; &lt;span class="s"&gt;"http://there.com"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;"there"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                     &lt;span class="s"&gt;"par"&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
       &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"http://hi.com"&lt;/span&gt;
        &lt;span class="s"&gt;"http://there.com"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="c1"&gt;;; Grumble: Needing to use `declare` is annoying compared to Racket.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;declare &lt;/span&gt;&lt;span class="nv"&gt;valid-url?&lt;/span&gt; &lt;span class="nv"&gt;scheme+host+port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;server-equal?&lt;/span&gt;
  &lt;span class="s"&gt;"Predicate for two URLs having &amp;#39;the same server&amp;#39;, as determined by&lt;/span&gt;
&lt;span class="s"&gt;  having the same scheme, host, and port.&lt;/span&gt;

&lt;span class="s"&gt;  If either URL is malformed (according to java.net.URL) then this&lt;/span&gt;
&lt;span class="s"&gt;  returns t. That&amp;#39;s because the intended use of this is by&lt;/span&gt;
&lt;span class="s"&gt;  `get-server-and-links&amp;#39;. Of course that means the name&lt;/span&gt;
&lt;span class="s"&gt;  `server-equal?` isn&amp;#39;t quite right, and probably all this should be&lt;/span&gt;
&lt;span class="s"&gt;  refactored. TO-DO."&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;valid-url?&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;valid-url?&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;valid-url?&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="c1"&gt;;; Note: java.net.URL can throw an exception if the string is not a&lt;/span&gt;
  &lt;span class="c1"&gt;;; well-formed URL. In that case, return some default map.&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;try&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java.net.URL.&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catch&lt;/span&gt; &lt;span class="nv"&gt;java.net.MalformedURLException&lt;/span&gt; &lt;span class="nv"&gt;e&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;valid-url?&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;valid-url?&lt;/span&gt; &lt;span class="s"&gt;"#anchor"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn- &lt;/span&gt;&lt;span class="nv"&gt;scheme+host+port&lt;/span&gt;
  &lt;span class="s"&gt;"Given a URL, return a map of its scheme, host, and port."&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;loc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java.net.URL.&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:scheme&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.getProtocol&lt;/span&gt; &lt;span class="nv"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.getHost&lt;/span&gt; &lt;span class="nv"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.getPort&lt;/span&gt; &lt;span class="nv"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;)}))&lt;/span&gt;

&lt;span class="c1"&gt;;; TODO: Move this test elsewhere&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com/path/to/foo?q=0;p=1"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.giggle.com"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"https://www.goggle.com"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com:80"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.goggle.com:8080"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; TODO: Move this test elsewhere&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:scheme&lt;/span&gt; &lt;span class="s"&gt;"http"&lt;/span&gt;, &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="s"&gt;"www.google.com"&lt;/span&gt;, &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scheme+host+port&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com/path/to/foo?q=0;p=1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:scheme&lt;/span&gt; &lt;span class="s"&gt;"http"&lt;/span&gt;, &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="s"&gt;"www.google.com"&lt;/span&gt;, &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;get-server-and-links&lt;/span&gt;
  &lt;span class="s"&gt;"Given a URL, visit it and return a map with the value of the Server&lt;/span&gt;
&lt;span class="s"&gt;  response header (if any), and a collection of URLs for other hosts&lt;/span&gt;
&lt;span class="s"&gt;  to which it links (if any).&lt;/span&gt;

&lt;span class="s"&gt;  In other words, the intended use is that you&amp;#39;d crawl and accumulate&lt;/span&gt;
&lt;span class="s"&gt;  data about web server technology for some subset of teh interwebs."&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;client/get&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:server&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;server&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="ss"&gt;:urls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;urls&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;complement &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;partial &lt;/span&gt;&lt;span class="nv"&gt;server-equal?&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)))}))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;comment&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="nv"&gt;get-server-and-links&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://www.google.com"&lt;/span&gt;
                                       &lt;span class="s"&gt;"http://clojure.org"&lt;/span&gt;
                                       &lt;span class="s"&gt;"http://www.racket-lang.org"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
  &lt;h1 id="next-steps"&gt;Next Steps&lt;/h1&gt;
  &lt;p&gt;UPDATE: Oops, I posted without this part.&lt;/p&gt;
  &lt;p&gt;What next? Given that:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;I&amp;rsquo;m a roll with HTTP stuff in Clojure.&lt;/li&gt;
   &lt;li&gt;I&amp;rsquo;ve done wrappers for web services like &lt;a href="https://github.com/greghendershott/aws"&gt;AWS&lt;/a&gt; and &lt;a href="https://github.com/greghendershott/gapi"&gt;GAPI&lt;/a&gt; in Racket.&lt;/li&gt;
   &lt;li&gt;&lt;a href="https://news.ycombinator.com/news"&gt;Hacker News&lt;/a&gt; has a new, simple &lt;a href="https://github.com/HackerNews/API"&gt;REST API&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;
  &lt;p&gt;I think I might try writing wrappers libraries for Hacker News in both Clojure and Racket. As a plus, I can name them &lt;code&gt;clacker-news&lt;/code&gt; and &lt;code&gt;racker-news&lt;/code&gt;. I mean, maybe that&amp;rsquo;s a plus.&lt;/p&gt;
  &lt;p&gt;Thursdays are alumni days at &lt;a href="https://www.hackerschool.com"&gt;Hacker School&lt;/a&gt;, and if I understand correctly there are lightning talks (maybe this afternoon?). So maybe I&amp;rsquo;ll have less time to work on stuff today. But I can carry it over to tomorrow, as well.&lt;/p&gt;
  &lt;footer&gt;&lt;/footer&gt;&lt;/article&gt;&lt;/div&gt;</description></item></channel></rss>
