Live data from Hacker News

Math.min(Math.max(num, min), max)

twitter.com

251–260 of 291 posts

Re: Math.min(Math.max(num, min), max)

#251

Fun seeing that pretty much everyone else finds that idiom confusing too. Half-serious, over breakfast: (case [(> n min) ( (Side note: Clojure's `>` and ` n min)` into "if n is greater than min" takes some work for me, still, after more than a year.)

> (Side note: Clojure's `>` and `I felt the same for awhile but now I just mentally put the operator between the operands, so (> 3 2) is the same as 3 > 2.

Re: Math.min(Math.max(num, min), max)

#252
post #75
post #28

I find that the fact that the functions min and max have the same name as the variables min and max increases cognitive load which makes it harder to think about it. I find the following easier to read : Math.min(Math.max(num, lower_bound), upper_bound)

Easy to remember, but may take some time to grasp: Arrays.sort( {lower_bound, num, upper_bound} )[1]; Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) (You can’t reduce it to the min/max call because it also works if you accidentally pass a lower bound that’s larger than the upper bound. Worst-case, the above takes 3 comparisons, unless at least two of the inputs are constants)

ohh this is clever!

Re: Math.min(Math.max(num, min), max)

#253

Here's clamp in idiomatic Elixir (using multi-clause functions and guards): def clamp(min, _max, n) when n max, do: max def clamp(_min, _max, n), do: n

An Elixir convention I've seen is to put the thing you're operating on first, so that you can compose functions using the `|>` operator, which places the previous expression as the first argument of the function to the right. Maybe something like this? defmodule Compare do def clamp(number, minimum, maximum) do number |> max(minimum) |> min(maximum) end end import Compare clamp(5, 1, 10) # 5 clamp(1, 5, 10) # 5 clamp…

> It makes the most "important" argument of the function the first thing you read in function signatures

Doesn't that make writing functions that can use partial application harder? e.g. If I was writing clamp i would want the signature to be

     (defn clamp [min max n] ,,,)
Then I can do:

    (map (partial clamp 1 11) [-14 2 5 8 11 15 18])
I know when I use Clojures threading macros I use thread last way more than any of the others. My next most common would be piping it into arbitrary locations, e.g.:

    ; pipe into an arbitrary spot (specified here as o)
    (as-> (range 1 10) o
          (map inc o)
          (filter even? o)
          (reduce + o))

I rarely use thread-first.

Re: Math.min(Math.max(num, min), max)

#255
post #165

Earlier quoted context omitted.

It depends on what space you're working on (e.g. the https://en.wikipedia.org/wiki/Extended_real_number_line define an order on the real field union {-∞, +∞}).

Yes, but in that context, ∞ is a number. We often interpret "NaN" to mean "infinity," but it only means "not a number." Maybe I'm being pedantic, but if we want a token representing infinity as a number, it ought not be called "not a number."

IEEE754 has both infinity and NaN. They are different. NaN is always the result of an invalid operation, such as trying to take the square root of a negative number. Infinity is for when the result would be valid, but is too large in magnitude to represent. There is both positive and negative infinity.

Re: Math.min(Math.max(num, min), max)

#256
post #132

Kotlin provides pretty nice syntax sugar for that: num.coerceIn(min..max) That's it. This human reader finds it considerably more readable. It also has coerceAtLeast and coerceAtMost

Does kotlinc optimize away inline ranges like that, or does this result in a range object being constructed and discarded?

I haven't heard of any instances of Kotlin itself optimizing these things away, but the JVM may be able to do so during its various JIT passes. It's definitely not something you can necessarily rely on, though.

Luckily, these convenience methods are usually implemented as inline extension functions, so the whole thing will get inlined into the calling method, making JIT optimization more likely.

Re: Math.min(Math.max(num, min), max)

#257
In APL:

    lower⌈ upper⌊ numbers
See a stream of random numbers flowing from right to left. See the higher ones being pushed down ⌊ to the upper bound, and the lower ones being pushed up ⌈ to the lower bound, and the middle ones flowing through both guards unchanged.

Re: Math.min(Math.max(num, min), max)

#260
post #75

Earlier quoted context omitted.

Easy to remember, but may take some time to grasp: Arrays.sort( {lower_bound, num, upper_bound} )[1]; Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) (You can’t reduce it to the min/max call because it also works if you accidentally pass a lower bound that’s larger than the upper bound. Worst-case, the above takes 3 comparisons, unless at least two of the inputs are constants)

> Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) I did exactly this for my PhD! https://chrisseaton.com/phd/

Very noble, but I'm assuming (hoping) the technique will be more generally applicable than Ruby?
Post reply on HN