Functional Dreams

zzzzzz

sometimes

i dream in code

class Book:
  def __init__(self, a, t, p):
    self.author = a
    self.title = t
    self.published = p

  def description(self):
    return self.title + " by " + self.author + 
           " published in " + self.published

bits of programs
glide around
in my head

function Book (t, a, p) {
  this.title = t;
  this.author = a;
  this.published = p;

  this.description = function() {
    return this.title + ' by ' + this.author + 
           ' published in ' + this.published;
  };
  return this;
}

i close my eyes
and there it is
code

0800 Rem One
0900 Dim thisBook As book
1000 Rem The next one

always the code
pointy k's
and bumpy m's

it follows me
from one rem cycle
to the next

01  BOOK
    05  TITLE           PIC X(15).
    05  AUTHOR          PIC X(15).
    05  YEARPUB         PIC 9(4).

i've used
a lot of
programming languages

class Book {
  private String title;
  private String author;
  private int year_published;

  public Book(t, a, p) {
    title = t;
    author = a;
    year_published = p;
  }

  public getDescription() {
    return title  + " by " + author +
           " published in " + year_published;
  }
}

from basic to fortran

0100 author = "Tolstoy"
0200 title = "War and Peace"
0300 published = 1869

to ruby and python

class Book
  attr_accessor :author, :title, :published

  def initialize(a, t, p)
    @title = t;
    @author = a;
    @published = p;
  end

  def description
    "#{@title} by #{@author} published in #{@published}"
  end
end

sometimes
it all
runs together

0100  class Book:
 0200    attr_accessor :author, :title, :published
 0300
 0400    public Book(t, a, p) {
 0500      title = t;
 0600      author = a;
 0700      year_published = p;
 0800    }
 0900  end

these dreams
of code
they are hell

var codeBook = Book("Inferno", "Dante", 1320);

coding is my job
five days a week
i'm coding man

but i don't want to code
when i'm sleeping

i just want to sleep
when i'm asleep

hell

pride = Book.new("Pride and Prejudice", "Austen", 1813)

since i can't
get away from the code
i try to make it
as easy as i can

after all
i’m tired
in fact i'm asleep
life should be easy
when i'm asleep

C  DONT LET THE SOUND OF YOUR OWN WHEELS DRIVE YOU CRAZY

       NOW = TIME(0)
       CALL MAKEEASY(NOW)

sometimes
when i'm dreaming
in code
i make an array

pride = new Book("Pride and Prejudice", "Austen", 1813);
war = new Book("War and Peace", "Tolstoy", 1869);

books = {pride, war};

and i let your code
borrow my array

your_nefarious_code(books);

and your code
changes my array

// Your nefarious code.

public your_nefarious_code(Book[] books) {
  zombies = new Book("Pride and Prejudice and Zombies", 
                     "Grahame-Smith", 2009);
  books[0] = zombies;
}

it's my array
i didn't want you
to change it

truth be told
sometimes
i do it to myself

// An honest mistake

public my_function(Book[] books) {
  jaws = new Book("Jaws", "Benchley", 1974);
  books[0] = jaws;
}

i have an excuse though
i’m asleep

# Don't modify this code unless you are unconscious.

this changing
behind my back
makes me
thrash in my sleep

def []=(idx, value)
  raise "YouCantChangeMyArraySucker"
end

so in my dream
i make
a new rule
no more
changing arrays
ever

// Your nefarious code foiled.
// Blam! Throws a YouCantChangeMyArraySuckerException!

  books[0] = zombies;

once i create an array
that's it
you can't change it
neither can i

your_impossible_to_be_nefarious_code(books);

now
i don't
have to worry
about your code or threads
messing with my arrays

or my code
or my threads
it’s just easier

0600 REM I like zombies

but sometimes
i need
to change my array

GoTo 0000

but if i do
i'm back to square one
i don't want to deal with it

