bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] compare function


From: Edward Welbourne
Subject: Re: [PATCH 2/2] compare function
Date: Tue, 9 Jun 2020 08:53:25 +0000

Jouke Witteveen (8 June 2020 22:20)
> This is an implementation of a $(compare) function as proposed by
> Edward Welbourne.

Yay ;^>
Looks promising in general.
As ever, review consists mostly of criticism, so let me just say I
approve of the general plan, before I start in on that ...

> It differs from his original proposal in that it behaves differently
> when given 4 or 5 arguments. In short, it's signature is
>
>  $(compare lhs,rhs,less-than[,greater-or-equal])
>  $(compare lhs,rhs,less-than,equal,greater-than)
>
> Documentation and a proper commit message is still missing, but this
> proof-of-concept shows that it is in fact pretty simple to implement.

Simplicity of implementation was not far from my thoughts when I
proposed it; it is also easy to understand ;^>

I note that your implementation only supports numeric lhs and rhs.
Might it be worth falling back, if either of them isn't numeric, to
doing a strcmp() comparison instead ?  Possibly after stripping leading
space from each.  There is value in lexical comparison, too, after all.

I am not convinced it is good to have $5 default to $4, which is what
you've done in effect.  IIRC, most of make's existing functions treat
missing argument as empty; if my memory is correct, it would then be
more consistent to have

  $(compare $lhs,$rhs,$less[,$same[,$more]])

with each of $same and $more empty if omitted.  (I make $less
non-optional because it's perverse to do a comparison and return false
regardless; but it could be optional, "for symmetry", if you like;
albeit that might lead to a temptation to make it default to a non-empty
string, so that $(compare $lhs,$rhs) serves as $lhs < $rhs as a
conditional; but this would violate the very symmetry that motivated
making $less optional.)

As I noted before, the cases where two branches want the same verbose
value can readily enough be handled by using $(if ...) on a condition
using $(compare ...) with two of its output values empty and the other
some non-empty string (due to Lisp influence, I'd use t), or vice versa;
or you could use $(let ...) to put the repeated value in a local
variable that you use in both intended branches, when this more verbose
form proves more readable (as it sometimes shall).

> Additionally, I feel that the interface is clean. In that way, it
> differs from the various proposals for integer operations. After
> thinking about them some more, I came to dislike all current proposals
> because of the unintuitive behavior of subtraction and division.

I think this depends a lot on your intuitions, which can be trained.  I
find $(math $op, $a $b ... $z) = $a $op $b $op ... $op $z to be
entirely intuitive, but then I've been exposed to many ways of doing
algebra and perpetrated some related to this.  (I would describe this as
a "bulk action", for reference; see
  http://www.chaos.org.uk/~eddy/maths/found/bulk.xhtml
for a more formal treatment of the associative (i.e. + and * but not -
and /) case.  It generalises sum and product.  I think some folk call
these monads.  However, the fact that I write stuff like that may fairly
be considered grounds for doubting my intuitions are shared by many
others.)

> We should only support integer mathematics, so division is always
> going to be integer division, which suggests that we need a modulus
> operator as well. Moreover, 1/$x will not be supported, so we can't
> implement the same behavior for $(math -,$x) as for $(math
> /,$x). While verbose, the only clean way I can think of is simply
> $(add $x,$y), $(subtract $x,$y), etc. All supporting precisely two
> arguments. Multi argument versions can be defined like
>
>  sum = $(let first rest,$1, \
>       $(if $(rest),$(add $(first),$(call sum,$(rest))), \
>                    $(first)))

which is surely somewhat expensive, since we're bouncing back and forth
between the make "interpreter" and the $(add ...) function over and over
again, instead of just taking one trip via $(math ...).  Not that performance
is likely to be a deal-breaker, here.

        Eddy.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]