Seven Languages In Seven Weeks By Bruce Tate - What An Adventure

Posted January 28, 2011 at 10:25 AM by Ben Nadel

Tags: Ruby, Io, Prolog, Scala, Erlang, Lisp, Clojure, Haskell

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.

 
 
 
 
 
 
Ben Nadel After Reading Seven Languages In Seven Weeks! 
 
 
 

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.

  1. Create a collection of names.
  2. Create a function that accepts a collection of names and an adjective and returns a new collection.
  3. The new collection must contain values in the form of, "NAME is so ADJECTIVE."
  4. 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:

Have a great weekend!




Reader Comments

Jan 28, 2011 at 11:08 AM // reply »
10 Comments

JavaScript:

  • (function () {
  • var names = "john jacob jingleheimer schmidt".split(' '),
  • phrase = [],
  • nameCollector = function (n, adj) {
  • for (var i = 0, l = names.length; i < l; i++) {
  • phrase.push(names[i].toUpperCase() + " is so " + adj);
  • }
  • return phrase;
  • } (names, "amazing".toUpperCase());
  • console.log(nameCollector);
  • })();


Jan 28, 2011 at 11:13 AM // reply »
11,314 Comments

@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.


Jan 28, 2011 at 11:16 AM // reply »
10 Comments

Ah. I through in toUpperCase just to be precise and increase my odds. x_x


Jan 28, 2011 at 11:27 AM // reply »
6 Comments

Python:

  • names = ["alice", "bob", "charlie"]
  •  
  • def nameAdj(nameList, adj):
  • return ["%s is so %s" % (name, adj) for name in nameList]
  •  
  • newNames = nameAdj(names, "weird")
  • print newNames


Jan 28, 2011 at 11:40 AM // reply »
2 Comments

ColdFusion (CFML):

  • <cfset names = listToArray("Napoleon,Kip,Tina,Pedro,Deb") />
  •  
  • <cffunction name="makePhrase" access="public" returntype="array" output="true" hint="">
  • <cfargument name="names" type="array" required="true" hint="list" />
  • <cfargument name="adj" type="string" required="true" />
  • <cfset local.phrases = ArrayNew(1) />
  •  
  • <cfloop from="1" to="#ArrayLen(arguments.names)#" index="nameIdx">
  • <cfset arrayAppend(local.phrases, "#UCase(arguments.names[nameIdx])# is so #arguments.adj#") />
  • </cfloop>
  •  
  • <cfreturn local.phrases />
  • </cffunction>
  •  
  • <cfset phrases = makePhrase(names,"FUNNY") />
  • <cfdump var="#phrases#" />


Jan 28, 2011 at 12:20 PM // reply »
4 Comments

CSharp

  • /// <summary>
  • /// A CSharp console program's main method.
  • /// </summary>
  • void Main()
  • {
  • var originalCollection = new List<string>() { "Will", "Sandler", "Martin" };
  • var modifiedCollection = GetNamesWithAdjectives(originalCollection, "funny");
  •  
  • foreach (string oneStatment in modifiedCollection)
  • {
  • Console.WriteLine(oneStatment);
  • }
  • }
  •  
  • /// <summary>
  • /// Function that gets a modified collection
  • /// </summary>
  • private static IEnumerable<string> GetNamesWithAdjectives(IEnumerable<string> collection, string adjective)
  • {
  • return collection.Select(name => name + " is so " + adjective);
  • }


