Avoiding Naming Things

Does anyone use & anonymous functions much?

E.g.

Enum.map [1, 2, 3, 4], &(&1 * 2)

One less thing to worry about everyday - naming variables - it’s probably the biggest mental waste I have.

But the syntax is a little clunky in Elixir…

I sort of prefer,

(*2)

maybe &s will grow on me. Is that a Ruby thing?

2 Likes

Something like (*2) would not really work well in most cases in Elixir as functions can have multiple arities (though not in *), and how would you know which to choose?

In languages like ML’y languages where every function is arity 1 (every-single-one) then something like (*2) becomes trivial to implement as it is not currying at all, it is instead just calling */1, which happens to return another function that is also arity 1. ^.^

2 Likes

I agree with you about the mental effort of giving names to trivial things. I find anonymous functions to be used a lot in Elixir. No, that shorthand syntax doesn’t come from Ruby.

4 Likes

Sam Gardiner:

if you don’t know what a thing should be called, you cannot know what it is. If you don’t know what it is, you cannot sit down and write the code.

If you can’t name it, you can’t write it. If you change the name 3 times, then you should stop until you know what you are trying to build.

I would have just said: “If you can’t name it, how do you know it’s doing what it needs to do?”

8 Likes

Naming things is one of the two hardest problems in all of computer science. Those problems are:

  1. Naming Things
  2. Cache coherency
  3. Off by one errors
1 Like

A Type definition? Just kidding :wink:

Typically attributed to Phil Karlton (well 66% of it)
Two hard things
Tim Bray’s Blog

2 Likes

Naming is communication - your future self is going to thank you for your continued efforts to communicate effectively.

Kevlin Henney has some opinions on some ineffective communication strategies related to naming, though you might as well just watch the whole thing:

Istanbul Tech Talks 2016 - Kevlin Henney - Seven Ineffective Coding Habits of Many Programmers.

Peter Hilton’s advice for “Better Naming” starts on slide 59:
How to name things: the hardest problem in programming

8 Likes

I like naming things - like you, I feel they act as documentation of sorts :003:

Some people (like DHH) go further and do not like comments at all, but instead prefer long(ish) variable and function (or in his case, method) names so they can replace comments.

3 Likes

Yep agree - I suppose I slip into naming things with single characters too often…

That’s insane :043:

1 Like

:icon_question: Really? Frankly &1, &2, &3, etc. (which some people have no problem with) are totally devoid of meaning, while stuff like

i, j, k
[h|t]
[x|xs]

conveys something by convention (though there’s typically room for improvement).

1 Like

I don’t think they are devoid of meaning, they signify the 1st, 2nd, 3rd etc

What is I``j k and [x|xs]?

[h|t] is fine as I imagine most people will know what that is (similarly perhaps, common abbreviations such as r``g``b - though personally I would prefer to be explicit).

Having said that, I gathered @mmport80 to be doing something like:

def c do
  #something
end

:lol:

2 Likes

While that may signify a parameter position within the function it doesn’t contribute any information about what the parameter’s role is within the problem that the function is solving.

  • i, j,k typically a whole number counter that is part of an exit condition for iteration, recursion.
  • [x|xs] x - a single element at the head of the list; xs a list of 0 or more elements (of the same type as x) - essentially what Haskell-ites use instead of [h|t], but it can come up in any language, in code that is written by someone who has used Haskell because it intuitively conveys: one x vs. zero-to-many of the type of x.
2 Likes

I inevitably start doing it whenever I use with:

with ... <- (fn -> ... end),
     ... <- (fn -> ... end),
     ... <- (fn -> ... end),
do: (fn -> ... end)
3 Likes

I seem to be in the minority but I feel that code that makes extensive use of anonymous functions is ultimately harder to reason about.

Source code isn’t for the computer, it’s for the person who has to maintain it down the road (possibly yourself after 10 or so other projects/products in 6 different languages have already passed through your brain). It ultimately forces the reader to be a human parser and make up names on the fly in order to compartmentalize the details.

I much prefer short (hopefully expressively) named functions where I only have to parse a tiny bit of code to get a general notion of what it does so that I can ditch the details and recall the “general notion” whenever I encounter the name.

In the particular case of the above with expression replacing the anonymous functions with named functions we could get an initial impression of what the code is all about - anonymous function force us to parse every nitty gritty detail.

Refactoring: Rename Method

The name of a method does not reveal its purpose.

Given that a anonymous function doesn’t have a name “it can’t reveal its purpose”.

3 Likes

This is precisely a good example of why well typed functions are useful. You don’t often need to name things since the types themselves already name them (and in any good IDE you get those on hover or in inline fake comments or so). :slight_smile:

Anonymous functions are much easier and readable in a typed world. :slight_smile:

1 Like

Yes you are absolutely right, I eventually go back and refactor those code during review time. In a way anon functions are like inner blocks in c.

1 Like

I don’t think you’re in the minority with that. The difference is probably where we draw the line of “extensive”. It’s a matter of degree.

1 Like

This is precisely a good example of why well typed functions are useful. You
don’t often need to name things since the types themselves already name them

Really?

int -> int -> int

? :slight_smile: However that may not be what you mean well-typed? and you’d rather
use type aliases or similar to give context (probably not the right word
to use here) to the types?

For me:

-spec x(integer(), integer()) -> integer().

has about the same informatition.

-spec multiply(Factor :: integer(), Factor :: integer()) ->
Result :: integer().

even more so.

Anonymous functions are much easier and readable in a typed world.

I don’t see much difference to be honest. Do you have a good example
where this shows?

2 Likes