# Coding pattern for "min with side effects"

Many algorithms require computing `min(a,b)` and then executing some side effects depending on whether `a < b`. I’m struggling to come up with a good coding pattern for this type of logic.

The problem is best described by means of an example. Consider the following function for finding the smallest element in a vector `v`.

``````function minimum(v)
@assert !isempty(v)
x = v
for i = 2:length(v)
x = min(x, v[i])
end
return x
end
``````

If in addition to finding the minimum we also want to find the index of the minimum, then this function has to be changed as follows.

``````function findmin(v)
@assert !isempty(v)
x = v
j = 1
for i = 2:length(v)
if v[i] < x
x = v[i]
j = i
end
end
return x,j
end
``````

My beef with this type of code is that `v[i]` occurs both in the `if` statement and the line just after the `if` statement. I believe this inefficient (repeated index lookups can’t be optimised by the compiler AFAIK), and if the statement is more complicated than simply `v[i]`, then repeating the same complicated statement is a likely source of typos. Of course, these problems could be avoided by introducing a temporary variable, but temporaries are often ugly and make the code harder to read. So my question is, is there a way to write this logic without repeating `v[i]` and without introducing a temporary?

I’m aware that this is a very OCD type of question and that in the real world you would just do whatever works and move on. But I thought it could be instructive and fun to hear what other people think about this.

you have a few options but no clear winner if you only use `v[i]` twice…

1. make `vi = v[i]` immediate after `for i = 2:length(v)`.
2. use `enumerate`
2 Likes
``````function minimum(v)
m = Inf
i = 0
for (k, e) in enumerate(v)
if e ≥ m
continue
end
m = e
i = k
end
return (m, i)
end
``````

This saves you linear indexing at all, which is good if `v` is, for instance, not an array.

1 Like

This is not, however, guaranteed to be typestable (if the array is empty or all its elements are `>Inf` it will return a `Float64`, otherwise `eltype(v)`). Possibly a better way is to use

``````((i, m), it) = Iterators.peel(enumerate(v)) # not sure this nested destructuring works
for (k, e) in it
...
``````