Jan 28, 2011 at 12:51 PM // reply »
4 Comments

  • (defparameter *names* (list "Josh" "Ben" "Ray"))
  •  
  • (defun addAdjective (namesList adjective)
  • (loop for i in namesList
  • append (list (concatenate 'string i " is so " adjective)) into newList
  • finally
  • (return (values newList))))
  •  
  • (addAdjective *names* "smart")

Who doesn't like Lisp?


Jan 28, 2011 at 1:18 PM // reply »
12 Comments

I'm a sucker for PowerShell, the object based piping makes operating on collections a cinch:

  • Function NameIsSoAdjective($names, $adjective)
  • {
  • $names | foreach { "$_ is so $adjective" }
  • }
  •  
  • NameIsSoAdjective "Me","Myself","I" "awesome


Jan 28, 2011 at 1:20 PM // reply »
12 Comments

Bah, I can't even copy/paste today. tgif


Jan 28, 2011 at 1:39 PM // reply »
11,314 Comments

I don't know about you guys, but I think it awesome how different each of these languages makes this approaches. So cool!


Jan 28, 2011 at 1:44 PM // reply »
3 Comments

PHP:

  •  
  • <?php
  • $names = array('Claire','Juliet','Kate','Penny','Charlotte','Sun','Shannon');
  •  
  • function nameAdjective($n, $v) {
  • foreach($n as $value){
  • $value .= " is so $v";
  • $values[] = $value;
  • }
  • return $values;
  • }
  •  
  • $newNames = nameAdjective($names, 'hot');
  •  
  • foreach($newNames as $new){
  • echo $new;
  • echo "<br />";
  • }
  •  
  • ?>


Jan 28, 2011 at 2:15 PM // reply »
4 Comments

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

  • names: ["Josh" "Ben" "Ray"]
  • newList: []
  •  
  • addAdjective: func [namesList adjective] [
  • foreach item namesList [append newList rejoin[item " is so " adjective "."]]
  • ]
  •  
  • namesFinal: addAdjective names "smart"
  •  
  • print namesFinal


Jan 28, 2011 at 2:23 PM // reply »
6 Comments

Objective-C/Cocoa:

  • - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  • NSArray *names = [NSArray arrayWithObjects:@"Homer",@"Marge",@"Bart",@"Lisa",@"Maggie",nil];
  • NSMutableArray *descriptions = [self describeNames:names asAdjective:@"freakin' awesome"];
  • NSLog(@"%@",descriptions);
  • }
  •  
  • - (NSMutableArray *)describeNames:(NSArray *)names asAdjective:(NSString *)adjective {
  • NSMutableArray *descriptions = [NSMutableArray array];
  • for(int i=0; i<[names count]; i++) {
  • [descriptions addObject:[NSString stringWithFormat:@"%@ is %@!",[names objectAtIndex:i],adjective]];
  • }
  • return descriptions;
  • }


Jan 28, 2011 at 2:25 PM // reply »
3 Comments

  • soAdj :: String -> [String] -> [String]
  • soAdj adj names = [n ++ sentence | n <- names]
  • where sentence = " is so " ++ adj ++ "."
  •  
  • > let names = ["Ben", "Wilkins", "Mike", "Seth"]
  • > soAdj "serious" names
  • ["Ben is so serious.","Wilkins is so serious.","Mike is so serious.","Seth is so serious."]
  • > take 100000 . soAdj "infinite" . repeat $ "This list"
  • ["This list is so infinite.","This list is so infinite.", ...snip...

Nobody here handled an infinite list of names... Fortunately, there is Haskell.


Jan 28, 2011 at 3:06 PM // reply »
11,314 Comments

@Hidde-Jan,

Ha ha, hurray for lazy sequences :)


Jan 28, 2011 at 3:13 PM // reply »
3 Comments

@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..


Jan 28, 2011 at 3:16 PM // reply »
11,314 Comments

@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.


Jan 28, 2011 at 3:20 PM // reply »
2 Comments

So many ways to write this;

  • /*
  • 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.
  • */
  • var challenge = function(){
  • var _isSo = ' is so ',
  • /* predefine collections */
  • _collections = { sentences: [], names: [
  • { name: 'Jon' },
  • { name: 'Franz' },
  • { name: 'Pernille' },
  • { name: 'Sonja' },
  • { name: 'Laura' },
  • { name: 'Lois' }
  • ], adjectives: [
  • { adj: 'super' },
  • { adj: 'hot' },
  • { adj: 'new' },
  • { adj: 'available' },
  • { adj: 'latest' },
  • { adj: 'great' }
  • ]};
  • /**
  • * Returns a random number
  • */
  • function getRandom(max){
  • return Math.floor(Math.random() * max || 1);
  • }
  • /**
  • * Mix the names and adjectives collections
  • */
  • function mix(names, adjectives){
  • for (var name in names){
  • _collections.sentences.push(
  • names[name].name + _isSo + _collections.adjectives[
  • getRandom(_collections.adjectives.length)
  • ].adj
  • );
  • }
  • }
  •  
  • return {
  • getSentences: function(){
  • return mix(_collections.names, _collections.adjectives), _collections.sentences.toString();
  • }
  • }
  • }();
  •  
  • challenge.getSentences();


Jan 28, 2011 at 3:32 PM // reply »
2 Comments

Here's mine in Ruby:

  • def map_adjective(names,adj)
  • names.map{|name| "#{name} is so #{adj}"}
  • end
  •  
  • names = %w(adam jon andy dave fred wilson)
  • puts map_adjective(names,"funny"


Jan 28, 2011 at 3:33 PM // reply »
2 Comments

@Adam,

Copy/Paste appears to have chopped off a trailed ) on my last line


Jan 28, 2011 at 3:38 PM // reply »
3 Comments

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]


