Suggestion for topic in the "Names" chapter

141 views
Skip to first unread message

Ben Brinckerhoff

unread,
Mar 29, 2016, 10:49:38 PM3/29/16
to Elements of Clojure
Zach,

I really enjoyed the sample chapter on naming and I look forward to the rest of the book. Incidentally, "Always Be Composing" is one of my favorite talks.

In the sample chapter, there are several pieces of good advice:

"If a function takes an id and returns a binary payload, it should be called get-payload."

"If a function only transforms data, we should avoid verbs wherever possible"

"The right side is a deeper level of the code, relevant only if the what of europa doesn’t satisfy, and we need to understand the how"

I like these guidelines, but I was wondering if you had advice for `let` bindings that shadow a function name. e.g.

(let [primes (primes numbers)]
  {:primes primes
   :primes-squared (map * primes primes))

I realize that's a silly example, but the relevant parts of the example are:

1. The `let` binding allows us to avoid duplication
2. The function name `primes` is the natural choice for the name of the result
3. If we replaced with a shorter name, like `p`, it requires that the reader looks at the right side of the binding to understand the value.

I find this comes up fairly often in my Clojure code. If you had advice that would naturally fit in the naming chapter, I suspect it would be useful to others as well.

Best wishes,
Ben
   

Zach Tellman

unread,
Mar 30, 2016, 1:57:40 AM3/30/16
to Ben Brinckerhoff, Elements of Clojure
That's a good question.  I think that in that case, absent any other context, I'd call it `p`, especially since I don't want to shadow the `primes` function unnecessarily.  As you say, though, `p` is far from self-explanatory.  I think expanding on the "you shouldn't have to look at the right side" advice would be useful, I'll have to think a bit more about it, though.

Thanks for the counter-example,
Zach

--
You received this message because you are subscribed to the Google Groups "Elements of Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elements-of-clo...@googlegroups.com.
To post to this group, send email to elements-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elements-of-clojure/47d129b1-d3d8-41fb-83bb-5bcc5c75bd60%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Zach Tellman

unread,
Apr 6, 2016, 4:34:40 PM4/6/16
to Elements of Clojure, bhbrinc...@gmail.com
I've added this to the first chapter:

---

Where a value is used repeatedly, we may prefer to use a short name rather than a self-evident one.  Consider this code:

```clj
(doseq [g (->> planets 
            (remove gas-planet?) 
            (map surface-gravity))]
  ...)
```

If we renamed `g` to `surface-gravity`, most readers could understand the intent without reading the right-hand expression.  Unfortunately, this shadows the function of the same name, and is fairly verbose.  By itself, though, `g` doesn't mean anything.  The reader is forced to carefully read both sides of the binding to understand the intent.

If the left-hand name isn't self-evident, the right-hand expression should be as simple as possible.  We prefer this:

```clj
(let [surface-gravities (->> planets 
                          (remove gas-planet?) 
                          (map surface-gravity))]
  (doseq [g surface-gravities]
    ...))
```

---

Let me know if you feel this doesn't address your question, or is in any way unclear.

Zach

On Tuesday, March 29, 2016 at 10:57:40 PM UTC-7, Zach Tellman wrote:
That's a good question.  I think that in that case, absent any other context, I'd call it `p`, especially since I don't want to shadow the `primes` function unnecessarily.  As you say, though, `p` is far from self-explanatory.  I think expanding on the "you shouldn't have to look at the right side" advice would be useful, I'll have to think a bit more about it, though.

Thanks for the counter-example,
Zach

On Tue, Mar 29, 2016 at 7:49 PM Ben Brinckerhoff <bhbrinc...@gmail.com> wrote:
Zach,

I really enjoyed the sample chapter on naming and I look forward to the rest of the book. Incidentally, "Always Be Composing" is one of my favorite talks.

In the sample chapter, there are several pieces of good advice:

"If a function takes an id and returns a binary payload, it should be called get-payload."

"If a function only transforms data, we should avoid verbs wherever possible"

"The right side is a deeper level of the code, relevant only if the what of europa doesn’t satisfy, and we need to understand the how"

I like these guidelines, but I was wondering if you had advice for `let` bindings that shadow a function name. e.g.

(let [primes (primes numbers)]
  {:primes primes
   :primes-squared (map * primes primes))

I realize that's a silly example, but the relevant parts of the example are:

1. The `let` binding allows us to avoid duplication
2. The function name `primes` is the natural choice for the name of the result
3. If we replaced with a shorter name, like `p`, it requires that the reader looks at the right side of the binding to understand the value.

I find this comes up fairly often in my Clojure code. If you had advice that would naturally fit in the naming chapter, I suspect it would be useful to others as well.

Best wishes,
Ben
   

--
You received this message because you are subscribed to the Google Groups "Elements of Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elements-of-clojure+unsub...@googlegroups.com.
To post to this group, send email to elements-of-clojure@googlegroups.com.

Ben Brinckerhoff

unread,
Apr 8, 2016, 10:17:04 PM4/8/16
to Elements of Clojure, bhbrinc...@gmail.com
It took me a minute to figure out what you were getting at, because my first reaction was "but `surface-gravities` doesn't shadow `surface-gravity`, so that doesn't really address the problem I'm having".

But now I think I see your intent. Ideally, the left side would be self explanatory, If that's not possible (due to shadowing or verbosity), then a short name is fine, but the *right-hand* side should be as simple as possible, so the reader can quickly and easily understand the meaning of the short name. And your example illustrates this: in the `doseq` form, the value of `g` is obvious due to the name `surface-gravities`.

Just to make sure I understand your intent, in my original example, a short name would be OK when the right side is simple:

```
(let [ps (primes numbers)]
  {:primes ps
   :primes-squared (map * ps ps)})
```

Whereas the following would be less desirable, since the right hand side does not clearly indicate the value of the short name "ps"

```
(let [ps (remove (fn [n] (some #(= 0 (mod n %)) (range 2 n))) numbers)]
  {:primes ps
   :primes-squared (map * ps ps)})
```

Of course, in the above, since there is no longer a `primes` function, we can create the left side name that clearly indicates the value e.g.

```
(let [primes (remove (fn [n] (some #(= 0 (mod n %)) (range 2 n))) numbers)]
  {:primes primes
   :primes-squared (map * primes primes)})
```

If I'm understanding correctly, then yes, those suggestions make sense. Thanks for the addition!

Best wishes,
Ben
To post to this group, send email to elements-...@googlegroups.com.

Zach Tellman

unread,
Apr 9, 2016, 12:21:17 AM4/9/16
to Ben Brinckerhoff, Elements of Clojure
Yeah, that's the idea.  Glad it makes sense and seems applicable.

To unsubscribe from this group and stop receiving emails from it, send an email to elements-of-clo...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "Elements of Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elements-of-clo...@googlegroups.com.

To post to this group, send email to elements-...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages