Seven Languages In Seven Weeks By Bruce Tate - What An Adventure
About two months ago, I started reading Seven Languages in Seven Weeks by Bruce Tate. I went into the book with a significant understanding of only two programming Languages: ColdFusion and Javascript. Now, not only do I have a sense of how many programming languages there are out there (Tate's list of 7 was selected from over a hundred languages), I see that there are some radically different approaches to problem solving.
|
|
|
|
|
|
|
|||
|
|
|
This book was straight up challenging! Tate does a good job of laying down a lot of the foundational concepts of each language; but, he really puts you through your paces. Most of the time, he merely points you in the right direction and then leaves it up to you to do the online research and connect the dots. Sometimes, I found this exhilarating; other times, I found this both frustrating and exhausting.
One of my favorite moments in the book, however, has nothing to do with any of the languages specifically; rather, it was a moment of clarity about the role of a language within a broader solution. When I started reading the book, I definitely thought of languages as being interchangeable. As such, I was always asking myself the question:
Yeah, this language is cool, but how do I get it to do all the amazingly powerful things that ColdFusion can do?
When you view languages as hot-swappable, I think this question is natural - it boils down to trade-offs. But, what I finally realized, going through this book, is that languages are not swappable; nor, should they be. Languages are designed to handle specific types of problems. The hard part is then having the wisdom to know when to apply a particular language to a particular type of problem.
Coming from a ColdFusion background, I am a bit of a generalist. As such, I tend to view a solution as relying on one language. But after talking with people like Sean Corfield, I am definitely starting to see that the "best" solution may contain 2 or 3 different programming languages all working in parallel.
That's a brave new world for me. This book has really opened my eyes to some new ways of thinking and some powerful forms of data manipulation. As you can see from my photo above, I'm tired; but, the journey was totally worth it.
Let's Give Some Stuff Away!
In honor of my Seven Languages journey, the good people at The Pragmatic Programmers have given me a discount code to give away. If you use the code at the Pragmatic Bookshelf:
BenNadelBlog7languages
... you'll get a 30% discount on either the print or electronic version of the Seven Languages in Seven Weeks book; but act fast, this coupon expires in a couple of days on February 2!
Let's Give Some MORE Stuff Away!
I think this book is awesome. As such, I'd like to give away a few copies of it myself. But, I want to foster an atmosphere of language appreciation. So here's how you enter: below, I am supplying the pseudo code for a problem. If you want to enter to win one of the free books, you have to translate the following pseudo code into the language of your choice within the comments of this post.
- Create a collection of names.
- Create a function that accepts a collection of names and an adjective and returns a new collection.
- The new collection must contain values in the form of, "NAME is so ADJECTIVE."
- Invoke this function.
NOTE: When posting code with the <code> tag, you can use Tabs or Spaces. However, if you use spaces, you must use 4-spaces to represent at tab.
You have until next Friday to post your code sample in the comments. And, remember to tell us all what language it is you are using!
The Journey In Its Totality
If you are curious about my Seven Languages in Seven Weeks journey, here are the related blog posts:
- Seven Languages In Seven Weeks: A Pragmatic Guide To Learning Programming Languages By Bruce Tate
- Seven Languages In Seven Weeks: Ruby - Day 1
- Seven Languages In Seven Weeks: Ruby - Day 2
- Seven Languages In Seven Weeks: Ruby - Day 3
- Seven Languages In Seven Weeks: Io - Day 1
- Seven Languages In Seven Weeks: Io - Day 2
- Seven Languages In Seven Weeks: Io - Day 3
- Seven Languages In Seven Weeks: Prolog - Day 1
- Seven Languages In Seven Weeks: Prolog - Day 2
- Seven Languages In Seven Weeks: Prolog - Day 3
- Seven Languages In Seven Weeks: Scala - Day 1
- Seven Languages In Seven Weeks: Scala - Day 2
- Seven Languages In Seven Weeks: Scala - Day 3
- Seven Languages In Seven Weeks: Erlang - Day 1
- Seven Languages In Seven Weeks: Erlang - Day 2
- Seven Languages In Seven Weeks: Erlang - Day 3
- Seven Languages In Seven Weeks: Clojure - Day 1
- Seven Languages In Seven Weeks: Clojure - Day 2
- Seven Languages In Seven Weeks: Clojure - Day 3
- Seven Languages In Seven Weeks: Haskell - Day 1
- Seven Languages In Seven Weeks: Haskell - Day 2
- Seven Languages In Seven Weeks: Haskell - Day 3
Have a great weekend!
Reader Comments
JavaScript:
@Wilkins,
Awesome stuff! Nice use of immediately-executed functions, especially in the context of return values.
To everyone:
Just a note to others - You don't have to make the Name/Adjective uppercase. Sorry about that - I put them in uppercase in my post to demonstrate substitution / interpolation.
Ah. I through in toUpperCase just to be precise and increase my odds. x_x
Python:
ColdFusion (CFML):
CSharp
Who doesn't like Lisp?
I'm a sucker for PowerShell, the object based piping makes operating on collections a cinch:
Bah, I can't even copy/paste today. tgif
I don't know about you guys, but I think it awesome how different each of these languages makes this approaches. So cool!
PHP:
I thought I'd try a language I'd never heard of to see how difficult it would be. I may actually pick this up now based on how easy it was. (I'm just rehasing my Lisp prog here)
The language is REBOL
Objective-C/Cocoa:
Nobody here handled an infinite list of names... Fortunately, there is Haskell.
@Hidde-Jan,
Ha ha, hurray for lazy sequences :)
@Ben
Yeah :) Like you, I also started learning Haskell this week and I really like the idea of defining what something is rather than saying how something should be computed. It feels really mathematical, which, for me, is a big plus.
From all the languages displayed here, I'm partial to Python and Haskell. They are both very concise and pleasant. But I have to admit that I'm a bit biased..
@Hidde-Jan,
ColdFusion is my love; but, even I can see how concise some of these other languages are. Like I said, one of the things I really came away with after reading this book was how powerful list manipulation is.
So many ways to write this;
Here's mine in Ruby:
@Adam,
Copy/Paste appears to have chopped off a trailed ) on my last line
Visual Basic .NET, with and without LINQ. (The C# example that already exists is similar enough it felt like cheating, so I implemented the version that doesn't use LINQ.) Both are idiomatic, though the non-LINQ implementation would be from before 2008 (or the product of a developer with high resistance to new features.)
<code>
Module Module1
Sub Main()
Dim names() As String = {"Bob", "Alice"}
Dim adjective As String = "stinky"
Dim linqSentences() As String = CreateSentencesWithLinq(names, adjective)
For Each sentence As String In linqSentences
Console.WriteLine(sentence)
Next
Dim nonLinqSentences() As String = CreateSentencesWithoutLinq(names, adjective)
For Each sentence As String In nonLinqSentences
Console.WriteLine(sentence)
Next
End Sub
Function CreateSentencesWithLinq(ByVal names As IEnumerable(Of String), ByVal adjective As String) As String()
Return names.Select(Function(name As String) String.Format("{0} is so {1}", name, adjective)).ToArray()
End Function
Function CreateSentencesWithoutLinq(ByVal names As IEnumerable(Of String), ByVal adjective As String) As String()
Dim sentences As New List(Of String)()
For Each name As String In names
sentences.Add(String.Format("{0} is so {1}", name, adjective))
Next
Return sentences.ToArray()
End Function
End Module
[/code]
@Ben
Before I started programming in Pyhon I did a lot of PHP and I had no idea about the power of this stuff.
Python's list comprehensions just make me smile :D
What makes ColdFusion special for you? I have to admit that, to me, it looks a bit like programming in what looks like a markup language. No offense.
@Owen,
A little pl/sql into the mix (one of the many, many ways to do this, I'm sure...especially depending on the collection type).
Tested in Oracle 10g by the way.
I fail so hard for not only mixing up the HTML code tag with the one I'm used to using for forums, I also hit Enter too soon and submitted the intended explanation too early. I think I have to go run some laps or something as punishment. :(
No Ruby entries, yet?
Whoops! Adam beat me to it by 8 minutes. :)
@Hidde-Jan,
List comprehensions are just awesomeness incarnate :) When I learned about those in this book, I was like, Whoa! Badass.
As far as ColdFusion, I just love how much stuff you can do. Clearly, all of these languages are very powerful and so is ColdFusion. What it lacks in syntax it makes up for with the enormity of the native library.
@Owen,
No worries my man - we can still see what's going on. I've heard of LINQ before, but never actually need any of the code that uses it.
@Marty, @Adam,
Ruby is pretty cool. When I started looking at that language, I was really thrown off by some of the syntax; but, by the end of the book, I was so warn down by minimal syntax that I might actually be coming around to loving it :)
@Ross,
Very interesting - I've never done anything like that at the SQL level. Is that an enterprise kind of thing? Or is that a wide supported concept (if you have any idea).
@dotnetCarpenter,
I like the way you mix the two lists together.
@Rich,
I spent a few days trying to learn how to program on the iPhone with Object-C and it just rubbed me the wrong way. What really irked me was the way you had to do so much manually allocation and de-allocation. Seemed like an archaic concept.
@Joshua,
I'm not sure I've even heard of REBOL. It looks like another one of those ultra-concise languages.
@Mike,
I've heard a lot of people really praise Python. The one thing I was always iffy about was the requirement of white-space. I mean, don't get me wrong, I LOVE white-space; but, when it becomes a requirement, I was afraid that it would mess with my approach.
@Andrew,
This is an interesting syntax:
$values[] = $value;
Is that like a self-push operator?
@Seth,
ColdFusion .. woot!
@Guganeshan.T,
That's interesting - I know almost nothing about C#; I didn't realize it supported a sort-of inline function declaration for working with collections.
@Jared,
What language is that?
@Ben, it's Groovy
@Ben
The whitespace in Python trips a lot of people up, and rubs others in a really bad way. However, one thing it's turned me to do is really evaluate my coding style and realize that if I end up with a ton of nested looping / control structures, there's probably a more elegant solution. In Python, because of the whitespace being important, your code ends up looking really ugly with a lot of nested loops/if-elses, so it kind of encourages you to do things in a more modular and articulate way.
Just my two cents, and I'm totally not saying other languages aren't elegant. For me personally, it's a bit easier to do in Python.
To be elegant, that is.
Just thought perl was missing. Although I am not sure the code qualifies?
@Mike,
That's actually a really good point. A while back, Brian Kotek presented the idea of Object Oriented Calisthenics:
http://www.briankotek.com/blog/index.cfm/2009/2/11/Taking-the-Object-Calisthenics-Challenge
One of the challenges was to not allow any function to nest more than twice. The idea being that, as you said, if you nest too much, there's probably a better way of doing it.
@Jared,
It's definitely groovy... but language is it (ha ha, sorry couldn't resist).
@Morten,
Ha ha, that might the record for the shortest entry.
@Ben
From what I can gather it was originally intended for network communications and distributed computing. I figured in the spirit of things I'd try a language I had never tried before. I even found an online compiler. Syntax is pretty straight forward and it does some decent list evaluation. Although for list evals you can't go wrong with Lisp. But I'm a ColdFusion die hard all the way.
@Joshua,
This time around, I was better with Lisp (Clojure) than I have been in the past; but as far as the book goes, I think I remember enjoying Io more than Lisp... though, in reality, my brain is just mush at this point.
@Ben
I'd imagine. That's why I like CF. Simple, straightforward, and lots of functionality.
Thank you for the discount code Ben! I just picked up my copy. I've enjoyed following your progress with it and I'm ready to dive in now.
Thanks again to you and folks at The Pragmatic Programmers!
Thought I should give it a more serious try and then I remembered playing around with moscow ml some ~10 years ago...
This example does by no means take advantage of the tasty bits of ML, but even if my life depended on it I wouldn't be able to remember much of it.
I think I have to dive back into this old one.
@Ben, of all the languages in that book (and in your brain), do you have a particular favorite? It's a big question, I know, all languages have their place.
That being said, what syntax to you find particularly beautiful and why?
@Eric,
Outstanding! I hope you enjoy it!
@Morten,
I'm certain I've never heard of MoscowML, let alone SML. It's bananas how many languages there are out there. The syntax for this one looks like Haskell a bit.
@Wilkins,
Let me think about this one for a bit - my brain needs a night of Netflix :)
@Ben, No doubt! =)
Ruby code, more defensive version:
This is in the J programming language. It includes definitions, invocation, and output.
For more about J, see http://jsoftware.com.
@Ben
$values[] = $value; creates an array called $values and adds each new value to the end of the array as the function loops through.
Thanks for doing this little contest too. I have enjoyed looking through everyone's code to see what they did with their languages. If I don't win one of the books I will definitely be buying this one!
@Ben, yeah, as a longtime CF/Java guy, the allocate/retain/release stuff in Objective-C drives me nuts. But it's worth it to see one's apps in the app store. :)
Check out the Head First iPhone Development book if you feel like giving it another shot. It's a fun read and cuts through all the complexity.
Like you Ben, I'm a CF and JS guy. Just picked up the 7 languages book today, but I have coworkers who could learn as well if I win a copy. :-) I use bash all the time to cat JS and CSS files prior to minification. Hadn't seen a regular ole bash script posted yet, so here's mine.
Bash:
<code>
#!/bin/bash
beatles=(John Paul George Ringo)
function rock(){
rockers=()
for i in ${beatles[@]}; do
rockers+=(${i}" is so "${2})
done
echo ${rockers[*]}
}
rock beatles Rockin!
<code>
Thx again for the contest and book discount!
Sorry about the bad markup, I'll try again!
Like you Ben, I'm a CF and JS guy. Just picked up the 7 languages book today, but I have coworkers who could learn as well if I win a copy. :-) I use bash all the time to cat JS and CSS files prior to minification. Hadn't seen a regular ole bash script posted yet, so here's mine.
Bash:
Thx again for the contest and book discount!
@Ben
ML is a fun(ctional) language to play around with and there are quite a few implementations of it.
I haven't played around with Haskell at all, but to my understanding Haskell is a pure functional language where as ML has some blurry edges when it come to that.
ML also shares similarities with javascript :)
What I like about SML is that is has no loop sytax like for, each and while. All recursion is done through tail recursion which forces me to think of programmatic solutions differently than I would in other languages.
That said I never code in ML, its too frustrating and reminds me of hours of tedious homework :)
Another Groovy submission:
Run it at (results are in the "Output" tab):
http://groovyconsole.appspot.com/script/404001
Submitting an example of the other language(s) I'm learning:
http://jsfiddle.net/jriggins/a8SgD/5/
Here's a java submission. The language is very concerned with types and requires a bit of set up to execute a program with a function.
I am disappointed that none of the Ruby solutions posted so far used the splat:
Here's a bit of Gosu...
...that produces as output...
AWK
yeah ok there is no function or collection unless I guess you allow a text file as a collection.
Wow, I am really loving these examples! What's cool is that not only are the languages different; but, so many of the approaches bring a slightly different twist to the solution. Very very cool stuff!
Since the CF Version has already been posted, here is the CFScript version:
Euphoria:
@Nelle,
CF Woot! Very clever use of delimiter-changing!
Oops, that should be
@Ben
Not sure if you are referring to the use of a cursors, the 'connect by level', or the use of a regular expression? Either way, all are standard PL/SQL in Oracle. But, given how much licenses cost, I'd say it is all enterprise :)
I'm by no means an accomplished programmer in this language, but I had to program in PLT Scheme (now Racket) in College. Scheme is a dialect of LISP.
Racket:
Hey guys, sorry I haven't picked any winners yet - things have been a bit crazy here. Will try to do this in the morning (I have a user-group meeting tonight).
Thanks again for all your submissions - this has been such an awesome turnout!
Ok guys, I finally picked a few winners using some super exciting ColdFusion code:
www.bennadel.com/blog/2122-Selecting-The-Seven-Languages-In-Seven-Weeks-Winners.htm
Congratulations to Jared Cacurak and Matt Gutting! Please shoot me an email at ben/at/bennadel.com so I know where to send the books.
Thanks again to everyone for participating - this was loads of fun.
Bit late in the day but I thought it be good to see a Perl & Io solutions to the required spec.
Perl:
And Io:
Or howbout in Fancy? :)
Even though it's already over, here's one for Progress 4GL:
There's been a couple of other .NET examples already, but just wanted to show extention methods and option query syntax for Linq. The query syntax is too verbose for a simple map (select) so I threw in the filter (where) clause. Also, the Dump method is a feature of the LINQPad scratch pad app.
<code>
void Main()
{
var names = new List<string> {"Bob", "Don", "Steve", "Bill"};
names.Adj("tall").Dump();
names.AdjQuery("tall").Dump();
}
public static class Extensions
{
public static IEnumerable<string> Adj(this IEnumerable<string> names, string adjective)
{
return names.Select(name => string.Format("{0} is so {1}", name, adjective));
}
public static IEnumerable<string> AdjQuery(this IEnumerable<string> names, string adjective)
{
return from name in names
where name.Length > 3
select string.Format("{0} is so {1}", name, adjective);
}
}
</code
Just to prove that there's always more than one way to do it in perl, here's an implementation that creates a list of anonymous subroutines in a function called gen and then returns and dispatches them.
I've enjoyed following your adventures in code, Ben and I'm now working my way through my own Seven Languages adventure at http://charlieharvey.org.uk/page/seven_languages_in_seven_weeks. Cheers and congrats on finishing!