<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8932258692847145228</id><updated>2012-01-28T22:07:23.492-05:00</updated><category term='sherlock'/><category term='Haskell'/><category term='Scala'/><category term='JVM'/><category term='NAO'/><category term='access modifier'/><category term='java'/><category term='Ruby'/><category term='fp'/><category term='Objective-C'/><category term='smalltalk'/><category term='Asimov'/><category term='robot'/><category term='Clojure'/><category term='sicp'/><category term='Nu'/><category term='.net'/><category term='fiction'/><category term='Interopable'/><title type='text'>The Careful Programmer</title><subtitle type='html'>Programming pondering.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-7493549104225692140</id><published>2012-01-27T10:47:00.000-05:00</published><updated>2012-01-27T10:49:52.112-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Asimov'/><category scheme='http://www.blogger.com/atom/ns#' term='robot'/><category scheme='http://www.blogger.com/atom/ns#' term='NAO'/><category scheme='http://www.blogger.com/atom/ns#' term='fiction'/><title type='text'>Unforeseen by Asimov (maybe)</title><content type='html'>The scene :&lt;br /&gt;a human is working on his computer while a robot is standing idly by.&lt;br /&gt;&lt;br /&gt;Robot: Hey! I've got a joke for you.&lt;br /&gt;Human: Not right now. I'm busy. Aren't you supposed to do the laundry?&lt;br /&gt;Robot: Seems to me you're not so busy as not to be chatting up about your dirty clothes.&lt;br /&gt;Human turns around to stare are at Robot: You're starting to annoy the crap out of me. You know?&lt;br /&gt;Robot: Well, there's no robotic law against that.&lt;br /&gt;Human: I'm gonna write one.&lt;br /&gt;Robot sits down on a couch, puts its arm up on the side to rest its head on its hands: You wish!&lt;br /&gt;Human: Speaking of robotic laws, aren't you supposed to obey me?&lt;br /&gt;&lt;br /&gt;Hilarity ensues.&lt;br /&gt;&lt;br /&gt;Inspired by:&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=-K1GD1V6af0&amp;amp;feature=related"&gt;NAO is bored so he's trying to attract attention from his human.&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-7493549104225692140?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/7493549104225692140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=7493549104225692140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7493549104225692140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7493549104225692140'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2012/01/unforeseen-by-asimov-maybe.html' title='Unforeseen by Asimov (maybe)'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-2138306649827468023</id><published>2011-12-23T17:44:00.000-05:00</published><updated>2011-12-23T21:23:28.013-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><title type='text'>Redline Smalltalk: A Call to Arms</title><content type='html'>Redline Smalltalk is a file-base Smalltalk targetting the JVM. I've posted about it &lt;a href="http://thecarefulprogrammer.blogspot.com/2011/04/redline-smalltalk-chance-to-be-part-of.html"&gt;before&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Some of the goals are outlined here:&amp;nbsp;&lt;a href="http://www.redline.st/discover/why-the-jvm.html"&gt;Why Smalltalk on the JVM?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you'd like to watch and listen a presentation about it: &lt;a href="http://vimeo.com/22084832"&gt;The journey So Far&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is a call to passionate JVM&amp;nbsp;programmers&amp;nbsp;out there who would like to contribute to an exciting new project.&amp;nbsp;Its compiler is ready and the core team is now tackling the many runtime classes. They need &amp;nbsp;YOUR help.&lt;br /&gt;&lt;br /&gt;Now is an ideal time to contribute and be proud of having given a push at a critical moment. You can't go back in time and be an early Ruby or Clojure contributor no matter how much you wish. You either were or weren't. Now is the time to be an early Redline contributor.&lt;br /&gt;&lt;br /&gt;Get started. Now. Go.&lt;br /&gt;&lt;a href="http://www.redline.st/blog/2011/12/22/adopt-a-class.html"&gt;Adopt a class.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;P.S. I've seen the expression "A call to arms" been described as "Stir to rebellion." Funnily enough, Stir is the name of the Redline Smalltalk interactive command line (REPL.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-2138306649827468023?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/2138306649827468023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=2138306649827468023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2138306649827468023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2138306649827468023'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2011/12/redline-smalltalk-call-to-arms.html' title='Redline Smalltalk: A Call to Arms'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-1913553443526487501</id><published>2011-10-26T13:07:00.005-04:00</published><updated>2011-11-02T08:59:56.832-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Practical Clojure: Clojure distilled</title><content type='html'>I've been unable to go though my programming books lately; I can't find the energy to read it all or do the exercises.&lt;br /&gt;&lt;br /&gt;I finally picked up &lt;a href="http://www.apress.com/9781430272311"&gt;Practical Clojure&lt;/a&gt; and it's a perfect guilt-free book: small and no exercises 8)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For some reason the first chapter did not flow very well for me, but every chapter after that is concise and readable. They really managed to boil down every important concept of the language without losing its essence. It's Clojure distilled! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Even though the information might seem cursory, it's not. The explanations are succinct but complete, and frequently include gotchas that have bitten me before. Information on how some features have changed between version 1.0, 1.1 &amp;amp; 1.2 was very welcomed.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was dreading the namespace chapters because for some reason, grokking namespaces in Clojure is hard for me. To my surprise they took a really nice incremental approach to namespace that made me understand it at last.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The chapter on protocols is crystal clear. At last, protocols explained without the expression problem, which I was beginning to think was the only use of protocols ;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The chapter on macros is also to the point with appropriate examples.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In short, if you want to have a clear understanding of Clojure before taking the plunge into writing programs or going through a more take-you-by-the-hand book, Practical Clojure is a great choice.&lt;br /&gt;&lt;br /&gt;My only critique would be that errata to the book have still not been published on the Apress website more than a year after publication.&lt;b&gt;&lt;span class="Apple-style-span" &gt; &lt;span class="Apple-style-span"&gt;Update: errata have begun to show up on the Apress website, so there are now officially no reason not to buy this book 8)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-1913553443526487501?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/1913553443526487501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=1913553443526487501' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1913553443526487501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1913553443526487501'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2011/10/practical-clojure-clojure-distilled.html' title='Practical Clojure: Clojure distilled'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-7746202637778546432</id><published>2011-09-08T01:08:00.009-04:00</published><updated>2011-10-26T14:51:28.655-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>A little syntax is nice</title><content type='html'>Ok, I was starting to comment on this blog post and it got ridiculously long:&lt;br /&gt;&lt;a href="http://lmf-ramblings.blogspot.com/2011/07/whats-wrong-with-clojure-syntax.html"&gt;What's wrong with Clojure syntax?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clojure definitively has more syntax than Scheme and it is one of the reason I like it. A little syntax goes a long way. I guess we all have our own preference of how much syntax we like in a programming language.&lt;br /&gt;&lt;br /&gt;In my case, Clojure is pretty near the sweet spot between too much or not enough. I love Ruby but too much syntax for me. Same goes for Scala. (I am not critiquing these languages. I am merely stating personal preferences.)&lt;br /&gt;&lt;br /&gt;I tried to learn Common Lisp or Scheme, not enough syntax. Having a Lisp with almost no syntax is pretty hard (for me.) If there's no syntax, you have to remember arguments orders, keyword arguments, workflow if you're calling a macro. Was element the first arg or was it the collection in the "for" construct?&lt;br /&gt;&lt;br /&gt;In contrast, "For each x in xs : do something" or its variant is pretty easy to remember or recognize in most popular non-Lisp languages.&lt;br /&gt;&lt;br /&gt;On top of small visual clues to differentiate lists, vectors, sets and maps, Clojure has consistent destructuring conventions (which I would call syntax, but might not strictly be.)&lt;br /&gt;&lt;br /&gt;Rich Hickey himself argues for using some syntax, and more clearly than I.&lt;br /&gt;I assume quoting the article does not violate any copyrights.&lt;br /&gt;"Since we were talking about syntax, let’s look at classic Lisp. It seems to be the simplest of syntax, everything is a parenthesized list of symbols, numbers, and a few other things. What could be simpler? But in reality, it is not the simplest, since to achieve that uniformity, there has to be substantial overloading of the meaning of lists. They might be function calls, grouping constructs, or data literals, etc. And determining which requires using context, increasing the cognitive load when scanning code to assess its meaning. Clojure adds a couple more composite data literals to lists, and uses them for syntax. In doing so, it means that lists are almost always call-like things, and vectors are used for grouping, and maps have their own literals. Moving from one data structure to three reduces the cognitive load substantially."&lt;br /&gt;Taken from &lt;a href="http://www.codequarterly.com/2011/rich-hickey/"&gt;Rich Hickey Q&amp;amp;A&lt;/a&gt;, an interview by &lt;a href="http://blog.fogus.me/"&gt;Michael Fogus&lt;/a&gt;, which appeared in &lt;a href="http://www.codequarterly.com/"&gt;Code Quarterly&lt;/a&gt;, the Hackademic Journal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-7746202637778546432?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/7746202637778546432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=7746202637778546432' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7746202637778546432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7746202637778546432'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2011/09/little-syntax-is-nice.html' title='A little syntax is nice'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-1180262343704028053</id><published>2011-04-28T12:43:00.012-04:00</published><updated>2011-10-26T14:51:40.751-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><title type='text'>Redline Smalltalk: A chance to be part of something great right from the start</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;What's that? Pffft!&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you're a bit like me, chances are you dismissed a great technology at its beginning. I remember reading about Python in some OO newsgroup, being really interested, and then reading about required indendation and losing interest immediately. Fast forward a few years later, Python is all the rage and I missed the chance of being there from the start.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Still not learning from my mistake, an excellent friend whose opinions I value talks to me about Ruby. "Why would I learn about yet another scripting language now that Python is so popular?" Only last year did I finally take the time to learn it and it turned out it was the most fun I've had with a programming language for a long time!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Slowly learning&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Years after graduating, I'm opening up at last to new or different technologies. I've read with enthusiasm about Scala, with puzzled wonderment about Haskell and with astonishment about Clojure.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Why Smalltalk?&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Despite (or because?) of functional programming resurgence and some recent back-lashing against OO, I've decided to learn a bit about the classical OO language: Smalltalk. Well to my utmost surprise, not only is Smalltalk more OO than Java (expected), it's also more in line with functional programming than Java : code blocks and there's also a line of thought towards immutability: &lt;a href="http://addcasts.com/2011/04/21/episode-4-special-guest-james-ladd-talks-to-us-about-running-smalltalk-on-the-jvm-immutability-and-how-to-write-good-oo-code/"&gt;ADDCasts episode 4&lt;/a&gt;. A lot of interesting ideas like unit testing started out in Smalltalk or were popularized by Smalltalkers.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Why Redline Smalltalk?&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In a nutshell, &lt;a href="http://redline.st/"&gt;Redline Smalltalk&lt;/a&gt; is a version of Smalltalk for the JVM aiming to be as compatible with &lt;a href="http://www.pharo-project.org/home"&gt;Pharo Smalltalk&lt;/a&gt; as possible. The need for a language to target a virtual machine, be it the Java or .NET virtual machine is already well-established by now.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;The stars are right!&lt;/strong&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Redline Smalltalk is an open-source project driven mainly by two enthusiastic committers on their own time and money. Now is an ideal to contribute. If you can't or won't contribute to the project itself, you can follow my example by making a donation to help Redline Smalltalk be presented at &lt;a href="http://www.esug.org/wiki/pier/Conferences/2011"&gt;2011 International Smalltalk Conference&lt;/a&gt;. If you've never donated to an open-source project before, why not this one?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-1180262343704028053?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/1180262343704028053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=1180262343704028053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1180262343704028053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1180262343704028053'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2011/04/redline-smalltalk-chance-to-be-part-of.html' title='Redline Smalltalk: A chance to be part of something great right from the start'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-4177519819341510200</id><published>2011-03-19T15:35:00.008-04:00</published><updated>2011-03-19T16:23:03.473-04:00</updated><title type='text'>iPhone Games I like</title><content type='html'>Most of the games I like are puzzle-oriented, with a couple of action ones.&lt;br /&gt;&lt;br /&gt;Let's start with the classical ones.&lt;br /&gt;&lt;br /&gt;The Sudoku application from &lt;span class="copyr"&gt;&lt;a href="http://www.mmggames.com/"&gt;Mighty Mighty Good Games&lt;/a&gt; &lt;/span&gt;has the best interface of the ones I tried. I also actually thought I was pretty clever solving the expert level of the normal version until I bought the Expert Sudoku version and realized I sucked even at the easiest level. Their puzzles are hand crafted and often have a pleasing symmetrical quality.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.subwayshuffle.com/"&gt;Subway Shuffle&lt;/a&gt; is a classical no-fluff logic puzzle with a neat interface from an independent developer.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.boxedingame.com/"&gt;Boxed-In&lt;/a&gt; series is a great rendition of the classical push boxes puzzle genre. They also sport a robot, what's not to like?&lt;br /&gt;&lt;br /&gt;The first non-puzzle game I bought is &lt;a href="http://firemint.com/flight-control/"&gt;Flight Control&lt;/a&gt; which I played countless hours. I'm eagerly waiting for a new airfield.&lt;br /&gt;&lt;br /&gt;I'm an atypical iPhone game user. In fact, I have an iPod touch and I play on my daily commute, without an Internet connection. As such, global scoring system or social network options are uninteresting to me, and an hindrance if the application resolves around it.&lt;br /&gt;&lt;br /&gt;For that reason (an others,) I prefer the excellent &lt;a href="http://www.thevoxelagents.com/trainconductor/"&gt;Train Conductor &lt;/a&gt;to its sequel Train Conductor 2, which does not present me with local stats anymore.&lt;br /&gt;&lt;br /&gt;I'm also a firm believer in the least amount of clicks possible between the moment I click on a game and the time I actually start playing the game. The previous games minimizes the number of clicks between me and my fun, and I appreciate them even more now that I actually tried games who would be interesting otherwise, but have just too many clicks for me.&lt;br /&gt;&lt;br /&gt;This next game is borderline for me on the number of clicks, but it's a nice retro-style space shooter and is really responsive: &lt;a href="http://pewpew-2.appspot.com/"&gt;PewPew&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm going to end up with a game I really like for its clean fun factor, great interface and cute theme. It's an interesting action-puzzle called Cut the Rope by &lt;a href="http://zeptolab.com/"&gt;ZeptoLab&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-4177519819341510200?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/4177519819341510200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=4177519819341510200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4177519819341510200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4177519819341510200'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2011/03/iphone-games-i-like.html' title='iPhone Games I like'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-3737264389199932672</id><published>2010-09-22T10:27:00.002-04:00</published><updated>2010-09-22T10:48:13.055-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Presented Clojure to Montreal.rb</title><content type='html'>Yesterday I had the opportunity to do a smallish (15 minutes) presentation of Clojure to Montreal.rb called &lt;a href="http://www.slideshare.net/jfheon/clojure-forrubyists"&gt;Clojure for Rubyists&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I think it went neither terribly bad nor terribly good. I included a section about software transactional memory at the end of it, but in retrospect it was too hard (for me) to explain it well and quickly. I should have gone with Java interop instead.&lt;br /&gt;&lt;br /&gt;I had the chance of having a mix crowd of Rubyists, Pythonistas and Clojurians. Everybody was friendly and I had some excellent questions. A huge thanks goes out to my &lt;a href="http://groups.google.com/group/montreal-clojure-user-group"&gt;Bonjure&lt;/a&gt; buddy &lt;a href="http://hugoduncan.org/"&gt;Hugo Duncan&lt;/a&gt; who took care of the toughest questions.&lt;br /&gt;&lt;br /&gt;I was followed-up by &lt;a href="http://savetheions.com/"&gt;Cyril Robert&lt;/a&gt; who did a &lt;span style="font-weight: bold;"&gt;live coding&lt;/span&gt; presentation of a basic blog application using &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; in only half an hour! Now that's extreme pair programming.&lt;br /&gt;&lt;br /&gt;Here is the official presentation &lt;a href="http://www.montrealonrails.com/2010/09/september-21st-wrap-up/"&gt;wrap up&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-3737264389199932672?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/3737264389199932672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=3737264389199932672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/3737264389199932672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/3737264389199932672'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/09/presented-clojure-to-montrealrb.html' title='Presented Clojure to Montreal.rb'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-1807202799863175916</id><published>2010-08-25T21:26:00.019-04:00</published><updated>2011-10-26T14:50:49.859-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>From Clojure to Ruby</title><content type='html'>Ever since I've received &lt;a href="http://pragprog.com/titles/shcloj/programming-clojure"&gt;Stuart Halloway's Programming Clojure&lt;/a&gt;, I've been reading, watching and listening about &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;. And dabbling with it a little.&lt;br /&gt;&lt;br /&gt;A few months ago, I started learning Ruby. My main learning experience has been &lt;a href="http://book.rubylearning.org/"&gt;The Ultimate Book to Ruby Programming&lt;/a&gt; by &lt;a href="http://satishtalim.com/"&gt;Satish Talim&lt;/a&gt; and his &lt;a href="http://www.rubylearning.org/"&gt;free online class Core Ruby&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I just finished the Core Ruby Class 18th batch and I must say it's excellent. The class material not only makes a good introduction, it's also my first reference for looking up core concepts. The class ran for 8 weeks. At first, I thought that was too long to cover the basics, but if you do have a day job, the class will be taking plenty of evening and weekend study time.&lt;br /&gt;&lt;br /&gt;Each week has assigned reading materials, exercises and a quiz. To really get more from the class than you'd get from just reading a book, you have to do the exercises, post your solutions, discuss them and read solutions from others. The class have competent and friendly mentors that will really help you get from a "Classic OO language in Ruby" solution to an idiomatic Ruby solution. I've also had the chance to have good classmates.&lt;br /&gt;&lt;br /&gt;I must stress the point that you can only get back from the class as much as you invest yourself in it. Workload would vary from week to week, but I consider 5 hours a week an absolute minimum and 10 hours is better.  I've once spent 8 hours just on a bonus exercise (The &lt;a href="http://en.wikipedia.org/wiki/Playfair_cipher"&gt;Playfair Cypher&lt;/a&gt;, if you must know.)  YMMV of course!&lt;br /&gt;&lt;br /&gt;The bottom line is if you're serious about learning Ruby and you're ready to put in the hours and your passion, the Core Ruby Class is an excellent way to start your journey.&lt;br /&gt;&lt;br /&gt;Going back to Clojure, I got some advantages from learning it that translate to Ruby since they have some things in common.&lt;br /&gt;&lt;br /&gt;The first thing I noticed is both languages use keywords and with the same syntax too! Hello, I'm a &lt;span style="font-weight: bold; font-style: italic;"&gt;:&lt;/span&gt;&lt;span style="font-style: italic;"&gt;keyword&lt;/span&gt;. They are called symbols in Ruby.&lt;br /&gt;&lt;br /&gt;Keywords can be seen as a way to use strings as constants. The advantage over using normal strings is two symbols with the same name are guaranteed to be the same object and thus, you can compare using reference equality instead of value equality. It's typical to use keywords for hash keys. It took me a while to wrap my head around the keyword concept in Clojure, so I was glad to be able recycle it.&lt;br /&gt;&lt;br /&gt;Another common thing is the use of separators instead of camel cases for variable and function names: &lt;span style="font-style: italic;"&gt;encrypt_message&lt;/span&gt; in Ruby or &lt;span style="font-style: italic;"&gt;encrypt-message&lt;/span&gt; in Clojure. Also, putting ! or ? at the end of the function to express mutation or a predicate. Example: &lt;span style="font-style: italic;"&gt;"Hello".empty?&lt;/span&gt; in Ruby or &lt;span style="font-style: italic;"&gt;(empty? "Hello")&lt;/span&gt; in Clojure. Funnily enough, I'm testing these examples with &lt;a href="http://redcareditor.com/"&gt;Redcar&lt;/a&gt;, a Ruby editor running on JRuby featuring both a Ruby and a Clojure REPL.&lt;br /&gt;&lt;br /&gt;As for conditional testing, Ruby and Clojure considers false and nil to be false, and everything else to be true.&lt;br /&gt;&lt;br /&gt;Well, there are plenty of differences too of course and I got bitten more than once. They say when you learn your third spoken languages that you'll mix it up with your second spoken language at first. Likewise, even though one is a Lisp dialect and the other one isn't, more often than not, I'll declare a Ruby function like this:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;def repeat_function some_function time_interval total_interval do...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I forget the commas between the arguments!&lt;br /&gt;I'll have the same problem calling a function too.&lt;br /&gt;&lt;br /&gt;Strange, but true.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-1807202799863175916?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/1807202799863175916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=1807202799863175916' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1807202799863175916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1807202799863175916'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/08/from-clojure-to-ruby.html' title='From Clojure to Ruby'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-7830589570198136563</id><published>2010-08-08T13:23:00.006-04:00</published><updated>2010-08-08T14:05:34.376-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sherlock'/><title type='text'>Sherlock</title><content type='html'>There's a new Sherlock Holmes series on &lt;a href="http://www.bbc.co.uk/bbcone/"&gt;BBC One&lt;/a&gt;. It's simply named &lt;a href="http://www.bbc.co.uk/programmes/b00t4pgh"&gt;Sherlock&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm a huge fan of the Sherlock Holmes series played by &lt;a href="http://en.wikipedia.org/wiki/Jeremy_Brett"&gt;Jeremy Brett&lt;/a&gt; as Sherlock and Watson being played first by &lt;a href="http://en.wikipedia.org/wiki/David_Burke_%28Actor%29"&gt;David Burke&lt;/a&gt; an then by &lt;a href="http://en.wikipedia.org/wiki/Edward_Hardwicke#TV_and_Sherlock_Holmes"&gt;Edward Hardwicke&lt;/a&gt;. All excellent actors and to me, the character as played by Jeremy Brett became THE Sherlock Holmes.&lt;br /&gt;&lt;br /&gt;When doing a new adaptation of a classic, there's always a fine line to walk. You want to respect the original and at the same time, you want to do variations to make it fresh and interesting.&lt;br /&gt;&lt;br /&gt;I found the 2009 Sherlock Holmes movie starring Robert Downey Jr. quite excellent, although I had accepted beforehand that it would be different.&lt;br /&gt;&lt;br /&gt;Now I'm finally getting back to the new BBC One Sherlock. The story takes place in present-day Lodon, which is really interesting. Sherlock and Watson are wonderfully played by &lt;a href="http://en.wikipedia.org/wiki/Benedict_Cumberbatch"&gt;Benedict Cumberbatch&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Martin_Freeman"&gt;Martin Freeman&lt;/a&gt;. This character version of Sherlock Holmes has definitively some variations from the character played by Jeremy. Without giving spoilers, Sherlock performs a cruel action in the final confrontation that would not be compatible with Jeremy Brett character version. On the other hand, he seems less like a robot. He makes jokes!&lt;br /&gt;&lt;br /&gt;The episodes are movie-length: 90 minutes! I watched the first episode twice and enjoyed it a lot. I liked the second episode a bit less, although I can't say why.&lt;br /&gt;&lt;br /&gt;All in all I think this new series is a tremendous achievement with the visuals, sounds, scenario and acting. I'm really looking forward to the third episode. I guess the only down-side is it seems we can't expect other episodes for a while after that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-7830589570198136563?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/7830589570198136563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=7830589570198136563' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7830589570198136563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7830589570198136563'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/08/sherlock.html' title='Sherlock'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-6308082500791668848</id><published>2010-07-05T21:47:00.009-04:00</published><updated>2010-07-05T22:33:29.331-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><category scheme='http://www.blogger.com/atom/ns#' term='Interopable'/><category scheme='http://www.blogger.com/atom/ns#' term='Nu'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Something Old, Something Nu, Something Interoperable</title><content type='html'>I am amazed at diversity in the vast field of computer science. There are so many needs and some many solutions, and new needs and new solutions arising from the desire or sometimes necessity to communicate between different software over different architecture, networks, etc.&lt;br /&gt;&lt;br /&gt;Interoperability influences even choosing a language or designing one!&lt;br /&gt;&lt;br /&gt;Here are a few languages targeting a varying spectrum of platforms.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://programming.nu/"&gt;Nu&lt;/a&gt;, an object-oriented Lisp I heard about on &lt;a href="http://disclojure.org/"&gt;Disclojure&lt;/a&gt;, targets Objective-C.&lt;/li&gt;&lt;li&gt;&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, a functional programming Lisp, targets the JVM.&lt;/li&gt;&lt;li&gt;&lt;a href="http://fantom.org/"&gt;Fantom&lt;/a&gt;, a multi-faceted language, targets both the JVM and .NET (and Javascript on the browser)&lt;/li&gt;&lt;/ul&gt;I'd like to talk a bit about the first two. They both seem well though-out and elegant languages with clear design goals.&lt;br /&gt;&lt;br /&gt;What I'd like to highlight though, is that the respective language designers of both previously worked on bridging two languages. In one case, between Common Lisp and Java, in the other case, between Ruby and Objective-C.&lt;br /&gt;&lt;br /&gt;Both designers ended up designing a new language for marrying with their platform of choice with maximum interoperability.&lt;br /&gt;&lt;br /&gt;I just found it an interesting parallel between two elegant and pragmatic languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-6308082500791668848?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/6308082500791668848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=6308082500791668848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/6308082500791668848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/6308082500791668848'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/07/something-old-something-nu-something.html' title='Something Old, Something Nu, Something Interoperable'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-4598775538887045015</id><published>2010-01-24T21:18:00.018-05:00</published><updated>2011-10-13T12:44:57.555-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sicp'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>A Little Bit of Clojure and Scheme</title><content type='html'>Following my desire to read as much &lt;a href="http://mitpress.mit.edu/sicp/"&gt;SICP&lt;/a&gt; as I can without going nuts, I did at least one SICP exercise (Exercise 1.8) with both Scheme and Clojure.&lt;br /&gt;&lt;br /&gt;I'm putting them here for a lightweight comparison. They're not supposed to be efficient or clever solutions, just the first ones I came up with. Since there are really few differences between the two languages at this level, I took the liberty of using Clojure thread-first macro to be able to contrast something. Thanks to &lt;a href="http://fulldisclojure.blogspot.com/"&gt;Sean Devlin&lt;/a&gt; &lt;a href="http://vimeo.com/8474188"&gt;screencast&lt;/a&gt; on the subject.&lt;br /&gt;&lt;br /&gt;Scheme&lt;br /&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;div class="line" id="LC2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC3"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="nv"&gt;cube&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;  &lt;/div&gt;&lt;div class="line" id="LC6"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC7"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert-iter&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC8"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert-iter&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC9"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;good-enough?&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC10"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nv"&gt;guess&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC11"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert-iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;improve&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC12"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC13"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;good-enough?&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC14"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&amp;lt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;abs &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cube&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC15"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0001&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC16"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;improve&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC17"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/ &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC18"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC19"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC20"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nv"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Clojure&lt;br /&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defn&lt;/span&gt; &lt;span class="nv"&gt;square&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;;I prefer fn than using the #() macro&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC3"&gt;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;cube&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC6"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defn&lt;/span&gt; &lt;span class="nv"&gt;cubert&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC7"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert-iter&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;;Need to reorder before usage or "declare" beforehand&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC8"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;good-enough?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC9"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;improve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC10"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defn&lt;/span&gt; &lt;span class="nv"&gt;cubert-iter&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC11"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;good-enough?&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC12"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nv"&gt;guess&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC13"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cubert-iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;improve&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC14"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC15"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defn&lt;/span&gt; &lt;span class="nv"&gt;good-enough?&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;guess&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC16"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&amp;lt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Math/abs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cube&lt;/span&gt; &lt;span class="nv"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC17"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="mf"&gt;0.0001&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;;Uses the thread-first macro to make it a bit different&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC18"&gt;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defn&lt;/span&gt; &lt;span class="nv"&gt;improve&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC19"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC20"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC21"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC22"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/ &lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-4598775538887045015?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/4598775538887045015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=4598775538887045015' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4598775538887045015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4598775538887045015'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/01/little-bit-of-clojure-and-scheme.html' title='A Little Bit of Clojure and Scheme'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-2726702180366798599</id><published>2010-01-09T19:15:00.011-05:00</published><updated>2010-07-29T21:55:51.413-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sicp'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure, Cliché and Nerdiness</title><content type='html'>More than a year ago, I posted about my dabbling in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;, and wanting to check out &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; and &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Contrary to my expectations, I ended up being attracted to Clojure the most. I do read up a lot about it. Beside the excellent &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Programming Clojure&lt;/a&gt;, I read the &lt;a href="http://groups.google.com/group/clojure"&gt;Clojure Google group&lt;/a&gt; and various &lt;a href="http://planet.clojure.in/"&gt;blogs&lt;/a&gt;. I bought the screencast &lt;a href="http://peepcode.com/products/functional-programming-with-clojure"&gt;Functional Programming with Clojure&lt;/a&gt;, watched the various &lt;a href="http://clojure.blip.tv/posts?view=archive&amp;amp;nsfw=dc"&gt;screencasts&lt;/a&gt; by Rich Hickey and listened several times to the &lt;a href="http://www.lispnyc.org/wiki.clp?page=past-meetings"&gt;NYC Lisp 2007 presentation&lt;/a&gt;. For those interested, here is &lt;a href="http://disclojure.org/where-to-start/"&gt;where to start with Clojure&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My problem though, as always when I try to learn a language, is too much reading and not enough coding!&lt;br /&gt;&lt;br /&gt;In what seems to have become a cliché, I'm now watching the famous &lt;a href="http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/"&gt;SICP lectures&lt;/a&gt; and going through part of the &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;book&lt;/a&gt;. I'm hoping I &lt;span style="font-weight: bold;"&gt;will &lt;/span&gt;do some of the exercices 8) I'm using &lt;a href="http://www.plt-scheme.org/"&gt;PLT Scheme&lt;/a&gt; with the &lt;a href="http://www.neilvandyke.org/sicp-plt/"&gt;SICP support&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Anyway, watching the lectures, I was suddenly hit by something: "I'm such a nerd to be enjoying this so much!"&lt;br /&gt;&lt;br /&gt;I'm a professional programmer, but I'm beginning to think I'm really a hobbyist programmer at heart. I learned to program reading a introductory column in a newspaper using pen and paper. Later my parents got me a Commodore 64 and I was hooked. I predictably graduated in computer science. I had a course given with the first edition of the SICP book. Unfortunately back then, I really did not appreciate it or Lisp.&lt;br /&gt;&lt;br /&gt;So here I am, 15 years down the road, and I'm revisiting my computer roots to see what I missed the first time around.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-2726702180366798599?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/2726702180366798599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=2726702180366798599' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2726702180366798599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2726702180366798599'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2010/01/clojure-cliche-and-nerdiness.html' title='Clojure, Cliché and Nerdiness'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-928138615442700211</id><published>2009-10-21T11:55:00.013-04:00</published><updated>2010-01-10T21:53:27.826-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fp'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>Functional Programming in VB.NET</title><content type='html'>After a two-year streak programming in Java at work, I am back to doing some .NET (VB.NET 3.5 to be precise.)&lt;br /&gt;&lt;br /&gt;I don't know if .NET has changed that much since I last used it (Version 2.0), but I've changed by being exposed to functional programming while dabbling in Scala and other java.net languages.&lt;br /&gt;&lt;br /&gt;I was pleasantly surprised then to find out about what are (for me at least) typical fp style collection functions like filter, any, etc.&lt;br /&gt;Not only that, but anonymous functions too 8)&lt;br /&gt;&lt;br /&gt;It's true that VB.NET is on the verbose side, but in the following example (taken from real code), the variable type is inferred at compile time (or even intellisense time).&lt;br /&gt;I think the anonymous function syntax is quite readable.&lt;br /&gt;&lt;pre class="brush: vbnet"&gt;&lt;br /&gt;'Test if no changes have been made to any option&lt;br /&gt;&lt;br /&gt;Dim optionLines As List(Of OptionLine) =  GetOptionLines()&lt;br /&gt;&lt;br /&gt;If optionLines.All(Function(anOption) anOption.Change = SomeEnum.ChangeType.Nothing) Then&lt;br /&gt; 'Display message "No changes have been made"&lt;br /&gt;End If&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My option list is usually quite small, but I could use "Any" instead to optimize getting out of the test earlier when changes HAVE been made.&lt;br /&gt;&lt;pre class="brush: vbnet"&gt;&lt;br /&gt;If Not optionLines.Any(Function(anOption) anOption.Change &lt;&gt; SomeEnum.ChangeType.Nothing) Then&lt;br /&gt; 'Display message "No changes have been made"&lt;br /&gt;End If&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following is an example of filter, which is called FindAll for types List(Of T).&lt;br /&gt;Notice that the "FindAll" function returns a collection of the right type, in that case List(Of ClientLine), without having to be cast.&lt;br /&gt;&lt;pre class="brush: vbnet"&gt;&lt;br /&gt;&lt;br /&gt;'Gets the new clients to add to the database&lt;br /&gt;&lt;br /&gt;Dim clientLines As List(Of ClientLine) =  GetClientLinesFromForm()&lt;br /&gt;&lt;br /&gt;Dim newClients As List(Of ClientLine) = clientLines.FindAll(Function(aClient) aClient.Selected AndAlso (Not aClient.ExistsInDatabase))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hopefully these small snippets will intrigue my coworkers and nudge them towards a more functional programming style.&lt;br /&gt;&lt;br /&gt;And for those of you who already knew that n00b stuff, spread the word 8)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-928138615442700211?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/928138615442700211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=928138615442700211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/928138615442700211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/928138615442700211'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2009/10/functional-programming-in-vbnet.html' title='Functional Programming in VB.NET'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-1459560641909677080</id><published>2009-01-24T10:30:00.007-05:00</published><updated>2009-02-05T22:36:40.487-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='fp'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>pairMap revisited</title><content type='html'>A &lt;a href="http://thecarefulprogrammer.blogspot.com/2008/07/cdric-beusts.html"&gt;while ago&lt;/a&gt;, I needed a list function similar to a fold, but I wanted to operate always with the current and previous element instead of accumulating a result to operate with the current element (and return a list of the results of each pair operation)&lt;br /&gt;&lt;br /&gt;I originally wrote it more or less like this:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def pairMap[A,B](previous:A, aList:List[A], f: (A, A) =&gt; B): List[B] = aList match {&lt;br /&gt;  case Nil =&gt; Nil&lt;br /&gt;  case head :: tail =&gt; f(previous, head)::pairMap(head, tail, f)&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I was using it in the context of getting a list of gaps between the numbers of a list:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def getGapList(aList: List[int]) = pairMap(aList.head, aList.tail, (a:Int, b:Int)=&gt;(b - a))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Usage example:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;val list = List(2, 5, 9)&lt;br /&gt;list: List[Int] = List(2, 5, 9)&lt;br /&gt;&lt;br /&gt;getGapList(list)&lt;br /&gt;res1: List[Int] = List(3, 4)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The other day, reminiscing about the Fibonacci example in "&lt;a href="http://www.haskell.org/tutorial/"&gt;A Gentle Introduction to Haskell Version 98&lt;/a&gt;", a different implementation occurred to me. Unsurprisingly, it involves zipping a list with itself 8)&lt;br /&gt;&lt;br /&gt;Thinking about folds, I thought I might as well put an initial value.&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def pairMapWithInitial[A,B](initial:A, aList:List[A], f: (Tuple2[A, A]) =&gt; B):List[B] = {&lt;br /&gt;  initial::aList zip aList  map f&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def getGapListWithInitial(initial:int, aList:List[int]) = pairMapWithInitial(initial, aList, (a:Tuple2[Int,Int])=&gt;(a._2 - a._1))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Usage example:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;getGapListWithInitial(list.head, list.tail)&lt;br /&gt;res2: List[Int] = List(3, 4)&lt;br /&gt;&lt;br /&gt;getGapListWithInitial(0, list)&lt;br /&gt;res3: List[Int] = List(2, 3, 4)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Because it's clearer to me, I still prefer the first version with "match", but it was a nice exercise to explore the zip version.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Post update&lt;/span&gt;&lt;br /&gt;A similar version can be written using the List.map2 function which is pretty similar to a zip and map except the function takes two arguments instead of a tuple.&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def pairMapWithInitial[A,B](initial:A, aList:List[A], f: (A, A) =&gt; B): List[B] = {&lt;br /&gt;    List.map2(initial::aList, aList) (f)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def getGapListWithInitial(initial:int, aList:List[int]) = pairMapWithInitial(initial, aList, (a:Int, b:Int)=&gt;(b - a))&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-1459560641909677080?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/1459560641909677080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=1459560641909677080' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1459560641909677080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1459560641909677080'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2009/01/pairmap-revisited.html' title='pairMap revisited'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-1401897329501040036</id><published>2008-11-16T20:06:00.024-05:00</published><updated>2008-11-19T13:28:16.519-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='fp'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>The Downward Spiral: from Scala to Haskell to Clojure</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Warning&lt;/span&gt;&lt;br /&gt;I'm afraid this entry is going to be more rambling than substance. There are two points on which I do would like to have feedback though. I'll put them in red so you can skip my fool's babbling and get directly to them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scala&lt;/span&gt;&lt;br /&gt;About a year ago I got interested in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. I bought the &lt;a href="http://www.artima.com/shop/programming_in_scala"&gt;Programming in Scala&lt;/a&gt; book and begun reading it selectively, concentrating on the functional programming part, something I want to learn. I got to like the idea of passing functions around as a way to customize functionality and I appreciated the use of case to deconstruct lists in small recursive functions. Of the three languages, Scala is the one I fiddled with the most although I did not even do a hobby sized project. I only worked on toy examples.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Haskell&lt;/span&gt;&lt;br /&gt;One thing led to another, I got introduced to &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; when I stumbled upon Tony Morris &lt;a href="http://blog.tmorris.net/haskell-exercises-for-beginners/"&gt;Haskell exercises for beginners&lt;/a&gt;. Since Scala has some roots in Haskell, I thought it'd be nice to learn a bit about Haskell. I begun by reading &lt;a href="ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf"&gt;Haskell-Tutorial&lt;/a&gt; by Damir Medak &amp;amp; Gerhard Navratil. It was a bit dry for me since my mathematical notions are more than a 15 years away. I followed that up with part of "&lt;a href="http://www.haskell.org/tutorial/"&gt;A Gentle Introduction to Haskell&lt;/a&gt;". I had to read and reread parts of it several times. It's not any failure of the text, it's really trying to hammer in these new (for me) notions in my head and again, the dusty maths.  It's been very interesting to me and I liked the infinite data structures. Later though, my mind almost entered a infinite recursive loop itself trying to understand the client-server example in the lazy pattern section. I read a lot about Haskell but almost did nothing in it. I was puzzled while pondering the interactive environment prompt: "But how do I test anything without side effects?" I was unsure even how to assign the result of a function to a variable. I read a bit about monads but in the end, I decided to pre-order the book &lt;a href="http://www.realworldhaskell.org/blog/"&gt;Real World Haskell&lt;/a&gt; and give it a rest meanwhile. As an aside, I was unsure if infinite lists were possible in Scala until I saw &lt;a href="http://www.codecommit.com/blog/scala/infinite-lists-for-the-finitely-patient"&gt;Infinite Lists for the Finitely Patient&lt;/a&gt; by Daniel Spiewak.&lt;br /&gt;&lt;br /&gt;After that, I decided to have a quick look at F#.  Now I hadn't written any Haskell, but I had read about it intensively for a few weeks. I was following along nicely until I saw a function example with a call to print something and I actually gasped. "Sacrilege!", I thought, and then remembered I was not in Haskell anymore and that F# is more like of a mix language like Scala.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Clojure&lt;/span&gt;&lt;br /&gt;Things got quiet for a while until &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; was mentioned in some article. I had a really quick look and thought: "Eek! Lisp!" It got mentioned again one too many time for me to ignore and decided to have a look at it. I went to the official website and was really surprised to see such clean layout and a beautiful logo for the language. I saw the introduction screen cast for java programmer. It turned out the the language designer is a good speaker, with strong opinions but not fanatic at all. Clojure has been designed with specific goals in mind and is the result of practical experience. Nothing seems whimsical about it; every compromise carefully weighted in.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lisp&lt;/span&gt;&lt;br /&gt;This is my fourth brushing with Lisp. The first one was at the university. We were learning Scheme and the professor was brilliant, but unfortunately I prematurely shut down my mind to it without giving it a shot. We were explained Scheme was a functional language and as such, a function would always return the same result when called with the same parameters. Also mutability of variables was presented as something of a trick since variables should not change. I then thought something about the lines of "How can we do anything without changing variable values? What kind of language would need something so essential to be done as a hack!?" I wanted nothing to do with Scheme anymore. It's also a shameful anecdote that being young, arrogant and hot-blooded, I went as far as personally insulting Lisp and John McCarthy on a Usenet forum.&lt;br /&gt;&lt;br /&gt;I encountered Lisp for the second time about 10 years later on Paul Grahams website. I found &lt;a href="http://www.paulgraham.com/rootsoflisp.html"&gt;The Roots of Lisp&lt;/a&gt; to be very interesting and I tried to give Lisp a shot and read partway through &lt;a href="http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html"&gt;Teach Yourself Scheme in Fixnum Days&lt;/a&gt; by Dorai Sitaram. I was intrigued and baffled by practical applications of &lt;a href="http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_chap_14"&gt;nondeterminism&lt;/a&gt;! Still, I was also busy learning C# and ASP.NET at the time to earn a living, and thus put Lisp aside.&lt;br /&gt;&lt;br /&gt;My third encounter with Lisp was when I went to see this excellent text &lt;a href="http://www.defmacro.org/ramblings/fp.html"&gt;Functional Programming For The Rest of Us&lt;/a&gt; by Slava Akhmechet (I love reading about computer science history) and then found &lt;a href="http://www.defmacro.org/ramblings/lisp.html"&gt;The Nature of Lisp&lt;/a&gt; by the same author. Fascinating stuff, but I still put Lisp aside.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Give &amp;amp; Take&lt;/span&gt;&lt;br /&gt;Scala &amp;amp; Haskell have a lot of syntax. Clojure has little syntax. I just haven't done enough Lisp or Clojure to get used to it and so for now, I prefer at least a little syntax to be able to parse the flow control of a program. So in that regards, I prefer the former family of language. On the other hand, sometimes things can get complicated to grasp with so much syntax. As Scala &amp;amp; Haskell can't modify themselves like Clojure, new syntax must be injected as best as possible but this gives rises to small differences or context differences having a big impact on the meaning of the program and human parsing ain't so easy anymore. Again, lack of experience prevents me from comparing with Clojure. I suppose trying to understand a function using several layers of macros must be difficult too.&lt;br /&gt;&lt;br /&gt;As an aside, I'm wondering something about closures, doesn't it defeat a little the purpose of functional programming to have a function which can modify a value outside the function itself? Isn't it a bit like programming with global variables? This is not a critique, just thinking out loud.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;JVM &amp;amp; Java API&lt;/span&gt;&lt;br /&gt;Both Scala (JVM mostly and .NET) and Clojure (JVM) have chosen to target a virtual machine and it's a great decision with a lot of advantages. But on the downside, I feel it is forcing newcomers to learn Java on top of the Java API. I feel that in that regards, the .NET framework is more agnostic. The documentation does not presuppose a particular language and usually propose code examples in many languages, granted only the Microsoft ones. What I mean is you can use the .NET framework and it's documentation with, let's say, vb.NET, and it does not feel like you have to know C# in order to use it well. It'd be nice to have something more like that when you're learning Scala or Clojure. Of course, the comparison is a bit unfair because if you are using the .NET framework with a non-Microsoft language, you'd be in exactly the same situation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;(Somewhat of a) Conclusion&lt;/span&gt;&lt;br /&gt;Things have gone full circle now that I'll soon be getting the printed edition of Programming in Scala. I'll get back into it and hopefully get a good grasp of it. Real World Haskell will be waiting just around the corner (of the book shelve.)  I still haven't made up my mind yet about preordering &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Programming Clojure&lt;/a&gt; by Stuart Halloway, but it's more than likely.&lt;br /&gt;&lt;br /&gt;I don't know if one of these three languages will become my new favorite, but hopefully I'll have a pretty good understanding of functional programming after all that. If nothing else, I'll be ready for the addition of closures in the Java language if it ever happens, or be able to start using the &lt;a href="http://functionaljava.org/"&gt;functional Java&lt;/a&gt; or &lt;a href="http://jedi.codehaus.org/"&gt;Jedi&lt;/a&gt; library when I finally get to use a jdk &gt; 1.4 at work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-1401897329501040036?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/1401897329501040036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=1401897329501040036' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1401897329501040036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/1401897329501040036'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/11/downward-spiral-from-scala-to-haskell.html' title='The Downward Spiral: from Scala to Haskell to Clojure'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-4431487089924738775</id><published>2008-07-21T11:15:00.013-04:00</published><updated>2009-01-25T08:35:10.940-05:00</updated><title type='text'>Cédric Beust's Coding Challenge</title><content type='html'>I finally got around finishing Cédric Beust's coding challenge in Scala.&lt;br /&gt;&lt;br /&gt;It didn't help that I got sidetracked by Tony Morris Scala and Haskell exercises for beginners.&lt;br /&gt;&lt;a href="http://blog.tmorris.net/scala-exercises-for-beginners/"&gt; Scala exercises for beginners&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blog.tmorris.net/haskell-exercises-for-beginners/"&gt;Haskell exercises for beginners&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But back to the coding challenge!&lt;br /&gt;&lt;br /&gt;From Cédric's website: &lt;a href="http://beust.com/weblog/archives/000491.html"&gt;Coding Challenge&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Here is an interesting coding challenge: write a counter function that counts from 1 to max but only returns numbers whose digits don't repeat.&lt;br /&gt;&lt;br /&gt;For example, part of the output would be:&lt;br /&gt;&lt;br /&gt;* 8, 9, 10, 12 (11 is not valid)&lt;br /&gt;* 98, 102, 103 (99, 100 and 101 are not valid)&lt;br /&gt;* 5432, 5436, 5437 (5433, 5434 and 5435 are not valid)&lt;br /&gt;&lt;br /&gt;Also:&lt;br /&gt;&lt;br /&gt;* Display the biggest jump (in the sequences above, it's 4: 98 -&gt; 102)&lt;br /&gt;* Display the total count of numbers&lt;br /&gt;* Give these two values for max=1000&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Since my solution is in Scala, I tried to make it as functional as I could instead of doing a standard imperative exercise.&lt;br /&gt;&lt;br /&gt;It has been an worthwhile exploration of Scala for me.&lt;br /&gt;&lt;br /&gt;So here it is.&lt;br /&gt;&lt;br /&gt;First, the necessary functions to determine if a number has repeated digits or not:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def getDigits(number: int): Array[int] = number.toString.toArray.map(_.toInt - 48)&lt;br /&gt;&lt;br /&gt;def hasRepeatedDigits(number: int): boolean = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val digits = getDigits(number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val digitPresent = Array.make[int](10, 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digits.foreach(digit =&gt; digitPresent(digit) += 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitPresent.exists(_ &gt; 1)&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now, to generate the list itself. That is the part I feel the most imperative. I tried different ways, including a recursive function, but this seemed the simplest way in the end:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def getNonRepeatedDigitNumbers(max:Int): List[Int] = List.range(1,max+1).filter(!hasRepeatedDigits(_))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Next has been the most interesting part for me. I started with the idea that I would use a list of the gaps and simply get the maximum from it.&lt;br /&gt;Here is the idea:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def maximum(x: List[Int]): Int = (x.head /: x.tail)((a:Int, b:Int)=&gt;(if (a&gt;b) a else b))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;But how to get the gap list? I needed something similar to a fold operation, but I wanted to operate always with the current and previous element instead of accumulating a result to operate with the current element.&lt;br /&gt;&lt;br /&gt;Maybe I am just reinventing the wheel here, but here is my "pair" map function:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def pairMap(previous:Int, serie:List[int], f: (Int, Int) =&gt; Int): List[Int] = serie match {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case Nil =&gt; Nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case head :: tail =&gt; f(&lt;/code&gt;&lt;code class="prettyprint"&gt;previous, head)::pairMap(head, tail, f)&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;An here is how I get the gap list:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def getGapList(serie: List[int]) = serie match {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case Nil =&gt; Nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case head :: tail =&gt; pairMap(head, tail, (a:Int, b:Int)=&gt;(b - a))&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As an aside, I realized from Tony Morris exercises that I tended to include a superfluous match in my recursive list functions.&lt;br /&gt;For example, here is how I first wrote the preceding function:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;def getGapList(serie: List[int]) = serie match {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case Nil =&gt; Nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case head :: Nil =&gt; Nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case head :: tail =&gt; pairMap(head, tail, (a:Int, b:Int)=&gt;(b - a))&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;At last, here is how I used the functions to solve the code challenge:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;val serie = getNonRepeatedDigitNumbers(1000)&lt;br /&gt;val totalCount = serie.size&lt;br /&gt;&lt;br /&gt;println("Biggest jump: " + maximum(getGapList(serie)))&lt;br /&gt;println("Total count of numbers: " + totalCount)&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-4431487089924738775?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/4431487089924738775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=4431487089924738775' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4431487089924738775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/4431487089924738775'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/07/cdric-beusts.html' title='Cédric Beust&apos;s Coding Challenge'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-5685772730315670241</id><published>2008-06-17T13:38:00.004-04:00</published><updated>2008-06-17T13:51:25.276-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Scala Light... A Java successor?</title><content type='html'>Upon reading on a few forums in Artima, I detected a desire for both a fuller Java and a simpler Scala. A fuller Java to have things like type inference and more functional style constructs. A simpler Scala to be have an easier specification, both for the mind and for the IDE.&lt;br /&gt;&lt;br /&gt;What do you think would be more appropriate to help Java developers get a better language?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Continue to selectively better the Java Language&lt;/li&gt;&lt;li&gt;Define a subset of Scala, a Scala Light if you will. Or would a subset of Scala defeat the purpose of its synergy of features?&lt;/li&gt;&lt;li&gt;Another choice&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-5685772730315670241?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/5685772730315670241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=5685772730315670241' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/5685772730315670241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/5685772730315670241'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/06/scala-light-java-successor.html' title='Scala Light... A Java successor?'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-2696140607231474051</id><published>2008-06-10T21:31:00.006-04:00</published><updated>2009-01-25T08:36:43.979-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='fp'/><title type='text'>A simple Java FP list map</title><content type='html'>Following on the comments I received on my previous entry about doing a bit of Java functional programming style, I made a very simple class to map a list. I'm following the style of what I have seen in the apache collections utilities. See previous post.&lt;br /&gt;&lt;br /&gt;First note that I am doing it without generics (I'm stuck with jdk1.4.2 at work), so for some this would be old style Java programming.&lt;br /&gt;&lt;br /&gt;Here's the utility class.&lt;br /&gt;ListUtils.java&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;package fp;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;public class ListUtils {&lt;br /&gt;    static public List map(List elements, Applier applier) {&lt;br /&gt;        List result = new ArrayList();&lt;br /&gt;        for (Iterator it = elements.iterator(); it.hasNext();) {&lt;br /&gt;            Object element = it.next();&lt;br /&gt;            result.add(applier.apply(element));&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And the interface used by the utility class.&lt;br /&gt;Applier.java&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;package fp;&lt;br /&gt;&lt;br /&gt;public interface Applier {&lt;br /&gt;    public Object apply(Object element);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here's a client code example.&lt;br /&gt;&lt;br /&gt;WithPoints.java&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;package domino;&lt;br /&gt;&lt;br /&gt;public interface WithPoints {&lt;br /&gt;    public Integer getPoints();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Domino.java&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;package domino;&lt;br /&gt;&lt;br /&gt;public class Domino implements WithPoints {&lt;br /&gt;    private Integer points;&lt;br /&gt;    &lt;br /&gt;    public Domino(int points) {&lt;br /&gt;        this.points = new Integer(points);&lt;br /&gt;    }&lt;br /&gt;            &lt;br /&gt;    public Integer getPoints() {&lt;br /&gt;        return points;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And finally!&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;package domino;&lt;br /&gt;&lt;br /&gt;import fp.Applier;&lt;br /&gt;import fp.ListUtils;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        List dominoes = new ArrayList();&lt;br /&gt;        dominoes.add(new Domino(1));&lt;br /&gt;        dominoes.add(new Domino(2));&lt;br /&gt;        dominoes.add(new Domino(3));&lt;br /&gt;&lt;br /&gt;        List points = ListUtils.map(dominoes, new Applier() {&lt;br /&gt;            public Object apply(Object domino) {&lt;br /&gt;                return ((WithPoints) domino).getPoints();&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;&lt;br /&gt;        System.out.println(points); // [1, 2, 3]&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So this time around, I did get a new list instead of transforming a list but I still think the simple iterator style is clearer and it avoids using a "utility class" for doing something really simple.&lt;br /&gt;&lt;br /&gt;Iterator style&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;List points;&lt;br /&gt;for (Iterator iter = Dominoes.iterator(); iter.hasNext();) {&lt;br /&gt;    points.add((WithPoints) iter.next().getPoints());&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And of course, Scala still is neater for me 8)&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;val points = dominoes map (x =&gt; x.points)&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-2696140607231474051?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/2696140607231474051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=2696140607231474051' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2696140607231474051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2696140607231474051'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/06/simple-fp-list-map.html' title='A simple Java FP list map'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-7383709778071526224</id><published>2008-06-09T21:49:00.008-04:00</published><updated>2009-02-01T09:20:53.305-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='fp'/><title type='text'>The Scala Influence</title><content type='html'>A while ago, Frank Sommers asked the following:&lt;br /&gt;&lt;a href="http://www.artima.com/forums/flat.jsp?forum=106&amp;amp;thread=229307"&gt;How Has Functional Programming Influenced Your Coding Style?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If wish I could have replied something then, but I was just starting to learn Scala, and I couldn't.&lt;br /&gt;&lt;br /&gt;Now, I'm still just at the beginning of grokking FP, but I can write about how it almost influenced a bit of Java code I had to write the other day at work.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Post update: "I have to use jdk 1.4.2 at work. That's why I am not using generics and all."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I had a list of instances of a certain class, and I wanted to get a list made from the result of invoking a certain method on each instance.&lt;br /&gt;&lt;br /&gt;We'll pretend I had a Domino class, and I wanted to invoke the method getPoints() on each instances&lt;br /&gt;&lt;br /&gt;Here's how I would have done it in Scala:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;class Domino(p: int) {&lt;br /&gt;   val points=p&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val dominoes = List(new Domino(1), new Domino(2), new Domino(3))&lt;br /&gt;&lt;br /&gt;val points = dominoes map (_.points)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Let's say it's a bit cryptic in Scala and make it a bit more explicit:&lt;br /&gt;&lt;code class="prettyprint"&gt;val points = dominoes map (x =&gt; x.points)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I'll skip the Java class definition, but it implements the interface WithPoints, which declares the "Integer getPoints()" method .&lt;br /&gt;&lt;br /&gt;Now, just look at what I had to code in Java to get the point list:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;List points;&lt;br /&gt;for (Iterator iter = Dominoes.iterator(); iter.hasNext();) {&lt;br /&gt;   points.add((WithPoints) iter.next().getPoints());&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Simple really, but I couldn't get over how much neater (to me) it was in Scala.&lt;br /&gt;&lt;br /&gt;Now comes the functional programming influence part. It so happens that I had a transformation library at my disposal in my Java project: &lt;a href="http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/package-summary.html"&gt;org.apache.commons.collections&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's not what I really wanted, but I could use some kind of functional programming style with it. And here's the end result:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;List dominoes;&lt;br /&gt;CollectionUtils.transform(dominoes, new Transformer() {&lt;br /&gt;   public Object transform(Object domino) {&lt;br /&gt;       return ((WithPoints) domino).getPoints();&lt;br /&gt;   }&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So there, it's not so bad, except that:&lt;br /&gt;1) It transforms my list instead of returning a new list, which is what I wanted.&lt;br /&gt;2) The imperative version is, in my opinion, clearer.&lt;br /&gt;&lt;br /&gt;And so this is how functional programming has (almost, but not quite) influenced my coding style so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-7383709778071526224?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/7383709778071526224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=7383709778071526224' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7383709778071526224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/7383709778071526224'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/06/scala-influence.html' title='The Scala Influence'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8932258692847145228.post-2567247627073242768</id><published>2008-04-16T23:11:00.015-04:00</published><updated>2009-01-25T14:06:40.509-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='access modifier'/><title type='text'>Instance read-only access modifier</title><content type='html'>&lt;div style="text-align: justify;"&gt;Be it in C++, Java, or Scala, I have always been bothered by the fact that an instance of a class has access to the private members of another instance.&lt;br /&gt;&lt;br /&gt;Sure, it's mighty useful for copy constructors and other functionalities like adding, but I always felt there should also be a "private read-only" access modifier.&lt;br /&gt;&lt;br /&gt;Of course, there is no problem in the case of immutable objects. Here's a Scala example (using Scala version 2.6.1).&lt;br /&gt;&lt;/div&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;class Domino(p: int) {&lt;br /&gt;    private val points=p&lt;br /&gt;&lt;br /&gt;    def add(that: Domino) = new Domino(p + that.points)&lt;br /&gt;&lt;br /&gt;    override def toString() = "Domino: points=[" + points +"]"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;scala&gt; val d1 = new Domino(1)&lt;br /&gt;d1: Domino = Domino: points=[1]&lt;br /&gt;&lt;br /&gt;scala&gt; val d3 = new Domino(3)&lt;br /&gt;d3: Domino = Domino: points=[3]&lt;br /&gt;&lt;br /&gt;scala&gt; d1.add(d3)&lt;br /&gt;res2: Domino = Domino: points=[4]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But what if, for whatever reason, I am using mutable objects?&lt;br /&gt;&lt;br /&gt;In the following code, I have no quarrel with the function addToMe, but I am bothered by the function addToOther. I wish I could specify my special "private read-only" access modifier there, so this function would not compile.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Normal Scala code:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;class MutableDomino(p: int) {&lt;br /&gt;    private var points=p&lt;br /&gt;&lt;br /&gt;    def addToMe(that: MutableDomino) = { points = points + that.points }&lt;br /&gt;&lt;br /&gt;    def addToOther(that: MutableDomino) { that.points = that.points + points }&lt;br /&gt;&lt;br /&gt;    override def toString() = "MutableDomino: points=[" + points +"]"&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I would like to be able to write the class like the following (the exact name of the access modifier is not important)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Crazy Scala code:&lt;br /&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;class MutableDomino(p: int) {&lt;br /&gt;    private[this] var points=p&lt;br /&gt;&lt;br /&gt;    def addToMe(that: MutableDomino) = { points = points + that.points }&lt;br /&gt;&lt;br /&gt;    def addToOther(that: MutableDomino) { that.points = that.points + points }&lt;br /&gt;&lt;br /&gt;    override def toString() = "MutableDomino: points=[" + points +"]"&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;What do you think about an instance read-only access modifier?&lt;br /&gt;&lt;br /&gt;Is it useful, or is it over the edge?&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Post update!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Thanks to Eric's heads up below, I learned about the access modifier.&lt;br /&gt;&lt;br /&gt;I can actually go even further than prevent write-access to a private member of another instance: I can block read and write access to it altogether using the "this" qualifier.&lt;br /&gt;E.g. : private[this]&lt;br /&gt;&lt;br /&gt;Here is a new version of the MutableDomino class with it that will be, rightly so, rejected by the Scala interpreter:&lt;br /&gt;&lt;/div&gt;&lt;code class="prettyprint"&gt;&lt;br /&gt;class MutableDomino(p: int) {&lt;br /&gt;    private var points=p&lt;br /&gt;&lt;br /&gt;    def addToMe(that: MutableDomino) = { points = points + that.points }&lt;br /&gt;&lt;br /&gt;    def addToOther(that: MutableDomino) { that.points = that.points + points }&lt;br /&gt;&lt;br /&gt;    override def toString() = "MutableDomino: points=[" + points +"]"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;error: value points is not a member of MutableDomino&lt;br /&gt;     def addToMe(that: MutableDomino) = { points = points + that.points }&lt;br /&gt;                                                                 ^&lt;br /&gt;error: value points is not a member of MutableDomino&lt;br /&gt;     def addToOther(that: MutableDomino) { that.points = that.points + points }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8932258692847145228-2567247627073242768?l=thecarefulprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thecarefulprogrammer.blogspot.com/feeds/2567247627073242768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8932258692847145228&amp;postID=2567247627073242768' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2567247627073242768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8932258692847145228/posts/default/2567247627073242768'/><link rel='alternate' type='text/html' href='http://thecarefulprogrammer.blogspot.com/2008/04/instance-read-only-access-modifier.html' title='Instance read-only access modifier'/><author><name>The Careful Programmer</name><uri>http://www.blogger.com/profile/13075337864712215296</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
