<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lojic Technologies Blog</title>
	<atom:link href="http://lojic.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lojic.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 30 Aug 2010 17:15:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Git commit message style</title>
		<link>http://lojic.com/blog/2010/08/30/git-commit-message-style/</link>
		<comments>http://lojic.com/blog/2010/08/30/git-commit-message-style/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 17:15:25 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=818</guid>
		<description><![CDATA[I just learned something about how git handles multi-line commit messages. If a commit message has a blank second line, git will treat the first line as the &#8220;subject&#8221; and the 3rd and following lines as the &#8220;body&#8221;. This will allow some nice things to be done with the git log command.
For example, the following [...]]]></description>
			<content:encoded><![CDATA[<p>I just learned something about how git handles multi-line commit messages. If a commit message has a blank second line, git will treat the first line as the &#8220;subject&#8221; and the 3rd and following lines as the &#8220;body&#8221;. This will allow some nice things to be done with the git log command.</p>
<p>For example, the following command:</p>
<pre>
git log --pretty=format:"%ai %an: %s%n%n%b%n"
</pre>
<p>Will produce output such as this:</p>
<pre>
2010-08-30 13:10:51 -0400 Brian Adkins: This is my second commit for this example.

And this is the body for the second commit.
Second line of the body.

2010-08-30 13:07:23 -0400 Brian Adkins: This text will be treated as the subject.

This text will be treated as the body. The subject should be
a short summary of the commit since you may want to show just
the subject on some git log invocations.
</pre>
<p>If you just want to see the &#8220;subject&#8221;, use:</p>
<pre>
git log --pretty=format:"%ai %an: %s%n"
</pre>
<p>Which will display as follows:</p>
<pre>
2010-08-30 13:10:51 -0400 Brian Adkins: This is my second commit for this example.

2010-08-30 13:07:23 -0400 Brian Adkins: This text will be treated as the subject.
</pre>
<p>See &#8220;git log &#8211;help&#8221; for various formatting specifications.</p>
<p>Thanks to Nathaniel Talbott for the chat message that prompted me to look into this.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2010/08/30/git-commit-message-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Precision Quadrotor Flying</title>
		<link>http://lojic.com/blog/2010/05/28/precision-quadrotor-flying/</link>
		<comments>http://lojic.com/blog/2010/05/28/precision-quadrotor-flying/#comments</comments>
		<pubDate>Fri, 28 May 2010 16:09:30 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[amazing]]></category>
		<category><![CDATA[robotics]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[physics]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=812</guid>
		<description><![CDATA[Wow &#8211; pretty amazing! HT Michael Hale via RT :)

]]></description>
			<content:encoded><![CDATA[<p>Wow &#8211; pretty amazing! HT Michael Hale via RT :)</p>
<p><object width="600" height="360"><param name="movie" value="http://www.youtube.com/v/MvRTALJp8DM&#038;color1=0xb1b1b1&#038;color2=0xd0d0d0&#038;hl=en_US&#038;feature=player_embedded&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/MvRTALJp8DM&#038;color1=0xb1b1b1&#038;color2=0xd0d0d0&#038;hl=en_US&#038;feature=player_embedded&#038;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="600" height="360"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2010/05/28/precision-quadrotor-flying/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switching from CarbonEmacs to Emacs.app</title>
		<link>http://lojic.com/blog/2010/03/17/switching-from-carbonemacs-to-emacs-app/</link>
		<comments>http://lojic.com/blog/2010/03/17/switching-from-carbonemacs-to-emacs-app/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 05:42:42 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=796</guid>
		<description><![CDATA[Thanks to a tip from David Joyner, I discovered that the current version of Emacs will easily build an Emacs.app application for Mac OSX i.e. I no longer need to install the CarbonEmacs application. I&#8217;m thankful to Seiji Zenitani for creating CarbonEmacs, but I&#8217;m glad to be able to build the app directly from the [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to a tip from David Joyner, I discovered that the current version of Emacs will easily build an Emacs.app application for Mac OSX i.e. I no longer need to install the CarbonEmacs application. I&#8217;m thankful to Seiji Zenitani for creating CarbonEmacs, but I&#8217;m glad to be able to build the app directly from the latest Emacs source code.</p>
<p>Here&#8217;s what I did:</p>
<h1>Get the source code and build it</h1>
<pre>
git clone git://git.savannah.gnu.org/emacs.git
cd emacs
./configure --with-ns
make install
</pre>
<h1>Copy Emacs.app to Applications</h1>
<p>Drag nextstep/Emacs.app to Applications</p>
<h2>Modify Emacs config files</h2>
<p>I had several configuration items I needed to adjust.</p>
<h3>carbon-emacs-package-add-to-path no longer exists</h2>
<p>I used the above command to set the path to allow running programs via shell-command as follows:</p>
<pre>
(carbon-emacs-package-add-to-path "/Users/badkins/sync/bin")
(defun my-fun ()
  (interactive)
  (shell-command "my_ruby_script.rb"))
</pre>
<p>I found a comment by Alex Payne on Ola Bini&#8217;s blog that provided an equivalent for Emacs.app:</p>
<pre>
(setq path "/Users/badkins/sync/bin")
(setenv "PATH" path)
</pre>
<h3>Use command for meta instead of alt/option</h3>
<p>The newly built Emacs.app used the alt/option key for meta instead of the command key that I was used to with CarbonEmacs. The following (found on Hacker News) took care of that:</p>
<pre>
(setq ns-command-modifier 'meta)
</pre>
<p>Prior to the above, I had tried the following. It worked, but was more verbose:</p>
<pre>
(setq mac-option-key-is-meta nil)
(setq mac-command-key-is-meta t)
(setq mac-command-modifier 'meta)
(setq mac-option-modifier nil)
</pre>
<h3>Allow use of command-h to minimize Emacs</h3>
<p>After the above fix for the command key, I could no longer minimize Emacs via command-h because Emacs mapped M-h to a command. The following key binding allowed using M-h to minimize again:</p>
<pre>
(global-set-key (kbd "M-h") 'ns-do-hide-emacs)
</pre>
<h3>Customize exec-path variable</h3>
<p>I was having difficulty using the built-in vc git support. It turns out that Emacs wasn&#8217;t able to find the git command because it wasn&#8217;t in the exec-path. I customized the exec-path variable to include /opt/local/bin where git resides as follows (it&#8217;s within the custom-set-variables invocation):</p>
<pre>
 '(exec-path (quote ("/usr/bin" "/bin" "/usr/sbin" "/sbin" "/Applications/Emacs.app/Contents/MacOS/bin" "/opt/local/bin")))
</pre>
<h2>Emacs is Awesome</h2>
<p>That was all it took to get the latest Emacs up and running equivalently to CarbonEmacs for me. I&#8217;m more pleased with Emacs today than when I started using it in earnest in 2008. I&#8217;m continually learning new things to be more productive. There are just so many things that it does very well, and it&#8217;s so extensible and introspective.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2010/03/17/switching-from-carbonemacs-to-emacs-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Art of Innovation</title>
		<link>http://lojic.com/blog/2009/11/12/the-art-of-innovation/</link>
		<comments>http://lojic.com/blog/2009/11/12/the-art-of-innovation/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 21:15:59 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[marketing]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=790</guid>
		<description><![CDATA[Found this Guy Kawasaki video on Duff O&#8217;Melia&#8217;s blog and enjoyed it.
 
]]></description>
			<content:encoded><![CDATA[<p>Found this Guy Kawasaki video on Duff O&#8217;Melia&#8217;s blog and enjoyed it.</p>
<p><embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=-3459408090550854446&#038;hl=en" flashvars=""> </embed></p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/11/12/the-art-of-innovation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming Language Popularity &#8211; Part Two</title>
		<link>http://lojic.com/blog/2009/10/24/programming-language-popularity-part-two/</link>
		<comments>http://lojic.com/blog/2009/10/24/programming-language-popularity-part-two/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 15:23:23 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[forth]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[ocaml]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[smalltalk]]></category>
		<category><![CDATA[sml]]></category>
		<category><![CDATA[tcl]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=781</guid>
		<description><![CDATA[I compiled some programming language popularity statistics in April and mentioned I&#8217;d update the results in 6 months, so here they are:
I made a number of Google searches of the forms below and averaged the results:
"implemented in &#60;language&#62;"
"written in &#60;language&#62;"



Language
# Results
Apr 09
# Results
Oct 09
Position
Delta


C
1,905,500
16,975,000
0


C++
699,000
6,270,000
+1


Java
850,000
5,118,000
-1


PHP
680,000
5,083,500
0


Lisp Family1
176,507
3,489,650
+3


Python
396,000
3,407,000
-1


Perl
365,500
3,132,500
-1


C#
349,700
2,125,000
-1


Scheme
86,450
2,100,000
+2


FORTRAN

1,621,000
N/A


JavaScript
102,700
1,163,000
-1


ML Family2
29,062
1,003,800
+3



(S)ML3
5,173
590,700
+12


Common Lisp
20,600
554,500
+5


Lisp
61,900
486,500
-2


Prolog
17,750
390,500
+4


Tcl
44,800
382,000
-3


OCaml
22,000
343,500
0


Arc
6,775
286,500
+4


Haskell
22,550
280,500
-4


COBOL

247,300
N/A


Ruby
99,650
227,000
-10


Io
1,760
198,500
+6


Smalltalk
9,105
187,500
-1


Erlang
22,285
161,700
-7


Forth
6,465
146,450
-1


Lua
13,065
131,800
-5


Caml
1,889
69,600
0


Scala
3,570
66,250
-2


Clojure
782
62,200
0



1 combines Lisp, Scheme, Common Lisp, Arc &#38; Clojure
2 [...]]]></description>
			<content:encoded><![CDATA[<p>I compiled some <a href="http://lojic.com/blog/2009/04/21/programming-language-popularity/">programming language popularity</a> statistics in April and mentioned I&#8217;d update the results in 6 months, so here they are:</p>
<p>I made a number of Google searches of the forms below and averaged the results:</p>
<pre class="code">"implemented in &lt;language&gt;"
"written in &lt;language&gt;"</pre>
<table border="0">
<tbody>
<tr>
<th>Language</th>
<th style="text-align: right;"># Results<br />
Apr 09</th>
<th style="text-align: right;"># Results<br />
Oct 09</th>
<th style="text-align: right;">Position<br />
Delta</th>
</tr>
<tr>
<td>C</td>
<td style="text-align: right;">1,905,500</td>
<td style="text-align: right;">16,975,000</td>
<td style="text-align: right;">0</td>
</tr>
<tr>
<td><strong>C++</strong></td>
<td style="text-align: right;">699,000</td>
<td style="text-align: right;">6,270,000</td>
<td style="text-align: right;"><strong>+1</strong></td>
</tr>
<tr>
<td>Java</td>
<td style="text-align: right;">850,000</td>
<td style="text-align: right;">5,118,000</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td>PHP</td>
<td style="text-align: right;">680,000</td>
<td style="text-align: right;">5,083,500</td>
<td style="text-align: right;">0</td>
</tr>
<tr>
<td><strong>Lisp Family<sup>1</sup></strong></td>
<td style="text-align: right;">176,507</td>
<td style="text-align: right;">3,489,650</td>
<td style="text-align: right;"><strong>+3</strong></td>
</tr>
<tr>
<td>Python</td>
<td style="text-align: right;">396,000</td>
<td style="text-align: right;">3,407,000</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td>Perl</td>
<td style="text-align: right;">365,500</td>
<td style="text-align: right;">3,132,500</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td>C#</td>
<td style="text-align: right;">349,700</td>
<td style="text-align: right;">2,125,000</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td><strong>Scheme</strong></td>
<td style="text-align: right;">86,450</td>
<td style="text-align: right;">2,100,000</td>
<td style="text-align: right;"><strong>+2</strong></td>
</tr>
<tr>
<td>FORTRAN</td>
<td style="text-align: right;"></td>
<td style="text-align: right;">1,621,000</td>
<td style="text-align: right;">N/A</td>
</tr>
<tr>
<td>JavaScript</td>
<td style="text-align: right;">102,700</td>
<td style="text-align: right;">1,163,000</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td><strong>ML Family<sup>2</sup></strong></td>
<td style="text-align: right;">29,062</td>
<td style="text-align: right;">1,003,800</td>
<td style="text-align: right;"><strong>+3</strong></td>
</tr>
<p><!-- use ML and SML --></p>
<tr>
<td><strong>(S)ML<sup>3</sup></strong></td>
<td style="text-align: right;">5,173</td>
<td style="text-align: right;">590,700</td>
<td style="text-align: right;"><strong>+12</strong></td>
</tr>
<tr>
<td><strong>Common Lisp</strong></td>
<td style="text-align: right;">20,600</td>
<td style="text-align: right;">554,500</td>
<td style="text-align: right;"><strong>+5</strong></td>
</tr>
<tr>
<td>Lisp</td>
<td style="text-align: right;">61,900</td>
<td style="text-align: right;">486,500</td>
<td style="text-align: right;">-2</td>
</tr>
<tr>
<td><strong>Prolog</strong></td>
<td style="text-align: right;">17,750</td>
<td style="text-align: right;">390,500</td>
<td style="text-align: right;"><strong>+4</strong></td>
</tr>
<tr>
<td>Tcl</td>
<td style="text-align: right;">44,800</td>
<td style="text-align: right;">382,000</td>
<td style="text-align: right;">-3</td>
</tr>
<tr>
<td>OCaml</td>
<td style="text-align: right;">22,000</td>
<td style="text-align: right;">343,500</td>
<td style="text-align: right;">0</td>
</tr>
<tr>
<td><strong>Arc</strong></td>
<td style="text-align: right;">6,775</td>
<td style="text-align: right;">286,500</td>
<td style="text-align: right;"><strong>+4</strong></td>
</tr>
<tr>
<td>Haskell</td>
<td style="text-align: right;">22,550</td>
<td style="text-align: right;">280,500</td>
<td style="text-align: right;">-4</td>
</tr>
<tr>
<td>COBOL</td>
<td style="text-align: right;"></td>
<td style="text-align: right;">247,300</td>
<td style="text-align: right;">N/A</td>
</tr>
<tr>
<td>Ruby</td>
<td style="text-align: right;">99,650</td>
<td style="text-align: right;">227,000</td>
<td style="text-align: right;">-10</td>
</tr>
<tr>
<td><strong>Io</strong></td>
<td style="text-align: right;">1,760</td>
<td style="text-align: right;">198,500</td>
<td style="text-align: right;"><strong>+6</strong></td>
</tr>
<tr>
<td>Smalltalk</td>
<td style="text-align: right;">9,105</td>
<td style="text-align: right;">187,500</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td>Erlang</td>
<td style="text-align: right;">22,285</td>
<td style="text-align: right;">161,700</td>
<td style="text-align: right;">-7</td>
</tr>
<tr>
<td>Forth</td>
<td style="text-align: right;">6,465</td>
<td style="text-align: right;">146,450</td>
<td style="text-align: right;">-1</td>
</tr>
<tr>
<td>Lua</td>
<td style="text-align: right;">13,065</td>
<td style="text-align: right;">131,800</td>
<td style="text-align: right;">-5</td>
</tr>
<tr>
<td>Caml</td>
<td style="text-align: right;">1,889</td>
<td style="text-align: right;">69,600</td>
<td style="text-align: right;">0</td>
</tr>
<tr>
<td>Scala</td>
<td style="text-align: right;">3,570</td>
<td style="text-align: right;">66,250</td>
<td style="text-align: right;">-2</td>
</tr>
<tr>
<td>Clojure</td>
<td style="text-align: right;">782</td>
<td style="text-align: right;">62,200</td>
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
<p><sup>1</sup> combines Lisp, Scheme, Common Lisp, Arc &amp; Clojure<br />
<sup>2</sup> combines OCaml, (S)ML, Caml<br />
<sup>3</sup> summed separate searches for sml and ml</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/10/24/programming-language-popularity-part-two/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Daniel Weinreb re: Lisp use at ITA</title>
		<link>http://lojic.com/blog/2009/08/29/daniel-weinreb-re-lisp-use-at-ita/</link>
		<comments>http://lojic.com/blog/2009/08/29/daniel-weinreb-re-lisp-use-at-ita/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 18:31:17 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[lisp]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=770</guid>
		<description><![CDATA[Some random notes:

650 KLOC plus 150 KLOC of open source code
100 people on the team, 70 programmers
SBCL for the QPX product
Clozure CL for the reservations product
Availability requirement: four 9&#8217;s => less than 53 minutes downtime per year

Latency agreement

90% of requests w/in 300 ms
5% of requests w/in 600 ms
5% of requests w/in 1,200 ms


Java presentation layer, [...]]]></description>
			<content:encoded><![CDATA[<p>Some random notes:</p>
<ul>
<li>650 KLOC plus 150 KLOC of open source code</li>
<li>100 people on the team, 70 programmers</li>
<li>SBCL for the QPX product</li>
<li>Clozure CL for the reservations product</li>
<li>Availability requirement: four 9&#8217;s => less than 53 minutes downtime per year</li>
<li>
Latency agreement</p>
<ul>
<li>90% of requests w/in 300 ms</li>
<li>5% of requests w/in 600 ms</li>
<li>5% of requests w/in 1,200 ms</li>
</ul>
</li>
<li>Java presentation layer, Common Lisp stateless business layer, Oracle data layer</li>
<li>Daniel is very positive about Clojure</li>
<li>Some links from the talk:
<ul>
<li><a href="http://common-lisp.net/~dlw/LispSurvey.html">Survey of Common Lisp Implementations</a></li>
<li><a href="http://ilc2009.scheming.org/">International Lisp Conference 2009 Discusison Forum</a></li>
<li><a href="http://danweinreb.org/blog">Dan Weinreb&#8217;s Blog</a></li>
</ul>
</li>
</ul>
<p><br/><br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/xquJvmHF3S8&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/xquJvmHF3S8&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/08/29/daniel-weinreb-re-lisp-use-at-ita/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Haskell In The Finals</title>
		<link>http://lojic.com/blog/2009/08/18/haskell-in-the-finals/</link>
		<comments>http://lojic.com/blog/2009/08/18/haskell-in-the-finals/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 16:36:16 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=717</guid>
		<description><![CDATA[As I explain in 2009 Programming Language Plan, I&#8217;ve been in the process of evaluating programming languages to determine their suitability for use in my work. I&#8217;ve been proceeding on two fronts &#8211; statically typed functional programming languages and the venerated Lisp family.
Haskell The Hope Of The Statically Typed Family
After many hours of research and [...]]]></description>
			<content:encoded><![CDATA[<p>As I explain in <a href="http://lojic.com/blog/2009/04/27/2009-programming-language-plan/">2009 Programming Language Plan</a>, I&#8217;ve been in the process of evaluating programming languages to determine their suitability for use in my work. I&#8217;ve been proceeding on two fronts &#8211; statically typed functional programming languages and the venerated Lisp family.</p>
<p><strong>Haskell The Hope Of The Statically Typed Family</strong></p>
<p>After many hours of research and a brief dive into Standard ML, I&#8217;ve selected Haskell as <em>the</em> best candidate for me to evaluate statically typed functional programming languages. At this point, I&#8217;m subjectively biased against <em>statically typed</em> functional programming languages because of the enjoyment and productivity I&#8217;ve found in Ruby &amp; Lisp, but my only experience with statically typed languages (C, C++, Java) has not been representative of <em>good</em> statically typed languages, so I&#8217;m reluctant to form a strong opinion of static typing before I&#8217;ve become proficient in a <em>good</em> statically typed language. </p>
<p>There are, of course, a number of respected statically typed functional programming languages, but I think Haskell provides me with the best opportunity to make a personal assessment regarding the benefits of static typing for my particular situation, and I think someone would be hard pressed to convince me that it&#8217;s a poor choice objectively.</p>
<p><strong>There Can Be Only One</strong></p>
<p>After working halfway through <em>Programming in Standard ML</em> by Robert Harper, I realized that I enjoy the language and it seems <em>simpler</em> &amp; <em>cleaner</em> than Haskell, but I also realized that I only have time to become truly <em>proficient</em> in one statically typed functional programming language in the near future. I feel that a reasonable level of proficiency is required to evaluate a language well. I have seen many examples of someone, with only a little knowledge of a programming language, making an unfounded criticism of a programming language, or a particular feature, only to be corrected with an accurate, elegant and convincing counter argument by someone who is experienced with the language. </p>
<p>A quick survey of a language won&#8217;t be enough for me to make a decision on some key points such as static vs. dynamic, nonstrict vs. strict, pure vs. impure, etc. as well as important peripheral issues such as existing libraries, tools, etc. &#8211; it&#8217;s going to require understanding some of the subtleties of the language and writing enough code to get a feel for the language, so I felt I needed to limit my choice to one statically typed FPL.</p>
<p><strong>Static vs. Dynamic</strong></p>
<p>Clearly <em>both</em> static and dynamic typing work well for large numbers of people. One of my goals is simply to answer the static vs. dynamic question for <em>myself</em> given my preferences and the type of software I want to develop. I&#8217;d previously decided to learn <em>both</em> Standard ML and Haskell, so my reasons below for choosing Haskell are primarily with respect to comparing the two languages:</p>
<h3>Haskell Is Pure And Lazy</h3>
<p>I&#8217;m already familiar with <em>impure</em>, or multi-paradigm, programming languages that offer some functional features but allow imperative programming, so being forced to program in a purely functional manner and abandon my comfort zone of imperative patterns is an advantage for me. I have no experience with lazy languages, so Haskell offers an opportunity to gain more experience with laziness :). </p>
<p>In some respects, Haskell is <em>more</em> different than Lisp compared to other statically typed functional programming languages, so it&#8217;s a good point of comparison. It may end up being the ultimate <em>death match</em> :)</p>
<ul>
<li>Static vs. Dynamic</li>
<li>Nonstrict vs. Strict</li>
<li>Rich/Complex Syntax vs. Simpler Syntax</li>
<li>Pure vs. Impure/Multi-paradigm</li>
</ul>
<h3>Active Community</h3>
<p>Haskell has a very active community. Although I&#8217;m skeptical about whether a statically typed functional programming language will be suitable for the type of work I want to do with it, it makes sense to choose one that has a reasonable shot, and I don&#8217;t personally feel that Standard ML does &#8211; it was mainly to be an introduction to functional programming and a stepping stone to another FPL.</p>
<p>Part of the reason I don&#8217;t feel that Standard ML has a reasonable shot is that it feels dated and somewhat abandoned. Functional programming languages are niche languages to begin with, but it seems that Haskell and OCaml both have fairly strong communities.</p>
<h3>Cool Features</h3>
<p>Although I think Haskell&#8217;s custom of continuing to add cutting edge research features into the language may have some disadvantages if not done well, i.e. making the language messier and complicated, for my primary purpose of evaluating the benefits of statically typed languages, I think having more advanced features is an advantage over Standard ML. If a language with such an active research community as Haskell fails to convince me of the benefits of static typing, then it may just not be for me.</p>
<p><em>Monads</em> and <em>type classes</em> seem interesting, and Haskell provides an opportunity to learn them. Monads seem useful outside of Haskell, so the time spent learning about them can be leveraged. I already like <em>list comprehensions</em>, so it&#8217;s nice to have them available again.</p>
<p>Learning some of the advanced features of Haskell will be beneficial to me regardless of whether I continue programming in Haskell or decide to go with the Lisp family.</p>
<h3>Textual Resources</h3>
<p>Standard ML actually has a surprising number of good texts available, so I don&#8217;t think Haskell offers a big advantage here, but in my particular case, I already own two Haskell texts &#8211; <em>Programming in Haskell</em> by Graham Hutton and <em>The Craft of Functional Programming</em> by Simon Thompson. Also, Chris Okasaki&#8217;s <em>Purely Functional Data Structures</em> provides Haskell examples as does Richard Bird&#8217;s <em>Introduction to Functional Programming using Haskell (2nd ed.)</em>. Lastly, I think <em>Real World Haskell</em> may be very helpful.</p>
<p><strong>Haskell Crash Course</strong></p>
<p>My goal now on the statically typed front is to become as proficient in Haskell as I can in a very short period of time. There seem to be plenty of resources available, but if you&#8217;re aware of any particularly helpful resources or tips, feel free to add a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/08/18/haskell-in-the-finals/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Programming in Standard ML &#8211; Part 3</title>
		<link>http://lojic.com/blog/2009/08/15/programming-in-standard-ml-part-3/</link>
		<comments>http://lojic.com/blog/2009/08/15/programming-in-standard-ml-part-3/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 19:43:30 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=603</guid>
		<description><![CDATA[Table of Contents
Chapter 6 &#8211; Case Analysis
Tuple types are homogeneous e.g. all values of type int*real are pairs containing an int and a real. Match failures occur at compile time. Types that have more than one form, such as int, are heterogeneous. Pattern matches fail at run time as a bind failure.
ML defines functions over [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-1/">Table of Contents</a></p>
<h2>Chapter 6 &#8211; Case Analysis</h2>
<p>Tuple types are <em>homogeneous</em> e.g. all values of type int*real are pairs containing an int and a real. Match failures occur at compile time. Types that have more than one form, such as int, are <em>heterogeneous</em>. Pattern matches fail at run time as a bind failure.</p>
<p>ML defines functions over heterogeneous types using <em>clausal function expressions</em>. For example:</p>
<pre class="code">
fn pat1 => exp1
 | pat2 => exp2
 | ...
 | patn => expn
</pre>
<p>Each component <em>pat => exp</em> is called a <em>clause</em>, or a <em>rule</em>. The entire assembly of rules is a called a <em>match</em>. For example:</p>
<pre class="code">
val recip : int -> int =
    fn 0 => 0 | n:int => 1 div n
</pre>
<p>The <code>fun</code> notation is generalized so we can be more concise:</p>
<pre class="code">
fun recip 0 = 0
  | recip (n:int) = 1 div n
</pre>
<p>Case analysis on the values of a heterogeneous type is performed by application of a clausally-defined function. The notation:</p>
<pre class="code">
case exp
  of pat1 => exp1
   | ...
   | patn => expn
</pre>
<p>is short for the application:</p>
<pre class="code">
(fn pat1 => exp1
  | ...
  | patn => expn)
exp
</pre>
<p>Matches are subject to two forms of &#8220;sanity check&#8221; &#8211; <em>exhaustiveness checking</em> and <em>redundancy checking</em>.</p>
<h2>Chapter 7 &#8211; Recursive Functions</h2>
<p>For a function to be able to call itself, it needs a name. For example:</p>
<pre class="code">
val rec factorial : int->int =
    fn 0 => 1 | n:int => n * factorial (n-1)
</pre>
<p>or using fun notation:</p>
<pre class="code">
fun factorial 0 = 1
  | factorial (n:int) = n * factorial (n-1)
</pre>
<h3>Iteration</h3>
<p>If we define a helper function that accepts an <em>accumulator</em> we can reduce the storage needed:</p>
<pre class="code">
fun helper (0,r:int) = r
  | helper (n:int,r:int) = helper (n-1,n*r)
fun factorial (n:int) = helper (n,1)
</pre>
<p>It&#8217;s better programming style to hide the helper function w/in a local declaration:</p>
<pre class="code">
local
    fun helper (0,r:int) = r
      | helper (n:int,r:int) = helper (n-1,n*r)
in
    fun factorial (n:int) = helper (n,1)
end
</pre>
<p><em>Tail recursive</em> functions are analogous to loops in imperative languages &#8211; they iterate the computation w/o needing auxiliary storage.</p>
<h3>Mutual Recursion</h3>
<p>Definitions which are <em>mutually recursive</em> can be joined together with the and keyword to indicate they are defined simultaneously by mutual recursion:</p>
<pre class="code">
fun even 0 = true
  | even n = odd (n-1)
and odd 0 = false
  | odd n = even (n-1)
</pre>
<h2>Chapter 8 &#8211; Type Inference and Polymorphism</h2>
<p>Standard ML allows you to omit type information whenever it can be determined from context. Consider the following:</p>
<pre class="code">
fn s:string => s ^ "\n"
</pre>
<p>There is no need to declare the type of s since it can be inferred from the context, so we may write:</p>
<pre class="code">
fn s => s ^ "\n"
</pre>
<p>A <em>type scheme</em> is a type expression involving one or more <em>type variables</em> standing for an unknown, but arbitrary type expression. Type variables are written &#8216;a (pronounced alpha), &#8216;b (pronounced beta), etc. For example, the type scheme  &#8216;a->&#8217;a has instances int->int, string->string, (int*int)->(int*int), and (&#8217;b->&#8217;b)->(&#8217;b->&#8217;b), etc. It does <em>not</em> have the type int->string.</p>
<p>We may bind an identity function to the variable I as follows:</p>
<pre class="code">
val I : 'a->'a = fn x=>x
</pre>
<p>We may also write:</p>
<pre class="code">
fun I(x:'a) : 'a = x
</pre>
<p>Standard ML eliminates the need to ascribe a type scheme to the variable:</p>
<pre class="code">
val I = fn x=>x

or

fun I(x) = x
</pre>
<h2>Chapter 9 &#8211; Programming with Lists</h2>
<p>The values of type <em>type</em> list are the finite lists of values of type <em>type</em>:</p>
<pre class="code">
1. nil is a value of type typ list.
2. if h is a value of type typ, and t is a value of type typ list,
   then h::t is a value of type typ list.
3. Nothing else is a value of type typ list.
</pre>
<p>The type expression <em>typ</em> list is a postfix notation for the application of the type constructor list to the type typ.</p>
<p>A value <em>val</em> of type <em>typ</em> list has the form:<br />
val1 :: (val2 :: (&#8230; :: (valn :: nil) &#8230; ))</p>
<p>The :: operator is <em>right-associative</em>, so we may omit parentheses:<br />
val1 :: val2 :: &#8230; :: valn :: nil</p>
<p>Or, we may use list notation:<br />
[ val1, val2, ..., valn ]</p>
<h3>Computing With Lists</h3>
<p>Some examples:</p>
<pre class="code">
fun length nil = 0
  | length (_::t) = 1 + length t
</pre>
<p>Note we do not give a name to the head of the list, instead we use a wildcard _</p>
<pre class="code">
fun append (nil, l) = l
  | append (h::t, l) = h :: append (t, l)
</pre>
<p>The latter is built into Standard ML and is written using infix as: exp1 @ exp2</p>
<pre class="code">
fun rev nil = nil
  | rev (h::t) = rev t @ [h]
</pre>
<p>The running time of the latter is O(<em>n</em><sup>2</sup>). The following definition makes use of an accumulator and has a running time of O(<em>n</em>):</p>
<pre class="code">
local
    fun helper (nil, a) = a
      | helper (h::t, a) = helper (t, h::a)
in
    fun rev' l = helper (l, nil)
end
</pre>
<h2>Chapter 10 &#8211; Concrete Data Types</h2>
<h3>Non-Recursive Datatypes</h3>
<p>Example of <em>nullary</em> i.e. zero argument, constructors:</p>
<pre class="code">
datatype suit = Spades | Hearts | Diamonds | Clubs
</pre>
<p>It is conventional to capitalize the names of value constructors, but this is not required by the language.</p>
<p>Datatypes may be <em>parameterized</em> by a type:</p>
<pre class="code">
datatype 'a option = NONE | SOME of 'a
</pre>
<p>The values are NONE or Some <em>val</em>, where <em>val</em> is a value of type <em>typ</em>. The option type constructor is pre-defined in Standard ML.</p>
<p>Option types can also be used in aggregate data structures:</p>
<pre class="code">
type entry = { name:string, spouse string option }
</pre>
<p>An entry for an unmarried person would have a spouse field with a value of NONE.</p>
<h3>Recursive Datatypes</h3>
<pre class="code">
datatype 'a tree =
  Empty |
  Node of 'a tree * 'a * 'a tree
</pre>
<p>1. The empty tree Empty is a binary tree.<br />
2. If tree_1 and tree_2 are binary trees, and val is a value of type type, then Node (tree_1, val, tree_2) is a binary tree.<br />
3. Nothing else is a binary tree.<br />
A function to compute the <em>height</em> of a binary tree, and one to compute the number of nodes:</p>
<pre class="code">
fun height Empty = 0
  | height (Node (lft, _, rht)) = 1 + max (height lft, height rht)

fun size Empty = 0
  | size (Node (lft, _, rht)) = 1 + size lft + size rht
</pre>
<h3>Heterogeneous Data Structures</h3>
<p>The tree data type above requires that the type of the data items at the nodes must be the same for every node of the tree. To represent a heterogeneous tree, the data item must be labelled with enough info to determine the type at run-time.</p>
<pre class="code">
datatype int_or_string =
  Int of int |
  String of string

type int_or_string =
  int_or_string tree
</pre>
<p>Datatype declarations and pattern matching can be useful for manipulating the abstract syntax of a language. Consider an example representing arithmetic expressions:</p>
<pre class="code">
datatype expr =
  Numeral of int |
  Plus of expr * expr |
  Times of expr * expr

fun eval (Numeral n) = Numeral n
  | eval (Plus (e1, e2)) =
    let
        val Numeral n1 = eval e1
        val Numeral n2 = eval e2
    in
        Numeral (n1+n2)
    end
  | eval (Times (e1, e2)) =
    let
        val Numeral n1 = eval e1
        val Numeral n2 = eval e2
    in
        Numeral (n1*n2)
    end
</pre>
<p>If we extend the expr datatype as follows:</p>
<pre class="code">
datatype expr =
  Numeral of int |
  Plus of expr * expr |
  Times of expr * expr
  Recip of expr
</pre>
<p>The compiler will complain about eval being incompatible with the new version of expr. Recompiling eval will produce an inexhaustive match warning since eval lacks a case for Recip. This is one of the benefits of static typing provided in Standard ML.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/08/15/programming-in-standard-ml-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Send Growl Notifications From Carbon Emacs On OSX</title>
		<link>http://lojic.com/blog/2009/08/06/send-growl-notifications-from-carbon-emacs-on-osx/</link>
		<comments>http://lojic.com/blog/2009/08/06/send-growl-notifications-from-carbon-emacs-on-osx/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 11:42:52 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=666</guid>
		<description><![CDATA[I found a handy article for sending growl notifications from Emacs and made some modifications for my particular setup.
Step One: Register Emacs with Growl
We need to register Carbon Emacs with Growl. This is a one time setup task. The following AppleScript script can be run in Script Editor.

tell application "GrowlHelperApp"
	-- Declare a list of notification [...]]]></description>
			<content:encoded><![CDATA[<p>I found <a href="http://alexott.blogspot.com/2008/11/working-with-growl-from-emacs.html">a handy article</a> for sending <a href="http://growl.info/">growl notifications</a> from <a href="http://homepage.mac.com/zenitani/emacs-e.html">Emacs</a> and made some modifications for my particular setup.</p>
<p><strong>Step One: Register Emacs with Growl</strong><br />
We need to register Carbon Emacs with Growl. This is a one time setup task. The following AppleScript script can be run in Script Editor.</p>
<pre class="code">
tell application "GrowlHelperApp"
	-- Declare a list of notification types
	set the allNotificationsList to {"Emacs Notification"}

	-- Declare list of active notifications.  If some of them
	-- isn't activated, user can do this later via preferences
	set the enabledNotificationsList to {"Emacs Notification"}

	-- Register our application in Growl.
	register as application "Emacs.app" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "Emacs.app"
end tell
</pre>
<p><strong>Step Two: Create Growl Notification Script</strong><br />
This is a template of the AppleScript that will be used in the Emacs Lisp function. It can be tested by executing it in the Script Editor.</p>
<pre class="code">
tell application "GrowlHelperApp"
	notify with name "Emacs Notification" title "Emacs alert" description "Message!!!" application name "Emacs.app"
end tell
</pre>
<p><strong>Step Three: Emacs Lisp Function</strong><br />
Create an Emacs Lisp function that can be invoked with a title and message.</p>
<pre class="code">
(defun bja-growl-notification (title message &#038;optional sticky)
  "Send a Growl notification"
  (do-applescript
   (format "tell application \"GrowlHelperApp\"
              notify with name \"Emacs Notification\" title \"%s\" description \"%s\" application name \"Emacs.app\" sticky %s
           end tell"
           title
           (replace-regexp-in-string "\"" "''" message)
           (if sticky "yes" "no"))))
</pre>
<p>This can be tested with the following function which sends two growl notifications. The &#8220;sticky&#8221; one requires an explicit dismissal.</p>
<pre class="code">
(defun bja-growl-test ()
  (interactive)
  (bja-growl-notification "Emacs Notification" "This is my message")
  (bja-growl-notification "Emacs Notification" "This is my sticky message" t))
</pre>
<p><strong>UPDATE:</strong> I noticed bja-growl-notification was failing if the message had embedded double quotes, so I added a call to replace-regexp-in-string to replace them with two apostrophes.</p>
<p><strong>UPDATE 2:</strong> My main motivation for setting this up was to be able to generate growl notifications from ERC (Emacs IRC client). However, I quickly realized that having a generic reminder that I can easily fire up from within Emacs is very handy. Here&#8217;s the code:</p>
<pre class="code">
(defun bja-growl-timer (minutes message)
  "Issue a Growl notification after specified minutes"
  (interactive (list (read-from-minibuffer "Minutes: " "10")
                     (read-from-minibuffer "Message: " "Reminder") ))
  (run-at-time (* (string-to-number minutes) 60)
               nil
               (lambda (minutes, message)
                 (bja-growl-notification "Emacs Reminder" message t))
               minutes
               message))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/08/06/send-growl-notifications-from-carbon-emacs-on-osx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Andrew Wiles &#8211; Fermat&#8217;s Last Theorem</title>
		<link>http://lojic.com/blog/2009/07/27/andrew-wiles-fermats-last-theorem/</link>
		<comments>http://lojic.com/blog/2009/07/27/andrew-wiles-fermats-last-theorem/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 16:34:32 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[mathematics]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=661</guid>
		<description><![CDATA[The story of Andrew Wiles who solved Fermat&#8217;s Last Theorem in 1994.
 
]]></description>
			<content:encoded><![CDATA[<p>The story of Andrew Wiles who solved Fermat&#8217;s Last Theorem in 1994.</p>
<p><embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=8269328330690408516&#038;hl=en&#038;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"> </embed></p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/07/27/andrew-wiles-fermats-last-theorem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
