<?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 &#187; sml</title>
	<atom:link href="http://lojic.com/blog/tag/sml/feed/" rel="self" type="application/rss+xml" />
	<link>http://lojic.com/blog</link>
	<description></description>
	<lastBuildDate>Fri, 28 May 2010 16:11:07 +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>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>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>TriFunc.org</title>
		<link>http://lojic.com/blog/2009/07/22/trifuncorg/</link>
		<comments>http://lojic.com/blog/2009/07/22/trifuncorg/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 14:15:42 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=635</guid>
		<description><![CDATA[I first became interested in functional programming when I was exposed to Python, Ruby &#038; JavaScript a number of years ago. Since then I&#8217;ve looked into Arc, Clojure, Common Lisp, Haskell, Logo, ML &#038; Scheme. I haven&#8217;t yet determined whether I&#8217;ll be more productive in any of them than I am with Ruby for developing [...]]]></description>
			<content:encoded><![CDATA[<p>I first became interested in functional programming when I was exposed to Python, Ruby &#038; JavaScript a number of years ago. Since then I&#8217;ve looked into Arc, Clojure, Common Lisp, Haskell, Logo, ML &#038; Scheme. I haven&#8217;t yet determined whether I&#8217;ll be more productive in any of them than I am with Ruby for developing web applications, but I do find them quite interesting.</p>
<p>After bumping into a number of local programmers who expressed an interest in functional programming, I thought it might be a good time to start a local group that focused on functional programming languages, so I did a couple days ago.</p>
<p><a rel="nofollow" href="http://TriFunc.org">TriFunc.org</a> is a group for programmers who are interested in functional programming languages and live near the Research Triangle area of North Carolina.</p>
<p>If you live in the area and have an interest in functional programming languages, feel free to dive in and start participating in the Google Group discussions. Once we reach a critical mass, I expect we&#8217;ll produce a meeting schedule, etc., but that will depend on where the group wants to take this.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/07/22/trifuncorg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming in Standard ML &#8211; Part 2</title>
		<link>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-2/</link>
		<comments>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-2/#comments</comments>
		<pubDate>Sun, 03 May 2009 01:51:13 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=579</guid>
		<description><![CDATA[Table of Contents
Chapter 4 &#8211; Functions
Lambda expressions are written as:
fn var : typ =&#62; exp
For example:
fn x : real =&#62; Math.sqrt (Math.sqrt x)
(fn x : real =&#62; Math.sqrt (Math.sqrt x)) (16.0)
val fourthroot : real -&#62; real =
  fn x : real =&#62; Math.sqrt (Math.sqrt x)
fourthroot 16.0
ML provides a special syntax for function bindings that&#8217;s [...]]]></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 4 &#8211; Functions</h2>
<p>Lambda expressions are written as:</p>
<pre class="code">fn var : typ =&gt; exp</pre>
<p>For example:</p>
<pre class="code">fn x : real =&gt; Math.sqrt (Math.sqrt x)
(fn x : real =&gt; Math.sqrt (Math.sqrt x)) (16.0)
val fourthroot : real -&gt; real =
  fn x : real =&gt; Math.sqrt (Math.sqrt x)
fourthroot 16.0</pre>
<p>ML provides a special syntax for function bindings that&#8217;s more concise:</p>
<pre class="code">fun fourthroot (x:real):real = Math.sqrt (Math.sqrt x)</pre>
<p>By experimenting (I expect this is covered later), I found the following is sufficient due to type inference:</p>
<pre class="code">
fun fourthroot x = Math.sqrt (Math.sqrt x)
</pre>
<p>Local val bindings may shadow parameters and other val bindings. For example, in the following, the last occurrence of x refers to the parameter of h, but the preceding two occurrences of x refer to the local binding with a value of 2.0:</p>
<pre class="code">fun h(x:real):real =
  let val x:real = 2.0 in x+x end * x</pre>
<h2>Chapter 5 &#8211; Products and Records</h2>
<p>The <em>n-tuple</em> is the simplest form of aggregate data structure. They are of the form:<br />
(val<sub>1</sub>, &#8230; ,val<sub>n</sub>)<br />
An <em>n</em>-tuple is a value of a <em>product type</em> of the form:<br />
<em>typ<sub>1</sub></em>* &#8230; *<em>typ<sub>n</sub></em><br />
For example:</p>
<pre class="code">val pair : int * int = (2, 3)
val triple : int * real * string = (2, 2.0, "2")
val pair_of_pairs : (int * int) * (real * real) = ((2,3),(2.0,3.0))</pre>
<p>A 0-tuple, also known as a <em>null tuple</em>, is the empty sequence of values, ( ). It is a value of type unit. 1-tuples are absent from the language.</p>
<h3>Tuple Patterns</h3>
<p>We can use pattern matching to extract portions of an n-tuple. For example, in the code snippet below, r will be equal to 3.14. Underscores indicate &#8220;don&#8217;t care&#8221; positions:</p>
<pre class="code">val foo : (int * string) * (real * char) = ((7,"hello"),(3.14,#"z"))
val ((_, _), (r:real, _)) = foo</pre>
<p>We can give names to the first and second components of the pair &#8211; using the REPL:</p>
<pre class="code">- val (is:int*string,rc:real*char) = foo;
val is = (7,"hello") : int * string
val rc = (3.14,#"z") : real * char</pre>
<p>A pattern is one of three forms:</p>
<ol>
<li>A <em>variable pattern</em> of the form <em>var : typ</em></li>
<li>A <em>tuple pattern</em> of the form (<em>pat<sub>1</sub>, &#8230;, pat<sub>n</sub></em>), where each<em> pat<sub>i</sub></em> is a pattern. This includes as a special case the null-tuple pattern, ()</li>
<li>A <em>wildcard pattern</em> of the form _</li>
</ol>
<h3>Record Types</h3>
<p>Tuples can become more difficult to use as the number of elements increases. Record types allow labeling each component. A record <em>type</em> has the form:<br />
{ lab<sub>1</sub>:typ<sub>1</sub>, &#8230;, lab<sub>n</sub>:typ<sub>n</sub>}<br />
A record <em>value</em> has the form:<br />
{ lab<sub>1</sub>=val<sub>1</sub>, &#8230;, lab<sub>n</sub>=val<sub>n</sub>}<br />
A record <em>pattern</em> has the form:<br />
{ lab<sub>1</sub>=pat<sub>1</sub>, &#8230;, lab<sub>n</sub>=pat<sub>n</sub>}</p>
<p>For example, the record type hyperlink is defined as follows:</p>
<pre class="code">
type hyperlink =
  { protocol : string,
    address  : string,
    display  : string }
</pre>
<p>The following record binding defines a variable of type hyperlink:</p>
<pre class="code">
val mailto : hyperlink =
  { protocol = "mailto",
    address = "foo@bar.com",
    display = "Brian Adkins" }
</pre>
<p>The following record binding:</p>
<pre class="code">
val { protocol=prot, display=disp, address=addr } = mailto
</pre>
<p>decomposes into the three variable bindings:</p>
<pre class="code">
val prot = "mailto"
val addr = "foo@bar.com"
val disp = "Brian Adkins"
</pre>
<p>We can use wildcard to extract selected fields:</p>
<pre class="code">
val {protocol=prot, address=_, display=_ } = mailto
</pre>
<p>However, this isn&#8217;t very helpful with many fields, so we can use <em>ellipsis patterns</em>:</p>
<pre class="code">
val {protocol=prot, ... } = mailto
</pre>
<p>ML provides an abbreviated form of record pattern {lab<sub>1</sub>,&#8230;lab<sub>n</sub>} which stands for { lab<sub>1</sub>=var<sub>1</sub>, &#8230;, lab<sub>n</sub>=var<sub>n</sub>} where the variables have the same name as the corresponding labels. For example, the following:</p>
<pre class="code">
val { protocol, address, display } = mailto
</pre>
<p>decomposes into these bindings:</p>
<pre class="code">
val protocol = "mailto"
val address = "foo@bar.com"
val display = "Brian Adkins"
</pre>
<h3>Multiple Arguments and Multiple Results</h3>
<pre class="code">
fun dist (x:real, y:real):real = sqrt (x*x + y*y)
</pre>
<p>Keyword parameters are supported through record patterns:</p>
<pre class="code">
fun dist’ {x=x:real, y=y:real} = sqrt (x*x + y*y)
</pre>
<p>Invoked as follows:</p>
<pre class="code">
dist' {x=2.0,y=3.0}
</pre>
<p>Functions with multiple results may be thought of as functions yield tuples (or records).</p>
<pre class="code">
fun dist2 (x:real, y:real):real*real
  = (sqrt (x*x+y*y), abs(x-y))
</pre>
<p><em>Sharp notation</em> allows us to conveniently access the Nth item in a tuple.</p>
<pre class="code">
- val foo = (3,7,5,2);
val foo = (3,7,5,2) : int * int * int * int
- #3 foo;
val it = 5 : int
</pre>
<p>A similar notation is used for record field selection:</p>
<pre class="code">
 - val foo = { name = "Brian", phone = "555-1212" };
val foo = {name="Brian",phone="555-1212"} : {name:string, phone:string}
- #name foo;
val it = "Brian" : string
</pre>
<p>However, Harper states, &#8220;<strong>Use of the sharp notation is strongly discouraged!</strong>&#8220;</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming in Standard ML &#8211; Part 1</title>
		<link>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-1/</link>
		<comments>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-1/#comments</comments>
		<pubDate>Sun, 03 May 2009 00:45:55 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=556</guid>
		<description><![CDATA[Table of Contents

Part Two
Part Three

The posts in this series will be notes &#38; highlights from working through &#8220;Programming in Standard ML&#8221; by Robert Harper. See Getting Started with Standard ML for a link to the PDF. I may not always use quotes in this series, but it should be assumed that any factual information about [...]]]></description>
			<content:encoded><![CDATA[<h2>Table of Contents</h2>
<ul>
<li><a href="http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-2/">Part Two</a></li>
<li><a href="http://lojic.com/blog/2009/08/15/programming-in-standard-ml-part-3/">Part Three</a></li>
</ul>
<p>The posts in this series will be notes &amp; highlights from working through &#8220;Programming in Standard ML&#8221; by Robert Harper. See <a href="http://lojic.com/blog/2009/05/02/getting-started-with-standard-ml/">Getting Started with Standard ML</a> for a link to the PDF. I may not always use quotes in this series, but it should be assumed that any factual information about Standard ML that I write in this series has been obtained from the PDF above &#8211; this series is, in effect, a summarization of Robert Harper&#8217;s PDF.</p>
<h2>Overview</h2>
<p>Attributes of Standard ML:</p>
<ul>
<li>Type-safe programming language</li>
<li>Statically typed</li>
<li>Extensible type system</li>
<li>Polymorphic type inference</li>
<li>Automatic storage management</li>
<li>Encourages functional (effect-free) programming</li>
<li>Allows imperative (effect-ful) programming where appropriate</li>
<li>Pattern matching</li>
<li>Extensible exception mechanism for handling error conditions</li>
<li>Expressive and flexible module system</li>
<li>Portable due to its <a href="http://www.amazon.com/gp/product/0262631814?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0262631814">precise definition</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0262631814" border="0" alt="" width="1" height="1" /></li>
<li>Portable <a href="http://www.amazon.com/gp/product/0521794781?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0521794781">standard basis library</a></li>
</ul>
<h2>Chapter 1 &#8211; Programming in Standard ML</h2>
<p>This chapter provides a brief overview of the language by considering an implementation of a regular expression package. It was slightly more familiar to me because of my brief studies of Haskell; otherwise, I think it would&#8217;ve appeared very foreign. I prefer more of a bottom up approach as much as possible instead of looking at language features that haven&#8217;t been described.</p>
<h3>Currying</h3>
<p>I do think that currying &amp; partial application are cool features. Consider the following function declaration:</p>
<pre class="code">val match : RegExp.regexp -&gt; string -&gt; bool</pre>
<p>Coming from a non-currying background, I would describe <em>match</em> as a function that accepts a regular expression and a string, and returns a boolean value indicating whether the string matches the regular expression, but Robert describes it this way:</p>
<blockquote><p>It contains a function match that, when given a regular expression, returns a function that determines whether or not a given string matches that expression.</p></blockquote>
<p>This was one of the features that made a strong impression on me when I first started looking at functional programming languages.</p>
<h2>Chapter 2 &#8211; Types, Values, and Effects</h2>
<blockquote><p>Computation in ML is of a somewhat different nature. The emphasis in ML is on computation by evaluation of expressions, rather than execution of commands.</p></blockquote>
<p>An expressions has three characteristics:</p>
<ul>
<li>It may or may not have a <em>type</em></li>
<li>It may or may not have a <em>value</em></li>
<li>It may or may not create an <em>effect</em></li>
</ul>
<p>Effects will be ignored until chapter 13, so until then, it&#8217;s assumed that all expressions are <em>effect-free</em>, or <em>pure</em>.  A type is defined by specifying three things:</p>
<ul>
<li>a <em>name</em> for the type,</li>
<li>the <em>values</em> of the type, and</li>
<li>the <em>operations</em> that may be performed on values of the type</li>
</ul>
<p>Notes:</p>
<ul>
<li>Negative numbers, as literals, are indicated with a tilde instead of a hypen e.g. ~7</li>
<li>div is used for integers, / for reals</li>
</ul>
<p>A typing assertion has the form: <em>exp : typ</em> For example:  3 : int  4 div 3 : int  ML does <em>not</em> perform any implicit conversions between types. Use real(3) + 4.3, or 3 + round(4.3)  Conditional expression (exp1 and exp2 must have the same type):  if <em>exp</em> then <em>exp1</em> else <em>exp2</em> if <em>not exp</em> then <em>exp1</em> else <em>exp2</em></p>
<h2>Chapter 3 &#8211; Declarations</h2>
<p>Once a <em>variable</em> is bound to a <em>value</em>, it is bound to it for life; there is no possibility of changing the binding of a variable once it has been bound.  Examples of <em>type</em> bindings:</p>
<pre class="code">type float = real
type count = int and average = real</pre>
<p>Examples of <em>value </em>bindings:</p>
<pre class="code">val m : int = 3+2
val pi : real = 3.14 and e : real = 2.17</pre>
<blockquote><p>One thing to keep in mind is that binding is not assignment. The binding of a variable never changes; once bound to a value, it is always bound to that value (within the scope of the binding). However, we may shadow a binding by introducing a second binding for a variable within the scope of the ﬁrst binding.</p></blockquote>
<p>Limiting scope with <em>let</em> expressions:</p>
<pre class="code">let
  val m : int = 3
  val n : int = m*m
in
  m*n
end</pre>
<p>The following expression evaluates to 54 because the binding of m is temporarily overridden during the evaluation of the let expression, then restored upon completion of this evaluation:</p>
<pre class="code">val m : int = 2
val r : int =
    let
        val m : int = 3
        val n : int = m*m
    in
        m*n
    end * m</pre>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/05/02/programming-in-standard-ml-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with Standard ML</title>
		<link>http://lojic.com/blog/2009/05/02/getting-started-with-standard-ml/</link>
		<comments>http://lojic.com/blog/2009/05/02/getting-started-with-standard-ml/#comments</comments>
		<pubDate>Sat, 02 May 2009 17:26:49 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=545</guid>
		<description><![CDATA[One of the two parallel tracks in my 2009 Programming Language Plan begins with the Standard ML programming language, so it&#8217;s time to get started.
Standard ML Resources
Compilers

 Standard ML of New Jersey is highly recommended and comes with a REPL.
 Moscow ML
 MLKit
 PolyML
 MLton is a Standard ML compiler with excellent performance. However, as [...]]]></description>
			<content:encoded><![CDATA[<p>One of the two parallel tracks in my <a href="http://lojic.com/blog/2009/04/27/2009-programming-language-plan/">2009 Programming Language Plan</a> begins with the Standard ML programming language, so it&#8217;s time to get started.</p>
<h2>Standard ML Resources</h2>
<h3>Compilers</h3>
<ul>
<li> <a href="http://www.smlnj.org/">Standard ML of New Jersey</a> is highly recommended and comes with a <a href="http://en.wikipedia.org/wiki/REPL">REPL</a>.</li>
<li> <a href="http://www.itu.dk/people/sestoft/mosml.html">Moscow ML</a></li>
<li> <a href="http://www.itu.dk/research/mlkit/index.php/Main_Page">MLKit</a></li>
<li> <a href="http://www.polyml.org/">PolyML</a></li>
<li> <a href="http://mlton.org/">MLton</a> is a Standard ML compiler with excellent performance. However, as far as I know, it doesn&#8217;t have a <a href="http://en.wikipedia.org/wiki/REPL">REPL</a>, which makes it less than ideal for learning.</li>
</ul>
<h3>Books</h3>
<p>Since I was unfamiliar with the Standard ML programming language, I was surprised to find there are a number of good books about the language. Following are just some of them:</p>
<p><a href="http://www.amazon.com/gp/product/0137903871?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0137903871">Elements of ML Programming</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0137903871" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/052156543X?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=052156543X">ML for the Working Programmer</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=052156543X" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/0521663504?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0521663504">Purely Functional Data Structures</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0521663504" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/0262631814?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0262631814">The Definition of Standard ML</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0262631814" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/0521794781?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0521794781">The Standard ML Basis Library</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0521794781" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/0201398206?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201398206">Introduction to Programming using SML</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=lojiccom-20&amp;l=as2&amp;o=1&amp;a=0201398206" border="0" alt="" width="1" height="1" /></p>
<p><a href="http://www.amazon.com/gp/product/0521714729?ie=UTF8&amp;tag=lojiccom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0521714729">Concurrent Programming in ML</a></p>
<h3>Other Educational Materials</h3>
<p>
<a href="http://www.cs.cmu.edu/~rwh/smlbook/online.pdf">Programming in Standard ML</a> &#8211; excellent online book by <a href="http://www.cs.cmu.edu/~rwh/">Robert Harper</a> of Carnegie Mellon University. Since I don&#8217;t know if Standard ML will simply be a stepping stone to Haskell (which in turn may not be a primary language for me) or a language I invest a lot of time in, I&#8217;m going to restrict myself from my normal method of purchasing a book or two when learning a new language. Instead, I&#8217;ll be going through Harper&#8217;s online book initially.
</p>
<p>
<a href="http://www.itu.dk/people/tofte/publ/tips.pdf">Tips for Computer Scientists on Standard ML (Revised)</a>
</p>
<h2>Hello World</h2>
<p>There are a number of great compilers for Standard ML (listed above), but I only need one to get started, so I chose Standard ML of New Jersey despite the funky name. It&#8217;s a popular version, and it has a REPL, so it&#8217;s good enough for me for now.</p>
<p>I develop software on Mac OSX and deploy on Ubuntu Linux. On my Ubuntu server, installing SML/NJ was as simple as:</p>
<pre class="code">
sudo apt-get install smlnj
</pre>
<p>On Mac OSX, there are a couple of options listed on <a href="http://www.smlnj.org/dist/working/110.69/index.html">this page</a>. I could use a pre-built system or the generic Unix install, so naturally I chose the generic Unix install which installed easily according to the simple directions.</p>
<pre class="code"># Download config.tgz
tar xzf config.tgz
config/install.sh

# Wait for install to complete

~/software/smlnj$ rlwrap bin/sml
Standard ML of New Jersey v110.69 [built: Sat May  2 12:04:08 2009]
- print "hello, world\n";
hello, world
val it = () : unit
-</pre>
<p>Great, looks like everything is working fine. Note, I use the <em>rlwrap</em> utility to provide a nicer REPL experience, but it&#8217;s not required.</p>
<p>I&#8217;ll continue with a series of posts with notes from working through &#8220;Programming in Standard ML&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/05/02/getting-started-with-standard-ml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2009 Programming Language Plan</title>
		<link>http://lojic.com/blog/2009/04/27/2009-programming-language-plan/</link>
		<comments>http://lojic.com/blog/2009/04/27/2009-programming-language-plan/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 17:36:42 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[common_lisp]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[sml]]></category>

		<guid isPermaLink="false">http://lojic.com/blog/?p=502</guid>
		<description><![CDATA[Background

The 2008 Programming Language Plan didn&#8217;t go as well as I hoped, so I&#8217;m regrouping for another go at it. I did make progress learning some Logo and teaching it to my daughters, and I worked through seven chapters of &#8220;Programming in Haskell&#8221; which was very enjoyable, but I also spent way too much time [...]]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>
The <a href="http://lojic.com/blog/2008/01/17/2008-programming-language-plan/">2008 Programming Language Plan</a> didn&#8217;t go as well as I hoped, so I&#8217;m regrouping for another go at it. I did make progress learning some Logo and teaching it to my daughters, and I worked through seven chapters of &#8220;Programming in Haskell&#8221; which was very enjoyable, but I also spent way too much time trying to decide which language(s) to learn without actually learning them.
</p>
<p>
I have now decided which languages I want to learn this year, so I figured I&#8217;d post this blog entry. In some respects, things haven&#8217;t changed much from last years plan, but my decisions are much less tentative which is encouraging. I&#8217;m glad to switch from <em>information gathering</em> to actually learning a few languages.
</p>
<h2>Motivation</h2>
<p>
When I switched from C++ to Java in 1996 and noticed a large increase in productivity; however, it didn&#8217;t occur to me to consider whether switching from Java to another language might also give me a similar boost in productivity. The job demand for Java was high during the 10 years I used it, and I was getting paid for my time vs. what I produced, so the oversight wasn&#8217;t too costly.
</p>
<p>
When I switched from Java to Ruby in 2006 I experienced a comparable, if not greater, boost in productivity as I had with the switch from C++ to Java. This time I considered the effect of programming language choice on productivity more carefully and began to wonder about the optimal programming language for me. As a small business owner, my primary consideration is productivity, not popularity or the interchangeableness of programmers.
</p>
<p>
I don&#8217;t think a perfect programming language exists in general, but I think there is an optimal language for me given my particular circumstances, the problems I want to solve, the type of software I want to develop, my way of thinking, my aesthetic tastes, etc.
</p>
<h2>The Problem</h2>
<p>
There is a cost to research programming languages to determine the optimal one, and there is a cost to switch programming languages, so the benefit of a new programming language needs to exceed those costs.
</p>
<p>
Additionally, a significant catch-22 exists in that to truly determine if a language is optimal, one must reach a level of proficiency with the language. There isn&#8217;t enough time to learn <em>all</em> of the candidate languages, so some filtering mechanism must be used first to narrow the choices to a reasonably small set. This filtering mechanism is theoretical by nature, but I think the subtle practicalities of a language have a significant effect on productivity.
</p>
<p>
I have a long term perspective for this task, so I don&#8217;t mind investing time researching programming languages, and I also don&#8217;t mind if I need to develop/acquire supporting libraries before being ultimately more productive than I am currently with Ruby and Rails.
</p>
<h2>The Process</h2>
<p>
I briefly entertained the idea of going about this research in a more systematic, scientific way. That might be a reasonable approach, but due to the following:
</p>
<ul>
<li>My laziness</li>
<li>The high degree of subjectivity in programming language choice</li>
<li>The lack of consensus among programming language researchers</li>
</ul>
<p>
I ended up with a fairly ad-hoc approach involving examining the following areas and trying to absorb enough information to formulate a plan:
</p>
<h3>Efficiency</h3>
<p>
Programming language efficiency is becoming increasingly important to me as Moore&#8217;s law loses steam, and power &amp; cooling issues become more prominent.
</p>
<p>
On the one hand, Ruby is near the bottom of the pack with respect to efficiency, but the productivity has been outstanding, and at the volume of transactions I&#8217;ve needed to deliver thus far, performance hasn&#8217;t been a problem.
</p>
<p>
On the other hand, if programming languages exist (and I believe they do) that have similar or greater <em>power</em> than Ruby but are compiled instead of interpreted, that would be an advantage.
</p>
<p>
Benchmarks are notoriously controversial with respect to the degree in which they predict performance, but I don&#8217;t think they&#8217;re irrelevant. One popular benchmark site is: <a href="http://shootout.alioth.debian.org/">Programming Language Shootout</a>. I also created some micro-benchmarks of my own to test performance.
</p>
<p>
One negative result of Ruby being inefficient is the disparity in performance of code written in Ruby vs. library code, or extensions, written in C. This creates counter-intuitive scenarios where a piece of code that appears less efficient is actually more efficient because of the use of built-in code implemented in C. I don&#8217;t like thinking in those terms; I would much prefer that user written code in the language is much closer to the efficiency of built-in library code.
</p>
<h3>Concurrency</h3>
<p>
With the flattening of CPU MHz and proliferation of CPU cores, I think concurrency may continue to grow in importance. Although I develop mainly server side web applications which can take advantage of multiple cores by virtue of having multiple independent processes, I would prefer to have better concurrency mechanisms in the language/libraries directly.
</p>
<h3>Joy</h3>
<p>
I think I first heard <em>joy</em> used, in the context of programming languages, in the Ruby community &#8211; probably from Matz himself. I have to agree that programming in Ruby has been more joyful than previous programming languages.
</p>
<p>
I&#8217;m not sure exactly why this is, but I expect it has something to do with the effectiveness and productivity of Ruby, but it may be helped by the incredibly friendly Ruby community.
</p>
<h3>Fundamental Nature</h3>
<p>
My preference is for a programming language to minimize arbitrariness and to maximize orthogonality. In other words, I would prefer the language to have a minimal set of core concepts/axioms/operators/etc. that are built upon systematically.
</p>
<h3>Community</h3>
<p>
Whether my optimal language is <em>mainstream</em> or not is irrelevant to me, so I don&#8217;t need the programming language community to be large (and in fact, being <em>too</em> large is a detriment), but I do think it should be active enough that there are people available to help answer questions, write libraries, maintain/improve compilers, debuggers etc.
</p>
<p>
To this end, I spent time on various usenet groups, IRC channels and blogs. Occasionally asking questions, but mostly observing the dialog and interaction among the community members.
</p>
<h3>Education</h3>
<p>
What educational materials are available?
</p>
<p>
I tend to prefer learning from books, so searching Amazon to see what books are available, how well they&#8217;re received, etc. was helpful. Although I prefer books typically, in the exploratory stages, it&#8217;s cheaper to go through online materials, so searching the web for free PDFs was useful. The existence of a few good texts is also an indication of the vitality of community.
</p>
<h3>Productivity</h3>
<p>
Ultimately, I&#8217;m after the most productive language for me; however, I think productivity is the factor that requires the most proficiency with a language to judge, so it was the most difficult factor to research prior to learning a language. I was limited to anecdotal stories, case studies, personal testimonies, etc.
</p>
<h3>Licensing</h3>
<p>
I prefer open source licensing because I think programming languages with proprietary licensing are more likely to die.
</p>
<h2>The Final Candidates</h2>
<p>
I began with Ruby as the point of reference irrespective of Rails and other libraries. Even though Rails is an important factor in my current productivity, since I&#8217;m taking a long term view, I didn&#8217;t want to exclude a fantastic language simply because it&#8217;s lacking something that Ruby was also lacking N years ago.
</p>
<p>
Due to the cost of researching, learning and switching to a new programming language, I only considered languages that had the potential of offering a significant improvement in one or more areas without losing too much in other areas.
</p>
<p>
The candidates I eventually selected fell into two groups. Both groups have strong <em>functional</em> capabilities, good efficiency, and long, successful track records. I believe that even the best programming language designers make serious mistakes which can only be identified with the hindsight of years of use. It&#8217;s possible that someone is about to release a brand new language that has the potential to be the most productive for me personally; however, I&#8217;m not willing to take the risk to learn it.
</p>
<h3>The Lisp Family</h3>
<p>
Lisp has a very long track record of success and adaptability. In fact, if I was forced to program in a single programming language from now on, I would probably choose a Lisp since I think it would have the greatest likelihood of being able to adapt.
</p>
<p>
The Lisp family has dynamic typing which I&#8217;ve grown to love with Ruby, but most also allow type declarations for efficiency. Lisp also appears to have a more fundamental nature than most languages. I&#8217;ve heard it said that Lisp was more discovered than invented.
</p>
<p>
I first became interested in Lisp when I learned that Ruby was influenced by it. My interest was reinforced by some of Paul Graham&#8217;s essays &amp; books. I like the exploratory and dynamic nature of developing Lisp &#8211; this is mostly from reading comments of others, but I&#8217;ve tasted a small part of this when evaluating Lisp code in Emacs and having it be available immediately.
</p>
<p>
<strong>Logo</strong> is first on the list simply because it&#8217;s both a Lisp and a great language for teaching children how to program, so I can kill two birds with one stone.
</p>
<p>
<strong>Scheme</strong> is next because it&#8217;s a natural sequel to Logo and I <em>still</em> want to work through &#8220;The Structure and Interpretation of Computer Programs&#8221;. The fact that Paul Graham chose mzcheme to create his Arc language is a good &#8220;letter of recommendation&#8221;. Scheme <em>feels</em> the most fundamental, simple &amp; clean thus far.
</p>
<p>
<strong>Common Lisp</strong> is after Scheme due to its eminent practicality and completeness. It has plenty of warts, but also plenty of power and functionality. It&#8217;s been called a great, big, ball of mud &#8211; but in a good way ;)
</p>
<p>
Lastly, is <strong>Clojure</strong>. It&#8217;s last in the Lisp family because I want to learn Scheme &amp; Common Lisp first so I&#8217;ll be better equipped to judge Clojure. This will also allow more time for Clojure to mature. Clojure has a focus on functional programming &amp; concurrency that is <em>symbiotic</em> with the Java platform. The latter provides a quick start and access to Java libraries, the JVM infrastructure, etc., but my preference would be to not be dependent on the JVM in the long run. I&#8217;ll withhold judgment until I&#8217;ve learned it and used it for a while.
</p>
<h3>The ML Family</h3>
<p>
I&#8217;m least familiar with the ML family and with functional programming in general. I&#8217;ve spent most of my career studying and using imperative, object-oriented programming languages.
</p>
<p>
I think the ML family is worth studying because:
</p>
<ul>
<li>Functional programming may be beneficial with respect to concurrency.</li>
<li>Prog. Lang. researchers seem to be enamored with ML family.</li>
<li>There are enough anecdotal testimonies of productivity to warrant further study.</li>
</ul>
<p>
<strong>Standard ML</strong> is an important functional language that differs from Haskell in that it&#8217;s <em>impure</em>, i.e. it allows side effects, and it&#8217;s <em>strict</em>, i.e. not lazy. It shares Hindly-Milner static typing with Haskell. The community seems rather tiny, and I expect that if I go with a static typed language it will likely be Haskell, but I wanted to learn Standard ML first because of its historical importance and to be able to compare an impure/strict language with a pure/nonstrict language.
</p>
<p>
<strong>Haskell</strong> is probably the most different programming language from what I&#8217;m used to. This, in and of itself, has some advantages with respect to gaining new perspectives and ideas. In some ways, it&#8217;s a language that has taken things to extremes with respect to functional purity and laziness.
</p>
<p>
The community is <em>very</em> active. It offers a great compiler (GHC), software transactional memory, a decent base of libraries, etc.
</p>
<p>
At this early stage, I&#8217;m skeptical of static typing, functional purity and laziness, so becoming proficient in Haskell is a great opportunity to be able to determine how I feel about those.
</p>
<h2>The Plan</h2>
<p>
Rather than go through the candidates sequentially, I&#8217;m going to try and make progress on two tracks concurrently to allow me to compare concepts from both families:</p>
<table border="1" cellpadding="3">
<tr>
<th>ML Family</th>
<th>Lisp Family</th>
</tr>
<tr>
<td>Standard ML</td>
<td>Logo</td>
</tr>
<tr>
<td>Haskell</td>
<td>Scheme</td>
</tr>
<tr>
<td></td>
<td>Common Lisp</td>
</tr>
<tr>
<td></td>
<td>Clojure</td>
</tr>
</table>
<p>
<br />
I&#8217;m curious to find out how I feel about these languages after I&#8217;ve achieved some skill with them, but I think becoming proficient in the Lisp and ML families will be time well spent. At minimum, I&#8217;ll be better equipped to compare other languages.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/04/27/2009-programming-language-plan/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Programming Language Popularity</title>
		<link>http://lojic.com/blog/2009/04/21/programming-language-popularity/</link>
		<comments>http://lojic.com/blog/2009/04/21/programming-language-popularity/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 19:55:41 +0000</pubDate>
		<dc:creator>Brian Adkins</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[common_lisp]]></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=466</guid>
		<description><![CDATA[Despite the numerous ways in existence to quantify programming language popularity, I thought I&#8217;d throw yet another one into the mix. 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;"

I&#8217;m very curious to see how these stats change over time, so I&#8217;ve added a calendar [...]]]></description>
			<content:encoded><![CDATA[<p>Despite the numerous ways in existence to quantify programming language popularity, I thought I&#8217;d throw yet another one into the mix. 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>
<p>I&#8217;m very curious to see how these stats change over time, so I&#8217;ve added a calendar item to recompute them in six months. Leave a comment if you&#8217;d like to add a programming language to the list, and I&#8217;ll update this article and it will be included in the recomputation six months from now.</p>
<table border="0">
<tbody>
<tr>
<th>Language</th>
<th># Results</th>
</tr>
<tr>
<td>C</td>
<td>1,905,500</td>
</tr>
<tr>
<td>Java</td>
<td>850,000</td>
</tr>
<tr>
<td>C++</td>
<td>699,000</td>
</tr>
<tr>
<td>PHP</td>
<td>680,000</td>
</tr>
<tr>
<td>Python</td>
<td>396,000</td>
</tr>
<tr>
<td>Perl</td>
<td>365,500</td>
</tr>
<tr>
<td>C#</td>
<td>349,700</td>
</tr>
<tr>
<td>Lisp Family<sup>1</sup></td>
<td>176,507</td>
</tr>
<tr>
<td>JavaScript</td>
<td>102,700</td>
</tr>
<tr>
<td>Ruby</td>
<td>99,650</td>
</tr>
<tr>
<td>Scheme</td>
<td>86,450</td>
</tr>
<tr>
<td>Lisp</td>
<td>61,900</td>
</tr>
<tr>
<td>Tcl</td>
<td>44,800</td>
</tr>
<tr>
<td>ML Family<sup>2</sup></td>
<td>29,062</td>
</tr>
<tr>
<td>Haskell</td>
<td>22,550</td>
</tr>
<tr>
<td>Erlang</td>
<td>22,285</td>
</tr>
<tr>
<td>OCaml</td>
<td>22,000</td>
</tr>
<tr>
<td>Common Lisp</td>
<td>20,600</td>
</tr>
<tr>
<td>Prolog</td>
<td>17,750</td>
</tr>
<tr>
<td>Lua</td>
<td>13,065</td>
</tr>
<tr>
<td>Smalltalk</td>
<td>9,105</td>
</tr>
<tr>
<td>Arc</td>
<td>6,775</td>
</tr>
<tr>
<td>Forth</td>
<td>6,465</td>
</tr>
<p><!-- use ML and SML --></p>
<tr>
<td>(S)ML<sup>3</sup></td>
<td>5,173</td>
</tr>
<tr>
<tr>
<td>Scala</td>
<td>3,570</td>
</tr>
<tr>
<td>Caml</td>
<td>1,889</td>
</tr>
<tr>
<td>Io</td>
<td>1,760</td>
</tr>
<tr>
<td>Clojure</td>
<td>782</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<br />
<strong>Update</strong> 4/23/09 added C#, Tcl per comment requests.</p>
]]></content:encoded>
			<wfw:commentRss>http://lojic.com/blog/2009/04/21/programming-language-popularity/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