Jan 28, 2011 at 3:38 PM // reply »
3 Comments

@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

  • >>> [(x, chr(x + 97)) for x in range(6) if not x % 2]
  • [(0, 'a'), (2, 'c'), (4, 'e')]

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.


Jan 28, 2011 at 3:38 PM // reply »
3 Comments

@Owen,


Jan 28, 2011 at 3:40 PM // reply »
2 Comments

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.

  • declare
  •  
  • CURSOR nameIsSo (nameList VARCHAR2, verb VARCHAR2) IS
  • SELECT REGEXP_SUBSTR( nameList, '[^,]+', 1, rownum) || ' is so ' || verb || '.' sentence
  • FROM dual
  • CONNECT BY LEVEL <= length (regexp_replace ( nameList, '[^,]+')) + 1;
  •  
  • begin
  •  
  • FOR rec IN nameIsSo( 'Ashley,Bre,Steph,Emily', 'radical')
  • LOOP
  •  
  • dbms_output.put_line(rec.sentence);
  •  
  • END LOOP;
  • end;


Jan 28, 2011 at 3:40 PM // reply »
3 Comments

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. :(


Jan 28, 2011 at 3:40 PM // reply »
2 Comments

No Ruby entries, yet?

  • names = ["John", "Paul", "George", "Ringo"]
  •  
  • def names_are_so_adjective(names, adjective)
  • names.map{ |name| "#{name} is so #{adjective}" }
  • end
  •  
  • puts names_are_so_adjective(names, "rad")


Jan 28, 2011 at 3:42 PM // reply »
2 Comments

Whoops! Adam beat me to it by 8 minutes. :)


Jan 28, 2011 at 3:50 PM // reply »
2 Comments

  • def appendIsSo (adjective, names) {
  • names.to*.plus " is so ${adjective}."
  • }
  •  
  • appendIsSo 'awesome', [to: ['Aby', 'Brooke', 'Claire']]


Jan 28, 2011 at 3:59 PM // reply »
11,314 Comments

@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.


Jan 28, 2011 at 4:00 PM // reply »
11,314 Comments

@Jared,

What language is that?


Jan 28, 2011 at 4:03 PM // reply »
2 Comments

@Ben, it's Groovy


Jan 28, 2011 at 4:05 PM // reply »
6 Comments

@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.


Jan 28, 2011 at 4:05 PM // reply »
6 Comments

To be elegant, that is.


Jan 28, 2011 at 4:09 PM // reply »
13 Comments

Just thought perl was missing. Although I am not sure the code qualifies?

  • @d = map sprintf("%s is so %s",$_,"perlish"), ("Morten","Ben","The lot");


Jan 28, 2011 at 4:21 PM // reply »
11,314 Comments

@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.


Jan 28, 2011 at 4:24 PM // reply »
4 Comments

@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.


Jan 28, 2011 at 4:32 PM // reply »
11,314 Comments

@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.


Jan 28, 2011 at 4:35 PM // reply »
4 Comments

@Ben

I'd imagine. That's why I like CF. Simple, straightforward, and lots of functionality.


Jan 28, 2011 at 4:41 PM // reply »
3 Comments

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!


Jan 28, 2011 at 6:16 PM // reply »
13 Comments

