# Name It

There will be Ruby in the middle of this blog post. But first, a tangent in which we explore the lambda calculus. Don’t worry too much about being lost in this next section; we’ll fix that immediately afterward.

## A Simple Language

There is a programming language named the lambda calculus. It’s rather minimal: an expression, `E`, is one of three things:

• a variable, `V`, like `a`, `b`, or `c`
• a function of one parameter, written `λV.E`
• two expressions applied to each other, written `E E`

For example, the identity function is written:

``λx.x``

And a function that takes two arguments and produces the first is written:

``λx.λy.x``

You might want to try it out interactively.

We can encode numbers using this programming language, with some creativity. For example, this is the number zero:

``λf.λx.x``

And this is one:

``λf.λx.f x``

And this is two:

``λf.λx.f f x``

And so on. We can even add them, using this addition expression:

``λm.λn.λf.λx.m f (n f x)``

(This is far too tangental, but this definition of numbers and addition is an early example of object-oriented programming.)

For example, to add the number one and the number two, we’d write this:

``(λm.λn.λf.λx.m f (n f x)) (λf.λx.f x) (λf.λx.f f x)``

## Name It

There is an oft-included “extension” to the lambda calculus that might help: naming. Let’s add this expression to our language:

• a name definition, written `VALUE ≡ E`

So now we can write:

``````
ONE ≡ λf.λx.f x
TWO ≡ λf.λx.f f x
ADD ≡ λm.λn.λf.λx.m f (n f x)

``````

## Law Of Demeter

Here is another case, in another programming language, where naming is useful:

``````User.where('admin').each do |user|
user.articles.where('published_at IS NULL').each do |article|
article.update_attributes(published_at: Time.now)
end
end
``````

Here it is after introducing some names:

``````User.admins.each(&:publish_articles)
``````

And here it is after a further simplification:

``````User.publish_admin_articles
``````

## Take It Further

In the first naming section, we named concrete nouns; in the second, we named verbs. Let us now name a concept:

``````class SignUp
def initialize(params)
@account_params = params[:account]
@user_params = params[:user]
@credit_card_params = params[:credit_card]
end

def run
account = Account.new(@account_params)
if account.save
user = User.new(@user_params.merge(account: account))
if user.save
credit_card = CreditCard.new(@credit_card_params.merge(user: user))
if credit_card.charge
user.charged
end
end
end
end
end
``````

Above we have named the concept of signing up, and given it behavior. We can name even more concepts: merging two users, generating flash messages, processing image files, building a model of a couch.

## Taking It Too Far The average human vocabulary is around 10000 words. While the jury is still out on what the maximum number is, we can all agree that keeping the number of names low is useful for keeping all of an app in your head at once.

There is another trick for more easily understanding an app: a common vocabulary. When you see a `User` model, you know what it means; when you see an `Enrichment` class, that’s puzzling. By naming more things uniquely, you have reduced the vocabulary overhead.

Or is this a red herring? Another way to keep the vocabulary low is to name everything, but have very few things to name. Push stuff into frameworks, libraries, and APIs when possible, and out of scope otherwise. You ain’t gonna need that `Bracelet` class.

## Not Taking It Far Enough

The idea of a common vocabulary is enticing. User, article, comment, controller, singleton, and enumeration are all names we Rails developers understand. Monad, cut, disjunction, pointer—those are other people’s vocabularies. But what if …

What if we outgrew our vocabulary and started poaching theirs? And not like how we poached “functional test” and “closure”—I mean actually use their words the way they are defined.

What if instead of this …

``````def map(&f = lambda {|x| x})
accumulation = []
each do |element|
accumulation << f.call(element)
end
accumulation
end
``````

… we wrote this:

``````def map(&f = id)
inject([]) do |accumulation, element|
accumulation + [f.call(element)]
end
end
``````

Heck, what if we went further and wrote this:

``````def map(&f = id)
inject(empty) do |accumulation, element|
accumulation + wrap(f.call(element))
end
end
``````

This uses a method `Kernel#id` to name the common `lambda {|x| x}` abstraction; a method `empty` that produces the empty version of whatever object this `Enumerable` is mixed into; and a similarly-defined method, `wrap`, that projects the given object into the `Enumerable`. Now it produces arrays, linked lists, sets, tries, maybes, and so on, as needed.

And now we can use the names identity function, functor, and monoid, too.

Just as our lambda calculus example was greatly simplified by naming our functions, our way-too-long methods can be improved by naming our methods. As with anything, though, there is a trade-off that you must carefully consider.

Here’s an example of some code with very few names:

``````def acquire_access_token_for(c)
res = Net::HTTP.start('github.com', 443, use_ssl: true) do |http|
r.set_form_data('client_id' => '1234123',
'client_secret' => 'basdu9as',
'code' => c)
http.request(req)
end

case res
when Net::HTTPsuccess
b = res.body
if b['access_token'].any?
b['access_token'].first
else
raise b['error'].first
end
else
raise res.inspect
end
end
``````

Here’s the same example, with more names:

``````def acquire_access_token_for(code)
access_token_response = access_token_post(code)

case access_token_response
when Net::HTTPsuccess
extract_access_token_from(access_token_response)
else
handle_access_token_failure(access_token_response.message)
end
end

private

GITHUB_CLIENT_ID = '1234123'
GITHUB_SECRET = 'basdu9as'

def access_token_post(code)
Net::HTTP.start(*http_connection) do |http|
request = Net::HTTP::Post.new(github_access_token_path)
request.set_form_data('client_id' => GITHUB_CLIENT_ID,
'client_secret' => GITHUB_SECRET,
'code' => code)
http.request(request)
end
end

def http_connection
[
github_access_token_uri.host,
github_access_token_uri.port,
use_ssl: true
]
end

def github_access_token_path
github_access_token_uri.path
end

def github_access_token_uri
URI.parse(github_access_token_url)
end

def github_access_token_url
end

def extract_access_token_from(successful_http_response)
body = CGI.parse(successful_http_response.body)
if body['access_token'].any?
body['access_token']
else
handle_access_token_failure(body['error'].first)
end
end

def handle_access_token_failure(error_message)
raise error_message
end
``````

As you can see, there’s a trade-off: on the one hand, you can now read it with ease, debug more easily, and have a vocabulary with which to discuss it with others. On the other hand, it takes more vertical space.

## Naming As a Building Block

Naming is the most powerful abstraction possible. By naming something, you give other people the ability to build atop it. By re-using a name you build a common vocabulary, encouraging more people to build. Naming turns a blob of code into a sequence of patterns. Giving a name to something develops it into a concept with analogies.

So, name it.