  lua-l archive

• Subject: Min and Max
• From: Rici Lake <lua@...>
• Date: Thu, 25 Aug 2005 11:15:41 -0500

On 18-Aug-05, at 4:06 AM, Philippe Lhoste wrote:

Rici Lake wrote:
For what it's worth, I still think min and max should be primitives rather than part of the math package. They are perfectly well defined for anything for which < or <= is a total-ordering, or something close to a total ordering. 

I don't disagree with you, but what are the use-cases? I mean, are they that much used that they need a special treatment over other math/string functions?

I don't use min and max much in my programs, that's why I ask. Of course, I don't much pow/^ either... But perhaps I am either missing opportunities, or I am just not in the "right" programming domain.

I'm not making a serious pitch for min and max operators here; just trying to illustrate a use case.

The recent "Lua uses" posting about DogLua lead me back to Øyvind Kolås' interesting Lua-based Gimp plug-in, gluas <http://pippin.gimp.org/image_processing/index.html>.

gluas allows you to write Gimp image filters in Lua; a number of examples can be found in the text. Many of them are crying out for min and max operators; here is just one example (taken from Chapter 7, <http://pippin.gimp.org/image_processing/chapter- automaticadjustments.html>). This function returns the minimum and maximum grayscale value in an image (but you'll find many more instances of this idiom in the examples):

function get_min_max()
min, max = 1000, -1000
for y=0, height-1 do
for x=0, width-1 do
value = get_value(x,y)
if value<min then
min = value
end
if value>max then
max = value
end
end
end
return min,max
end

The author uses an if statement to do the min/max; the style is consistent in all of his scripts, presumably because:

min, max = math.min(min, value), math.max(max, value)

would be even slower.

I personally find the following more attractive:

function get_min_max()
local rmin, rmax = 1000, -1000
for y = 0, height - 1 do
for x = 0, width - 1 do
local value = get_value(x, y)
rmin = rmin min value
rmax = rmax max value
end
end
return rmin, rmax
end

It's not going to be lot faster to execute (well, it will but only because I made `value' a
local) but it seems clearer to me. Maybe that's just me.

However, this doesn't capture another very common idiom: if we actually wanted to know which <x,y> co-ordinates were associated with the min and the max, we'd still need the `if' statement. Probably more than half of Dr. Kolås's examples are of this form, rather than simple min and max computations.

By the way, the starting values 1000, -1000 are fine in this example because get_value returns a number between 0.0 and 1.0. But I would actually opt for a definition of `min' and `max' where:
nil min x ==> x
nil max x ==> x
for any x. This makes reductions a little easier to write, and could easily be achieved in the 5.1 framework, I think, by providing __min and __max metamethods for `nil'.