Thought I should give it a more serious try and then I remembered playing around with moscow ml some ~10 years ago...

  • val list = ["Morten","Ben","The lot"] : string list;
  •  
  • fun map (f, adj, nil) = nil | map (f, adj, h::t) = (f(h, adj)) :: map (f, adj, t);
  •  
  • fun func (h,adj) = h ^ " is so " ^ adj;
  •  
  • map(func,"MLed",list);

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
http://www.amazon.com/Introduction-Programming-International-Computer-Science/dp/0201398206/ref=sr_1_7?ie=UTF8&qid=1296256526&sr=8-7


Jan 28, 2011 at 7:47 PM // reply »
10 Comments

@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?


Jan 28, 2011 at 8:00 PM // reply »
11,314 Comments

@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 :)


Jan 28, 2011 at 8:06 PM // reply »
10 Comments

@Ben, No doubt! =)


Jan 28, 2011 at 10:13 PM // reply »
1 Comments

Ruby code, more defensive version:

  • #!/usr/bin/env ruby
  •  
  • # Author: Greg Mefford
  •  
  • # * Create a collection of names.
  • names = %w{Ruby Ursula Bob Yuri}
  •  
  • # * 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."
  • def xs_are_so_y(names=["Everyone"], adjective="Lame")
  • unless names.is_a? Enumerable and names.map{|n| n.respond_to? :upcase}.uniq == [true]
  • fail "You have to specify a collection of name Strings"
  • end
  • unless adjective.respond_to? :upcase
  • fail "You have to specify an adjective String"
  • end
  • names.map{ |name| "#{name.upcase} is so #{adjective.upcase}"}
  • end
  •  
  • # * Invoke this function.
  • puts xs_are_so_y
  • puts xs_are_so_y(names, "Awesome")


Jan 28, 2011 at 11:34 PM // reply »
1 Comments

This is in the J programming language. It includes definitions, invocation, and output.

  • names=: ;:'Miles Ella Jaco Wynton'
  • say_is_so=: [:,@> ([,' is so ',])&.>
  • names say_is_so <'cool.'
  • Miles is so cool.
  • Ella is so cool.
  • Jaco is so cool.
  • Wynton is so cool.

For more about J, see http://jsoftware.com


Jan 29, 2011 at 12:06 AM // reply »
3 Comments

@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!


Jan 29, 2011 at 12:34 AM // reply »
6 Comments

@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.


Jan 29, 2011 at 3:02 AM // reply »
3 Comments

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!


Jan 29, 2011 at 3:05 AM // reply »
3 Comments

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:

  • #!/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!

Thx again for the contest and book discount!


Jan 29, 2011 at 3:10 AM // reply »
13 Comments

@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 :)

  • (fn 0=>1 | n:int => n*(n-1))(10);

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 :)


Jan 29, 2011 at 3:16 AM // reply »
2 Comments

Another Groovy submission:

  • def printNamesAndAdjective = { names, adjective ->
  • names.each { println "$it is so $adjective" }
  • }
  •  
  • printNamesAndAdjective(['Groovy', 'Grails', 'GSP', 'GORM'], "amazing")

Run it at (results are in the "Output" tab):
http://groovyconsole.appspot.com/script/404001


Jan 29, 2011 at 3:18 AM // reply »
2 Comments

Submitting an example of the other language(s) I'm learning:

http://jsfiddle.net/jriggins/a8SgD/5/


Jan 29, 2011 at 12:20 PM // reply »
1 Comments

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.

  • import java.util.Iterator;
  • import java.util.ArrayList;
  •  
  • public class Describer {
  •  
  • public static void main(String [] args) {
  • ArrayList<String> list = new ArrayList<String>();
  • list.add("Atticus Finch");
  • list.add("Holden Caulfield");
  • list.add("John Proctor");
  • String adjective = "fictitious";
  • Iterable<String> newList = describeIsSo(list, adjective);
  •  
  • for (String s: newList) {
  • System.out.println(s);
  • }
  • }
  •  
  • public static Iterable<String> describeIsSo(Iterable<String> collection, String adjective) {
  • ArrayList<String> newCollection = new ArrayList<String>();
  •  
  • for(String s : collection) {
  • newCollection.add(String.format("%s is so %s", s, adjective));
  • }
  •  
  • return newCollection;
  • }
  •  
  • }


