Skip to main content
Ben Nadel at Node.js Training with Nodejitsu (Apr. 2011) with: Paolo Fragomeni and Charlie Robbins and Marak Squires
Ben Nadel at Node.js Training with Nodejitsu (Apr. 2011) with: Paolo Fragomeni@hij1nx ) , Charlie Robbins@indexzero ) , and Marak Squires@maraksquires )

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

By on

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

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);
	})();
15,260 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.

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
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#" />
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);
}
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?

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
15,260 Comments

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

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 />";
}
 
?>
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
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;
}
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.

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

15,260 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.

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();
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"
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]

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.

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

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")
15,260 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.

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.

14 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");
15,260 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.

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.

15,260 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.

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!

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

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?

15,260 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 :)

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")
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.

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!

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.

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!

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!

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

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;
}
 
}
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')
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
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.

15,260 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!

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

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)
15,260 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!

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")
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
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 */
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

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!