function justLikeTheOldOneExcept(a, i, x){
  result = a.slice(0);
  result[i] = x
  return result
}

so i'll let arrays make
copies of themselves
copies that are
the same as the original

only different

var pride = new Book("Pride and Prejudice", "Austen", 1813);
var war = new Book("War and Peace", "Tolstoy", 1869);
var zombies = new Book("Pride & Prejudice & Zombies", "Grahame-Smith", 2009);

var books = [pride, war];

var other_books = justLikeTheOldOneExcept(books, 0, zombies);

then i can have
my old array
and
my new array

C  ZOMBIES ARE BACK

now i don't have to
expend the effort
to trust you

/* I trust me more than you. */

or me

/* I don't trust me. */

but sometimes you
change my objects too

public void aNefariousBookMethod(Book b) {
  b.setTitle("Dirk Gently's Holistic Detective Agency");
}

sometimes i forget
and change them myself

// Going about my sleepy business..

Book war = new Book("War and Peace", "Tolstoy", 1869);
aNefariousBookMethod(war);

// Wait what?

System.out.println(war.title);

it's been a long night
so let's have the same rules for objects
and arrays

def justLikeTheOldOneExcept(v, i, x):
  result = copy(v)
  if isinstance(result, list):
    result[i] = x
  else:
     setattr(result, i, x)
  return result

no changing
just modified copies

Book book1 = new Book("War and Peace", "Tolstoy", 1869);

Book book2 = book1.justLikeTheOldOneExcept(
                 "title", 
                 "Dirk Gently's Holistic Detective Agency");

after all
it's just a dream

// Rules are like spouses. There is an optimal number to have.

now there are fewer
rules to remember

sometimes i make an object
with private fields

class Book {
  private String title;
  private String author;
  private int year_published;

  // ...
}

then i discover
that i need
to get at
those private fields

class Book {
  private String title;
  private String author;
  private int year_published;

  public String getTitle(){
    return title;
  }

  public String getAuthor(){
    return author;
  }

  public int getYearPublished(){
    return year_published;
  }
}

so i make them public

C TOTAL UP THE EFFORT

       EFFORT = PRIVEFFT + PUBLEFFT

i had to make the
private fields private
and then i had to make
the private fields public

C ITS HARD TO SLEEP WHEN YOUR CODE IS SHOUTING
C BUT FORTRAN IV HAS NO LOWERCASE
C NO INSIDE VOICE

that’s a lot of work
and then it's more work

class Book {
  public String title;
  public String author;
  public int year_published;
}

so i'll just use a
map or a hash or a dictionary
or whatever we call it in this language
and make an open
name/value thing

var pride = {"title": "Pride and Prejudice",
             "author": "Austen", 
             "published": 1813};

now i can make
new objects full of data
as fast as i can type
which isn't very fast
since
my eyes are closed

var zombies = {"title": "Pride and Prejudice and Zombies",
               "author": "Grahame-Smith", 
               "published": 2009};

var war =  {"title": "War and Peace", 
            "author": "Tolstoy", 
            "published": 1869};

if all my data
is in
hashes or
dictionaries
or maps
whatever we call them
in this language
then i don't have a place for my code

interface Function {
  public Object invoke(Object arg);
}

class MakeDescription implements Function {
  public Object invoke(Object arg) {
    Book book = (Book)arg;

    return book.get("title") +
           " by " +   
           book.get("author") + 
           " published in " +  
           book.get("yearPublished");
  }
}

so i'll just make little
one method
no data
objects
and put my code there

i'll call these things
functions
that’s a word i learned in
math class
before i feel asleep

var make_description = function (b){
  return b.title + 
         " by " + b.author +
         " published in " + b.published
};

sometimes i dream
that these function things
are already there

make_description = lambda do |b|
  "#{@title} by #{@author} / #{@year_publ}"
end

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

/*  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-8: With mustard
 *  9-10: Methods generating world peas
 *  11+: 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

REM Sleep

[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

live the dream

clojure