Jan 29, 2011 at 12:21 PM // reply »
1 Comments

I am disappointed that none of the Ruby solutions posted so far used the splat:

  • def describe(adjective, *names)
  • names.collect{|name| "#{name} is so #{adjective}"}
  • end
  •  
  • describe('awesome', 'Harry', 'Bob', 'John')


Jan 29, 2011 at 9:29 PM // reply »
1 Comments

Here's a bit of Gosu...

  • var testNames = {"Bob", "Carol", "Ted", "Alice"}
  •  
  • function describe(names : List<String>, adjective : String) : List<String> {
  • return names.map( \name -> (name + " is so " + adjective))
  • }
  •  
  • describe(testNames, "awesome").each(\s -> print(s))

...that produces as output...

  • Bob is so awesome
  • Carol is so awesome
  • Ted is so awesome
  • Alice is so awesome


Jan 30, 2011 at 2:10 PM // reply »
4 Comments

AWK

  • awk -v adjective="simples" '{$2=adjective; print $1" is "$2}' ./nameList.txt >> nameWithAdjective.txt

yeah ok there is no function or collection unless I guess you allow a text file as a collection.


Jan 30, 2011 at 3:51 PM // reply »
11,314 Comments

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!


Jan 31, 2011 at 7:38 AM // reply »
27 Comments

Since the CF Version has already been posted, here is the CFScript version:

  • <cfscript>
  • names = "Marky,Ricky,Danny,Terry,Mikey,Davey,Timmy,Tommy,Joey,Robby,Johnny,Brian";
  • function add_adjective ( names, adjective ) {
  • return listChangeDelims( names, " is so " & adjective & "," ) & iif(listLen(names), DE(" is so " & adjective), DE(""));
  • }
  • writeOutput( add_adjective( names, "funny" ) );
  • </cfscript>


Jan 31, 2011 at 8:46 AM // reply »
17 Comments

Euphoria:

  • sequence names
  •  
  • names = {"Matthew","Mark","Luke","John"}
  •  
  • function Insert_IsSo(name, adj)
  • return name & "is so" & adj
  • end function
  •  
  • for i = 1 to length(names)
  • printf(SCREEN,%s,Insert_IsSo(names[i],"funny"))
  •  
  • end for


Jan 31, 2011 at 8:47 AM // reply »
11,314 Comments

@Nelle,

CF Woot! Very clever use of delimiter-changing!


Jan 31, 2011 at 8:48 AM // reply »
17 Comments

Oops, that should be

  • for i = 1 to length(names) <b>do</b>


Jan 31, 2011 at 9:21 PM // reply »
2 Comments

@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 :)


Feb 4, 2011 at 9:41 AM // reply »
1 Comments

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:

  • #lang racket
  •  
  • (define names (list "Bob" "Lisa" "Bill" "Cindy"))
  •  
  • (define (nameAdjective adj namelist) (map (lambda (i) (string-append (string-append i " is so ") adj)) namelist))
  •  
  • (nameAdjective "stupid" names)


Feb 8, 2011 at 11:07 AM // reply »
11,314 Comments

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!


Feb 10, 2011 at 10:22 AM // reply »
11,314 Comments

Ok guys, I finally picked a few winners using some super exciting ColdFusion code:

http://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.


Mar 3, 2011 at 6:08 AM // reply »
1 Comments

Bit late in the day but I thought it be good to see a Perl & Io solutions to the required spec.

Perl:

  • my @names = qw/tom dick harry/;
  •  
  • sub add_adj {
  • my $adj = shift;
  • map "$_ is so $adj", @_;
  • }
  •  
  • my @new_names = add_adj( perlish => @names );

And Io:

  • names := list("Tom", "Dick", "Harry")
  •  
  • nameAdj := method (nameList, adj,
  • nameList map (name, "#{name} is so #{adj}" interpolate)
  • )
  •  
  • newNames := nameAdj(names, "Io-ish")

/I3az/


Apr 14, 2011 at 9:30 AM // reply »
1 Comments

