<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Logo, Ruby &amp; JavaScript</title>
	<atom:link href="http://lojic.com/blog/2007/08/31/logo-ruby-javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/</link>
	<description></description>
	<lastBuildDate>Sun, 25 Dec 2011 09:28:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Brian Adkins</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-31109</link>
		<dc:creator>Brian Adkins</dc:creator>
		<pubDate>Sun, 16 Oct 2011 21:28:51 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-31109</guid>
		<description>Here&#039;s a better cartesian using nested folds that&#039;s about twice as fast as the concat / map version:

&lt;pre&gt;
fun cartesian [] = []
  &#124; cartesian ([x]) = map (fn e =&gt; [e]) x
  &#124; cartesian (x::xs) =
    let val tailCross = cartesian xs
    in foldr (fn (x&#039;,result) =&gt; 
        foldr (fn (tc,l) =&gt; (x&#039;::tc) :: l ) result tailCross) [] x
    end
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Here&#8217;s a better cartesian using nested folds that&#8217;s about twice as fast as the concat / map version:</p>
<pre>
fun cartesian [] = []
  | cartesian ([x]) = map (fn e => [e]) x
  | cartesian (x::xs) =
    let val tailCross = cartesian xs
    in foldr (fn (x',result) =>
        foldr (fn (tc,l) => (x'::tc) :: l ) result tailCross) [] x
    end
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Adkins</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-30925</link>
		<dc:creator>Brian Adkins</dc:creator>
		<pubDate>Thu, 13 Oct 2011 22:14:48 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-30925</guid>
		<description>I recently had a problem pop up where I needed to create a cartesian product of N lists. I&#039;m coding it in Standard ML, so I now have a new entry in that language :)  Pretty concise I think:

&lt;pre&gt;
fun cartesian ([x]) = map (fn e =&gt; [e]) x
  &#124; cartesian (x::xs) =
    let val tailCross = cartesian xs
    in concat(map (fn e =&gt; map (fn e2 =&gt; e::e2) tailCross) x) end
    
fun choices xs = map join (cartesian xs)
&lt;/pre&gt;

The Standard ML REPL abbreviated the list, but it works fine:

&lt;pre&gt;
- choices [[&quot;Small&quot;,&quot;Medium&quot;, &quot;Large&quot;],[&quot;vanilla&quot;, &quot;ultra chocolate&quot;, &quot;lychee&quot;, &quot;rum raisin&quot;, &quot;ginger&quot;],[&quot;cone&quot;, &quot;cup&quot;]];
val it =
  [&quot;Small vanilla cone&quot;,&quot;Small vanilla cup&quot;,&quot;Small ultra chocolate cone&quot;,
   &quot;Small ultra chocolate cup&quot;,&quot;Small lychee cone&quot;,&quot;Small lychee cup&quot;,
   &quot;Small rum raisin cone&quot;,&quot;Small rum raisin cup&quot;,&quot;Small ginger cone&quot;,
   &quot;Small ginger cup&quot;,&quot;Medium vanilla cone&quot;,&quot;Medium vanilla cup&quot;,...]
  : string list
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>I recently had a problem pop up where I needed to create a cartesian product of N lists. I&#8217;m coding it in Standard ML, so I now have a new entry in that language :)  Pretty concise I think:</p>
<pre>
fun cartesian ([x]) = map (fn e =&gt; [e]) x
  | cartesian (x::xs) =
    let val tailCross = cartesian xs
    in concat(map (fn e =&gt; map (fn e2 =&gt; e::e2) tailCross) x) end

fun choices xs = map join (cartesian xs)
</pre>
<p>The Standard ML REPL abbreviated the list, but it works fine:</p>
<pre>
- choices [["Small","Medium", "Large"],["vanilla", "ultra chocolate", "lychee", "rum raisin", "ginger"],["cone", "cup"]];
val it =
  ["Small vanilla cone","Small vanilla cup","Small ultra chocolate cone",
   "Small ultra chocolate cup","Small lychee cone","Small lychee cup",
   "Small rum raisin cone","Small rum raisin cup","Small ginger cone",
   "Small ginger cup","Medium vanilla cone","Medium vanilla cup",...]
  : string list
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Python combinations &#171; I gotta have my orange juice.</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-7883</link>
		<dc:creator>Python combinations &#171; I gotta have my orange juice.</dc:creator>
		<pubDate>Tue, 06 Oct 2009 17:43:24 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-7883</guid>
		<description>[...] a comment &#187;  In September 2007, Brian Adkins posted a simple Logo program to print all possible combinations of lists of items, and asked for alternatives in other [...]</description>
		<content:encoded><![CDATA[<p>[...] a comment &raquo;  In September 2007, Brian Adkins posted a simple Logo program to print all possible combinations of lists of items, and asked for alternatives in other [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Moonen</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-6699</link>
		<dc:creator>Scott Moonen</dc:creator>
		<pubDate>Mon, 17 Aug 2009 17:04:45 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-6699</guid>
		<description>Ha, well, turns out that the clojure-contrib library, a standard part of any serious Clojure setup, has some built-in combinatorics support.  That brings the Clojure sample down to a simple call to &quot;cartesian-product&quot;.  I use &quot;apply&quot; below since cartesian-product expects the choices to be supplied as a series of arguments rather than a list of lists.

&lt;pre&gt;
(use &#039;clojure.contrib.combinatorics)

(def choices
  &#039;((&quot;small&quot; &quot;medium&quot; &quot;large&quot;)
    (&quot;vanilla&quot; &quot;ultra chocolate&quot; &quot;lychee&quot; &quot;rum raisin&quot; &quot;ginger&quot;)
    (&quot;cone&quot; &quot;cup&quot;)))

(doseq [x (apply cartesian-product choices)] (apply println x))
&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p>Ha, well, turns out that the clojure-contrib library, a standard part of any serious Clojure setup, has some built-in combinatorics support.  That brings the Clojure sample down to a simple call to &#8220;cartesian-product&#8221;.  I use &#8220;apply&#8221; below since cartesian-product expects the choices to be supplied as a series of arguments rather than a list of lists.</p>
<pre>
(use 'clojure.contrib.combinatorics)

(def choices
  '(("small" "medium" "large")
    ("vanilla" "ultra chocolate" "lychee" "rum raisin" "ginger")
    ("cone" "cup")))

(doseq [x (apply cartesian-product choices)] (apply println x))
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Moonen</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-6368</link>
		<dc:creator>Scott Moonen</dc:creator>
		<pubDate>Fri, 07 Aug 2009 18:49:01 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-6368</guid>
		<description>I&#039;ve also tried a similar approach in Clojure.  I tried to combine Clojure&#039;s (for) macro with (gensym), but (for) didn&#039;t like anything other than a literal vector, so I couldn&#039;t make any progress there.  Instead I took a simple recursive approach, as with many of the solutions above:

&lt;pre&gt;
(def choices
  &#039;((&quot;small&quot; &quot;medium&quot; &quot;large&quot;)
    (&quot;vanilla&quot; &quot;ultra chocolate&quot; &quot;lychee&quot; &quot;rum raisin&quot; &quot;ginger&quot;)
    (&quot;cone&quot; &quot;cup&quot;)))

(defn combo [l]
  (if (empty? (rest l))
    (first l)
    (for [x (first l) y (combo (rest l))] (str x &quot; &quot; y))))

(doseq [x (combo choices)] (println x))
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>I&#8217;ve also tried a similar approach in Clojure.  I tried to combine Clojure&#8217;s (for) macro with (gensym), but (for) didn&#8217;t like anything other than a literal vector, so I couldn&#8217;t make any progress there.  Instead I took a simple recursive approach, as with many of the solutions above:</p>
<pre>
(def choices
  '(("small" "medium" "large")
    ("vanilla" "ultra chocolate" "lychee" "rum raisin" "ginger")
    ("cone" "cup")))

(defn combo [l]
  (if (empty? (rest l))
    (first l)
    (for [x (first l) y (combo (rest l))] (str x " " y))))

(doseq [x (combo choices)] (println x))
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Moonen</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-6367</link>
		<dc:creator>Scott Moonen</dc:creator>
		<pubDate>Fri, 07 Aug 2009 18:47:34 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-6367</guid>
		<description>A lot of the replies used Brian&#039;s original technique of passing in a &quot;sofar&quot;.  My Python version avoided this and did the concatenation on the return path, which seems a little more like the &quot;functional way&quot;.  Brian pointed out to me that my original Python version misunderstood the intentions for &quot;ultra chocolate&quot;.  A briefer and more correct version is available here: http://scott.andstuff.org/PythonSpikes</description>
		<content:encoded><![CDATA[<p>A lot of the replies used Brian&#8217;s original technique of passing in a &#8220;sofar&#8221;.  My Python version avoided this and did the concatenation on the return path, which seems a little more like the &#8220;functional way&#8221;.  Brian pointed out to me that my original Python version misunderstood the intentions for &#8220;ultra chocolate&#8221;.  A briefer and more correct version is available here: <a href="http://scott.andstuff.org/PythonSpikes" rel="nofollow">http://scott.andstuff.org/PythonSpikes</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Moonen</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-6365</link>
		<dc:creator>Scott Moonen</dc:creator>
		<pubDate>Fri, 07 Aug 2009 16:29:09 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-6365</guid>
		<description>Brian, Enumerable::inject is the Ruby equivalent of Python&#039;s reduce.  Looks like Enumerable::reduce was introduced as a synonym in Ruby 1.8.7.</description>
		<content:encoded><![CDATA[<p>Brian, Enumerable::inject is the Ruby equivalent of Python&#8217;s reduce.  Looks like Enumerable::reduce was introduced as a synonym in Ruby 1.8.7.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: XXX</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-78</link>
		<dc:creator>XXX</dc:creator>
		<pubDate>Tue, 11 Nov 2008 02:04:32 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-78</guid>
		<description>&lt;pre&gt;
APL:

?,??.{?,&#039; &#039;,?}/(&#039;small&#039; &#039;medium&#039; &#039;large&#039;)(&#039;vanilla&#039; &#039;ultra chocolate&#039; &#039;lychee&#039; &#039;rum raisin&#039; &#039;ginger&#039;)(&#039;cone&#039; &#039;cup&#039;)

J (2 solutions):

&gt;,{ (&#039;small&#039;;&#039;medium&#039;;&#039;large&#039;);(&#039;vanilla&#039;;&#039;ultra chocolate&#039;;&#039;lychee&#039;;&#039;rum raisin&#039;;&#039;ginger&#039;); , { options
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<pre>
APL:

?,??.{?,' ',?}/('small' 'medium' 'large')('vanilla' 'ultra chocolate' 'lychee' 'rum raisin' 'ginger')('cone' 'cup')

J (2 solutions):

&gt;,{ ('small';'medium';'large');('vanilla';'ultra chocolate';'lychee';'rum raisin';'ginger'); , { options
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ric</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-79</link>
		<dc:creator>Ric</dc:creator>
		<pubDate>Tue, 11 Nov 2008 01:13:01 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-79</guid>
		<description>There are some APL, J &amp; K versions of this program in &lt;a href=&quot;http://groups.google.com/group/comp.lang.apl/browse_thread/thread/c323c1da136d5c03/d148e7a626d27a5f#d148e7a626d27a5f&quot; title=&quot;&quot; rel=&quot;nofollow&quot;&gt;this comp.lang.apl thread&lt;/a&gt;. Here is a version in J:

&lt;pre&gt;
   Options=: ;: each (&#039;small large medium&#039;);(&#039;ginger lychee rum_raisin ultra_choc vanilla&#039;);(&#039;cone cup&#039;)
   choices=: monad : &#039;;:^:_1 &gt;,{ y&#039;
   choices Options
small vanilla cone
small vanilla cup
small ultra_choc cone
...
large rum_raisin cup
large ginger cone
large ginger cup
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>There are some APL, J &amp; K versions of this program in <a href="http://groups.google.com/group/comp.lang.apl/browse_thread/thread/c323c1da136d5c03/d148e7a626d27a5f#d148e7a626d27a5f" title="" rel="nofollow">this comp.lang.apl thread</a>. Here is a version in J:</p>
<pre>
   Options=: ;: each ('small large medium');('ginger lychee rum_raisin ultra_choc vanilla');('cone cup')
   choices=: monad : ';:^:_1 &gt;,{ y'
   choices Options
small vanilla cone
small vanilla cup
small ultra_choc cone
...
large rum_raisin cup
large ginger cone
large ginger cup
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Neil</title>
		<link>http://lojic.com/blog/2007/08/31/logo-ruby-javascript/comment-page-1/#comment-74</link>
		<dc:creator>Neil</dc:creator>
		<pubDate>Sat, 02 Feb 2008 18:22:15 +0000</pubDate>
		<guid isPermaLink="false">http://lojic.com/blog/2007/08/31/logo-ruby-javascript/#comment-74</guid>
		<description>One more:

&lt;pre&gt;
&lt;code&gt;
choices xss = mapM_ (putStrLn . unwords) (sequence xss)

main = choices [[&quot;small&quot;, &quot;medium&quot;, &quot;large&quot;],
 [&quot;vanilla&quot;, &quot;ultra chocolate&quot;, &quot;lychee&quot;, &quot;rum raisin&quot;, &quot;ginger&quot;],
 [&quot;cone&quot;, &quot;cup&quot;]]
&lt;/code&gt;
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>One more:</p>
<pre>
<code>
choices xss = mapM_ (putStrLn . unwords) (sequence xss)

main = choices [["small", "medium", "large"],
 ["vanilla", "ultra chocolate", "lychee", "rum raisin", "ginger"],
 ["cone", "cup"]]
</code>
</pre>
]]></content:encoded>
	</item>
</channel>
</rss>

