bits of programs
glide around
in my head
sometimes i dream
that my data structures are all immutable and that I've made little one method, no data object
objects i call functions
sometimes i dream that these function things
are already there
make_description = lambda {|b| "#{@title} by #{@author} / #{@year_publ}"}
and i don't have to do anything
then it's a good dream
function pipeline(value, funcs) {
for(i in funcs) {
value = funcs[i](value);
}
return value;
}
function compose(funcs){
return function(value){
return pipeline(value, funcs);
}
}
now
my functions are things
i can start with an array
of function things
and turn them into a new function
def upper(s)
s.upcase
end
def title(book)
#puts "title for book #{book}"
book[:title]
end
upperCaseTitle=compose([method(:title), method(:upper)])
big_title = upperCaseTitle.call(pride)
i can assemble
functions
like legos
new_array = []
for b in books:
new_array.append(big_title(b))
sometimes i want to
loop over an array
doing something
to each element
but
loops are hard
there's
loop variables
and making a new array
for the result
and
my code is all wrapped up
in these function things
def nap_map(f, arry):
result = []
for i in range(len(arry)):
result.append(f(arry[i]))
return result
new_array = nap_map(upperCaseTitle, books)
so i write a function
that does the loop for me
var new_array = books.map(upperCaseTitle);
sometimes in my dream
this function is
already there
and i roll over
and make yummy noises
C ITS HARD TO SLEEP WHEN YOUR CODE IS SHOUTING
C BUT FORTRAN IV HAS NO LOWERCASE
C NO INSIDE VOICE
sometimes i want
to combine
the elements of an array
together
into a single value
a = [1, 2, 3, 4]
result = 0
a.each {|x| result = result + x}
like when i want to
add all the numbers
in an array
together
but loops are a lot of work
i’m too tired
to repeat
all that work
so i write a function
that reduces the work
def resting_reduce(f, arry)
result = arry.first
arry.shift.each {|x| result = f(result, x)}
result
end
all i
supply is the function
to combine
an element with
the current result
numbers = [1, 2, 3, 4]
sum = resting_reduce(method(:add2), 0, numbers)
that’s kind of hard
so i pull
the covers over my head
but easier
than the loop thing
/* Java coding standard - method parameters
* The number of parameters that required by a method
* should be proportional to the good that the method does
* 0-4: Ordinary application methods
* 5-6: System accounting and free pretzels
* 7-9: Methods generating world peas
* 10+: No excuse
*/
sometimes i have
a function
lots of arguments
i already know the values
of the first few arguments
writing out all those arguments
over and over
is hard
def placid_partial(f, *args):
return lambda *more_args: f(*args, *more_args)
so i write a function
that gives me a function
that does the same thing
function add2(a, b) {return a + b}
var increment = placid_partial(add2, 1);
but fills in the arguments
it's a pain
but less pain
than writing this stuff
over and over
var pride = {"title": "Pride and Prejudice", "author": "Austen", "published": 1813};
sometimes
i'm tired of typing
semicolons
and commas
and all the rest
in my dream
i make them
go away
pride = {"title" "Pride and Prejudice" "author" "Austen" "published" 1813}
better
but there are still
a lot of rules
a lot
function nap_map(f, arry) {
result = [];
for(i in arry){
result.push(f(arry[i]));
}
return result;
}
do i have parentheses
do i have braces?
is END a thing?
too hard
function(nap_map [f arry]
set(result [])
for(i in arry
push(result f(get(arry i)))
)
return(result))
make everything
look like
a function call
now there is less to remember
i can end
this exhausting REM sleep
and go back
to being truly unconscious
[1 2 3 4]
sometimes i’m making an array
add2(1 3)
sometimes i’m calling a function
sometimes i forget
to put the name of the function
on the outside
(add2 1 3)
in my dream i
stick the name of the function
on the inside
like an array
(function upper [s] (return (toUpperCase s)))
(function title [book] (return (title book)))
(def upperCaseTile (compose [title, upper]))
(def bigTitle (upperCaseTitle pride))
and now there's
two kinds of collections
the ones with
parentheses
do something
like call a function
the ones with square brackets
are data
time my-program.jsrbpyjavaftnco
real 0m0.018s
user 0m0.001s
sys 0m0.006s
and in the predawn hours
just before i wake up
i dreamed
that i
waved my hands
and it all runs
fast
very fast
(def pride {:title "Pride and Prejudice" :author "Austen" :published 1813})
(def war {:title "War and Peace" :author "Tolstoy" :published 1869})
(def zombies {:title "Pride and Prejudice and Zombies" :author "Grahame-Smith" :published 2009})
(def books [pride war])
and as reality
folds into my dream
and i think now
(def other-books (assoc books 0 zombies))
i can look away
from my data
without worrying
that someone will
mess with it
(defn description [b]
(str (:title b) " by " (:author b) " published in " (:published b)))
i can write code
without
so much
syntax
(defn upper [s] (.toUpperCase s))
my code lives
in tidy little function
which are things
my functions operate
(def yelling-title (upper "War and Peace"))
on simple values
(def yelling-titles (map upper ["Emma" "Jaws" "The Giver"]))
on collections
(def extract-yelling-title (comp upper :title))
on each other
it all runs fast
in my dream
the living is good
the programming is easy
– Russ
A version of this article originally appeared on Cognitect blog.