Or howbout in Fancy? :)

  • def names: names with_adjective: adj {
  • names map: |n| {
  • "#{n} is so #{adj}"
  • }
  • }
  •  
  • names: ["John", "Mike", "Alex", "Chris"] with_adjective: "cool" . println


Jul 5, 2011 at 3:34 PM // reply »
1 Comments

Even though it's already over, here's one for Progress 4GL:

  • DEF VAR names AS CHAR NO-UNDO.
  • DEF VAR adjective AS CHAR NO-UNDO.
  •  
  • DEF TEMP-TABLE ttFullSentences NO-UNDO
  • FIELD sentence AS CHAR.
  •  
  • ASSIGN
  • names = "Tiger Woods, Phil Mickelson, Rory McIlroy"
  • adjective = "much better at golfing than me".
  •  
  • RUN SetFullSentences(INPUT names,
  • INPUT adjective,
  • INPUT-OUTPUT TABLE ttFullSentences).
  •  
  • FOR EACH ttFullSentences:
  • DISPLAY
  • ttFullSentences.sentence FORMAT "X(60)" LABEL "Sentences".
  • END.
  •  
  • PROCEDURE SetFullSentences:
  •  
  • DEF INPUT PARAM namesList AS CHAR NO-UNDO.
  • DEF INPUT PARAM adjective AS CHAR NO-UNDO.
  • DEF INPUT-OUTPUT PARAM TABLE FOR ttFullSentences.
  •  
  • DEF VAR sentenceFormat AS CHAR NO-UNDO INIT "&1 is so &2.".
  • DEF VAR idx AS INT NO-UNDO.
  •  
  • EMPTY TEMP-TABLE ttFullSentences.
  •  
  • DO idx = 1 TO NUM-ENTRIES(namesList):
  • CREATE ttFullSentences.
  • ASSIGN
  • sentence = SUBSTITUTE(sentenceFormat,
  • ENTRY(idx, namesList),
  • adjective).
  • END.
  •  
  • END. /* SetFullSentences */


Oct 11, 2011 at 1:56 PM // reply »
1 Comments

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


Feb 23, 2012 at 1:16 PM // reply »
1 Comments

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.

  • sub gen {
  • $a=shift;
  • &{say "$_ is so $a"} for (@_);
  • }
  •  
  • $_->() for(@{gen('perlish'=>qw|tom dick harry|)});

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!



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 19, 2013 at 9:38 PM
Directive Link, $observe, And $watch Functions Execute Inside An AngularJS Context
@Alesei, Glad you like it. Even after working with AngularJS for months, I still get a bunch of unexpected, "$digest is already in progress". So hard to debug sometimes! ... read »
Jun 19, 2013 at 9:36 PM
Working With Inherited Collections In AngularJS
@Mike, The relationship of $scope values is definitely an interesting thing! But it's not simple - it really forces you to understand prototypal inheritance, which is not at all a simple topic! Gla ... read »
Jun 19, 2013 at 9:35 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
@Joe, Oh, super interesting! I had only thought to url-encode the signature; but I think that's because the S3 docs actually have a special NOTE telling you to do so. It would have never occurred t ... read »
Jun 19, 2013 at 9:32 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
@Richard, Glad you like! Hopefully I'll have some more interesting stuff coming. This morning, I blogged a bit more about generating the pre-signed, query string authenticated URLs; but, then deeme ... read »
Jun 19, 2013 at 9:31 PM
Filter vs. ngHide With ngRepeat In AngularJS
@Mike, Honestly, in the majority of cases, I would say there isn't going to be a difference. Both approaches have trade-offs. If you use the filter, then you have fewer DOM elements and fewer $scop ... read »
Jun 19, 2013 at 2:01 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
I have coincidentally been beating my head against the S3 API for the last week or so. One big "gotcha" I had to work around was file names and paths containing spaces. Remember to URL Enco ... read »
Jun 19, 2013 at 1:27 PM
Using Slice(), Substring(), And Substr() In Javascript
very good article. By the way IE supports negative values in substr or slice in verson 10. ... read »
Jun 19, 2013 at 11:33 AM
Filter vs. ngHide With ngRepeat In AngularJS
In your assessment, is it correct to say that given a list of say 500 items its more performant to use the `ngHide` method over the `filter` method? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools