# Digression on short variable names

**URL:** <https://discourse.julialang.org/t/digression-on-short-variable-names/91859>\
**Category:** Offtopic\
**Created:** [December 18, 2022, 8:27am UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859 "2022-12-18T08:27:42Z")\
**Posts on this page:** 14\
**Page:** 2

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [December 20, 2022, 6:59am UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/21 "2022-12-20T06:59:13Z")

</div>

Great extension! I think between Module and let it is also okay locally within a function (see above `sim::Simulation` – maybe even just `s`), of course only for not-too-long functions, but that is something one should anyways aim for 🙂

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [December 21, 2022, 9:27am UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/22 "2022-12-21T09:27:09Z")

</div>

Type annotation on concrete types is very descriptive and gives users of your function nearly perfect information of what they can use it for. The drawback, if you’re just using it to hint what sort of object something is, is that now you’re locked into a specific type of object—possibly before you’ve thought about what the type hierarchy should be. So it can sometimes be a premature optimization.

If you haven’t figured out the type hierarchy yet, it can often be better to avoid trapping yourself like this; and that’s what Julia’s philosophy of method genericism is about. In those circumstances I think it’s good to use verbose names for function arguments, then internally the name can be shorter. For example:

```julia
run!(simulation) = let s=simulation
    while !completed(s)
        step!(s)
    end
    s
end

```

This way, external users can still get a good idea how to use your function from the argument names, but internally you’re not forced to repeat over and over a long name.

Either that, or default to declaring functions of abstract types such as `run!(s::AbstractSimulation)`, so that when you inevitably decide a month later that you want to fill out the type family (with `BatchedSimulation` and `SequentialSimulation` and every other simulation type you didn’t think about the first time), you can just add them as subtypes and not break everything.

---

<div class="post-metadata">

**Author:** ![tfiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tfiers/32/32427_2.png) [@tfiers](https://discourse.julialang.org/u/tfiers)\
**Post date:** [December 21, 2022, 1:06pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/23 "2022-12-21T13:06:39Z")

</div>

I love that!  
I’ve been experimenting with `let` for internal aliases lately  
(re also: Brian Chen’s mention [in Slack](https://julialang.slack.com/archives/C67TK21LJ/p1671115961485849?thread_ts=1671099263.640329&cid=C67TK21LJ) of [Swift’s ‘argument labels’](https://docs.swift.org/swift-book/LanguageGuide/Functions.html#ID166), where you can have different names for the public API and for internal use).

Does anyone know if multiline variable bindings are possible with `let` ?  
i.e. sth like

```julia
simulate(model, parameters, and, more, names) = let (
    m = model,
    p = parameters,
    ⋮
)
    …
end

```

I’ve been trying different possibilities with `( )` and `;`, but they all give a syntax error 😄

* * *

Edit: ofc you can just write

```julia
function simulate(model, parameters, and, more, names)
    m = model
    p = parameters
    ⋮
    …
end

```

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [December 21, 2022, 1:30pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/24 "2022-12-21T13:30:07Z")

</div>

You can separate bindings with commas:

```julia
julia> let a=1,
           b=2,
           c=3
           a+b+c
       end
6

```

Note that there must be at least one binding on the same line as `let`; this doesn’t work:

```julia
julia> let
           a=1,
           b=2,
           c=3
           a+b+c
       end
ERROR: syntax: invalid assignment location "2" around REPL[181]:2

```

Because they evaluate left-to-right, later bindings can depend on earlier bindings:

```julia
julia> let a=1, b=a+1, c=b+1
           a+b+c
       end
6

```

See docs for [short description](https://docs.julialang.org/en/v1/base/base/#let).

> [@tfiers](#):
>
> Edit: ofc you can just write

indeed, although if you make a habit of using this style, for locally-declared functions you can sometimes run into [trouble with captured variables](https://github.com/JuliaLang/julia/issues/15276) so you have to be a bit more careful with managing your local namespace. Declaring bindings with `let` allows you not to think about that. You can also prefix each local assignment with `local` (which has meaning within scoped blocks like `let`, `for`, and functions, but not `begin...end`), but I think `let` is usually easier.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 21, 2022, 1:40pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/25 "2022-12-21T13:40:29Z")

</div>

> [@uniment](#):
>
> ```julia
> run!(simulation) = let s=simulation
> while !completed(s)
> step!(s)
> end
> s
> end
> 
> ```

But here you might as well write

```julia
function run!(simulation)
    s=simulation
    while !completed(s)
         step!(s)
    end
    return s
end

```

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [December 21, 2022, 1:46pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/26 "2022-12-21T13:46:18Z")

</div>

I agree. There’s no reason to add an additional nested local scope in that example.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [December 21, 2022, 1:58pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/27 "2022-12-21T13:58:14Z")

</div>

This is true for globally-declared functions, but can be hazardous for locally-declared functions. I’ve just made it a habit so my style can be consistent across scopes, since there’s no harm in it.

I also tend to write my named function definitions with `f(x) = ...` instead of `function f(x)...end` anyway, so maybe that’s why it feels natural for me.

---

<div class="post-metadata">

**Author:** ![tfiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tfiers/32/32427_2.png) [@tfiers](https://discourse.julialang.org/u/tfiers)\
**Post date:** [December 21, 2022, 2:04pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/28 "2022-12-21T14:04:44Z")

</div>

Yes, thank you for the warning, this feels like something that can bite you and cause befuddlement long down the line.

I didn’t know `function f(x) … end` and `f(x) = begin … end` are not the same 😮

So as a takeaway of that linked julialang issue: I should `@code_warntype` my closures to make sure no `Box`es are introduced?

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [December 21, 2022, 2:17pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/29 "2022-12-21T14:17:25Z")

</div>

> [@tfiers](#):
>
> I didn’t know `function f(x) … end` and `f(x) = begin … end` are not the same 😮

No they’re the same, but instead of saying `f(x) = begin ... end` you can also write `f(x) = let; ... end` and it’s [slightly] shorter and allows you to declare local variables without worrying about scope.

> [@tfiers](#):
>
> So as a takeaway of that linked julialang issue:

Yeah, I think that’d be a good takeaway. The reason boxes get introduced is because the compiler can’t prove from static analysis that the variable will not be changed during the closure’s lifetime, so when it compiles the function it does the safe thing and boxes the value, and then your performance goes down the drain. To get around that, you can use a `let` block. For example, you might have this:

```julia
map(k->m[k], o)

```

and somewhere in the parent scope, `m` gets changed so the closure puts `m` in a box. If you know that you really just wanted to take a snapshot of `m` at that very instant, you can wrap it in a `let` block like this:

```julia
map(let m=m; k->m[k] end, o)

```

There are other, more ergonomic ways to achieve this goal, such as:

```julia
let m=m; map(k->m[k], o) end

```

Anyway, point is that `let` blocks are awesome and I’m not shy to use them 😅

---

<div class="post-metadata">

**Author:** ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)\
**Post date:** [December 25, 2022, 12:33pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/30 "2022-12-25T12:33:46Z")

</div>

I just got recommended a video on Youtube. I think it’s absolutely spot on, so I wanted to share it with you: [Naming Things in Code - YouTube](https://www.youtube.com/watch?v=-J3wNP6u5YU)  
Let me know what you think!

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 25, 2022, 1:37pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/31 "2022-12-25T13:37:17Z")

</div>

I’m quite saddened by the general sentiment in this thread, seemingly preferring short or single letter variable names over just the slight inconvenience of thinking about a better name. The purpose of a longer, more descriptive name has nothing at all to do with readability. Sure, short variable names make sense “in context”, IFF you know that context already and haven’t forgotten it since the last time you touched that code. However, if you have lost that context (or maybe you’re reading a codebase for the first time?), longer variable names are incredibly useful for rediscovering that context. That’s what it means to have self-documenting code and that is the purpose of longer names.

I also heavily disagree with the notion that somehow, it’s more ok to have short variable names in libraries and only need longer ones in applications - how is anyone supposed to maintain a (perhaps critical) library if they can’t easily read & dive into the code?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 25, 2022, 3:21pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/32 "2022-12-25T15:21:23Z")

</div>

> [@Sukera](#):
>
> I’m quite saddened by the general sentiment in this thread, seemingly preferring short or single letter variable names over just the slight inconvenience of thinking about a better name.

As the (inadvertent) OP I’d like to point out that the ideal is ‘conciseness’, not terseness. There’s a balance to be struck between scrutability and legibility, and conciseness is the name of the balancing point.

In fact, one should expend a _lot_ of energy coming up with short, pregnant, names, it’s one of the important challenges in programming.

The linked thread showcased ‘the worst of both worlds’ imo, long, repetitive names, very similar, visually noisy, and with nearly zero explanatory information. If you don’t already know what they mean, you won’t be able to glean it from reading, and if you, you’d be better off just calling them `k` and `k'`.

> [@Sukera](#):
>
> I also heavily disagree with the notion that somehow, it’s more ok to have short variable names in libraries and only need longer ones in applications - how is anyone supposed to maintain a (perhaps critical) library if they can’t easily read & dive into the code?

Not always, but sometimes, library code is significantly more abstract. Variables don’t necessarily carry much meaning. When you look through Base, it is rife with `x`s, and quite right, there’s no inherent meaning in the inputs to `sqrt` or `sin` or `max`. Meaningful descriptive names should be in the code that _calls_ these functions, like `max(number_of_cats, number_of_dogs)`, ie. In the application code, not the library code.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 25, 2022, 5:20pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/33 "2022-12-25T17:20:45Z")

</div>

> [@DNF](#):
>
> The linked thread showcased ‘the worst of both worlds’ imo, long, repetitive names, very similar, visually noisy, and with nearly zero explanatory information. If you don’t already know what they mean, you won’t be able to glean it from reading, and if you, you’d be better off just calling them `k` and `k'`.

You’re conflating “descriptive names are better” with “longer names are better”. Sure, having similar looking long variable names is no better than having similar looking, short variable names, but I’d say that is not an argument for shorter variable names, but rather against similar looking names. Those are not the same thing.

> [@DNF](#):
>
> Variables don’t necessarily carry much meaning. When you look through Base, it is rife with `x`s, and quite right, there’s no inherent meaning in the inputs to `sqrt` or `sin` or `max`.

I think that those names are just as bad for those functions as they are in “longer” or “application” code. They still do carry meaning, especially since those library functions are very often using implicit assumptions for their correctness (which is a bad thing in itself), reverse engineering of which is significantly easier if the name for a variable is descriptive of what it’s purpose is. That doesn’t mean that every generic loop needs to have a name describing what it exactly is in the greater context of the program as a whole, that’s impossible for libraries, but just that it shouldn’t be “some x”, if it’s at all possible to avoid. E.g. for `sin`, call the input _at least_ `num` to be clear that you’re expecting something that at least superficially resembles a number.

For example, there’s this section in the fallback implementation for `hypot`:

> <https://github.com/JuliaLang/julia/blob/162ee48e1c34b2a2cd797395353f19a7aca21aa2/base/math.jl#L799-L804>

which I think would be much, MUCH more readable with something like this:

```julia
# Pythagoras - a² + b² = c², then sqrt(c²)
hypotenuse = sqrt(muladd(abs_x, abs_x, abs_y*abs_y))

# This branch is correctly rounded but requires a native hardware fma.
if Core.Intrinsics.have_fma(typeof(hypotenuse))
    hypotenuse² = hypotenuse * hypotenuse
    abs_x² = abs_x * abs_x
    # error per side
    error_y = fma(-abs_y, abs_y, hypotenuse² - abs_x²) 
    error_hypotenuse = fma(hypotenuse, hypotenuse, -hypotenuse²)
    error_x = fma(abs_x, abs_x, -abs_x²)
    
    # correct the error
    # /2 due to each side being use twice, /hypotenuse due to the errors being relative to that 
    hypotenuse -= (error_y + error_hypotenuse - error_x)/(2*hypotenuse)
[...]

```

Having even a slightly longer names makes “clever” oneliners much less enticing to write, precisely because the line would end up taking up waay too much space. To be clear, I’m not 100% certain that I’ve refactored the code correctly, in part because reading the original gives no clear signal whatsoever what exactly any one of the intermediate results even calculates - which is the entire point we’re discussing here, to save people that either haven’t touched the code in a long time or just want to understand how it works in general some time when understanding it.

> [@DNF](#):
>
> Meaningful descriptive names should be in the code that _calls_ these functions, like `max(number_of_cats, number_of_dogs)`, ie. In the application code, not the library code.

I’m not talking about trivial oneliner library functions like `max`, and I don’t think anyone here is. I’m talking about some longer functions that are rife with `x`, `y`, `i`, `j`, `k`, `tmp` (WHAT is stored here temporarily?!).

We’re not just writing code to have the computer be as fast as possible, we’re also writing code for _others to read_, which I’d argue is, generally speaking, the most important factor when writing code. ESPECIALLY writing scientific code that is supposed to be easily understood, reproducible and easy to check for subtle mistakes by people other than the original author (who possibly are used to different conventions than the author…!).

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 25, 2022, 6:21pm UTC](https://discourse.julialang.org/t/digression-on-short-variable-names/91859/34 "2022-12-25T18:21:52Z")

</div>

> [@Sukera](#):
>
> You’re conflating “descriptive names are better” with “longer names are better”.

Not really, since I am very much criticizing _long_ names, not _descriptive_ names. (Though, I will admit to disliking descriptive names in cases where I think abstractness is better.)

Descriptive names are good. Long names are bad. That’s the trade-off, and the ideal answer is “conciseness”, hard as it might be.

[Previous page](https://discourse.julialang.org/t/digression-on-short-variable-names/91859.md?page=1)
