Today morning while browsing The Changelog, I came across this interesting project called - Goal.
g()(‘al’) is a challenge whereby you need to write in as many languages as possible code which enables the code g()(‘al’) to return the string “goal”, the code g()()(‘al’) to return the string “gooal”, the code g()()()(‘al’) return the string “goooal”, etc.
This sounded a good way to kill a couple of hours on a lazy holiday so I decided to give this a shot in a couple of programming languages I know.
The project is interesting because it is a fun way to demonstrate support for higher order functions in your favorite language. Getting to see how this is accomplished in all kinds of languages (and languages where it’s not possible) is quite useful. The key idea to solve this problem is indeed simple -
g
that takes two arguments. One to check for the suffix and other to count the number of ‘o’s to insertg
is called without a suffix e.g. g()
return a function that returns the function g
with the count incrementedg
is called with a suffix e.g. g()('al')
return the final string by concatenating ‘g’, the numbers of ‘o’s and the suffix.Programming languages where functions can be returned make this problem very easy to solve. Languages where this is not possible, there are techniques like regex matching, metaprogramming, or preprocessing to solve the problem.
The code below in Python is a literal translation of the above pseudo-code and pretty readable.
def g(al=None, count=0):
if al:
return 'g' + (count * 'o') + al
else:
return lambda al=None: g(al, count+1)
print(g('al')) # gal
print(g()('al')) # goal
print(g()()('al')) # gooal
print(g()()()('al')) # goooal
Here’s the golfed version (in case you’re into golfing)
def g(al=None,c=0):
return 'g'+c*'o'+al if al else lambda al=None: g(al, c+1)
Must-Read Python submissions
functools
module.inspect
module to regex match through the stack trace.The same thing is implemented below in Javascript but with a slight change. Since, javascript does not provide support for default arguments a neat way is to keep updating the second argument with repeated ‘o’s.
function g(al,o) {
if (al === undefined) {
return function(al) {
return g(al, ((o||'')+'o'))
}
} else {
return 'g' + (o||'') + al
}
}
console.log(g('al')) // gal
console.log(g()('al')) // goal
console.log(g()()('al')) // gooal
console.log(g()()()('al')) // goooal
This can be made much shorter by using coffeescript.
g = (al,o) -> return if al then 'g'+(o||'')+al else (al) -> return g(al,((o||'')+'o'))
OCaml is a language that I’ve been learning lately. Being functional, this seemed a rather easy task to accomplish. Unfortunately, due to lexical reasons you can’t use the g()()
syntax for function calls (without hacking the parser). However, below is the code that does something similar.
let g f = f "g"
let al x = x ^ "al"
let o x f = f (x ^ "o")
let () =
print_endline (g al); (* gal *)
print_endline (g o al); (* goal *)
print_endline (g o o o al); (* goooal *)
Note: The OCaml solution has been picked up from this reddit thread.
()
is seen.For more exciting solutions do check out the github repo and the pull requests.