Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Pete Dietl
> This really annoys me and keeps me on the fence about gnulib, and
> prevents me from completely switching (for example, moving to modern
> glob/fnmatch).  I've only pulled in some relatively simple elements so
> far.
>
> So... I'm not sure which way to fall on that.

Apparently gnulib requires
> at least a freestanding C99 compiler
which is responsible for providing ``.
So we can just use int64_t.



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Pete Dietl
> I believe the form being considered is:
>
>   $(math OPERATOR,LIST)

I am still partial to `$(math ...)`
with only one argument.

> The only one I'm not sure about is overflow.  That will need some
> thought.  Gnulib contains a comprehensive set of macros to deal with
> overflow, in various ways.

My initial thought was to simply leave it implementation defined, like
C does for signed integers.



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Paul Smith
On Mon, 2020-05-25 at 13:28 -0500, Pete Dietl wrote:
> Question about 64-bit, what happens when compiling make for a 32-bit
> system? I don’t think c90 has `stdint.h`... maybe there’s something
> in gnulib. Anyway, would we want to support 64 bit integers even on
> 32-bit platforms?

32bit platforms can support 64bit integers.  I see no reason to suggest
we shouldn't.  I would prefer to not make this platform dependent
because that will lead to all sorts of portability issues.

Regarding C99: it turns out that gnulib already requires C99 (at least
parts of it) and since we started incorporating gnulib in GNU make 4.3,
we have sort of "backed into" requiring it as well.

I haven't made an official statement on this because I haven't thought
clearly enough about it yet (just discovered it recently).


Gnulib frustrates me because although it purports to solve portability
issues, and does so admirably between different variations of POSIX
systems, it actually _exacerbates_ portability issues to non-POSIX
systems.  In order to build gnulib-enabled software you have to have a
POSIX portability layer (for example, a POSIX shell and set of POSIX
shell utilities), which is a big ask.

This really annoys me and keeps me on the fence about gnulib, and
prevents me from completely switching (for example, moving to modern
glob/fnmatch).  I've only pulled in some relatively simple elements so
far.

So... I'm not sure which way to fall on that.




Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Paul Smith
On Mon, 2020-05-25 at 12:07 -0400, Sam Kendall wrote:
> I'd like to raise some questions that I think any proposal ought to
> answer. I'll assume a straw man proposal: there's one function, and
> it takes one of the following forms:
> 
> $(math OPERATOR,VALUE1,VALUE2)
> $(math OPERATOR,VALUE1)

I believe the form being considered is:

  $(math OPERATOR,LIST)

where LIST expands to a space-separated list of integer values.  The
operator is applied to the entire list, from left to right.

> A binary operator (first form) is one of + - * and /. The only unary
> operator is "-".

Negation (unary "-") is definitely a problem since unfortunately
standard math uses the same symbol for negation and subtraction.  I
don't want to use the OPERATOR (in the above form) to handle it,
because I don't want to have $(math -,2) behave differently from $(math
-,2 0): it's too bizarre and confusing.

I'd prefer to see it allowed in the parsing of LIST, and handled there.
This absolutely needs thought and needs to be in the proposal.

> There might also be equality and relational operators. A value is an
> optional "-" followed by one or more decimal digits. It represents a
> 64-bit signed integer.

If negation is handled during LIST parsing then we need to allow
multiple initial "-", so you can say "-$(foo)" where $(foo) is -5.

This does mean that we wouldn't support "--"/"++" operators.

For all your other questions I agree the proposal needs to address
them.  I agree with you that all invalid operations should yield fatal
errors.

The only one I'm not sure about is overflow.  That will need some
thought.  Gnulib contains a comprehensive set of macros to deal with
overflow, in various ways.




Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Pete Dietl
`long long` was not introduced until c99, neither was `stdint.h`, but
perhaps gnulib can help us out here.

On Mon, May 25, 2020 at 3:44 PM Pete Dietl  wrote:
>
> > I was not even considering specifying the base of the the resulting
> > expansion.  I was assuming it would always be base 10.  I don't have
> > any good way to specify the output form.
> >
> > I was only considering the parsing of input (constant) values: whether
> > we wanted to support 0xfff, 0o777, 0b111 as well as base 10.  I don't
> > want to support "traditional" octal values that start with plain 0... I
> > believe that's always been a bad idea and it's especially bad in the
> > context of makefiles where values are all strings right up until the
> > moment they're parsed.
>
> I definitely agree with 0x 0o 0b.
>
> As for converting between bases, that could always be a separate
> function like `$(convert-base number,radix)` where radix is one of: 2,
> 8, 10, or 16



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Pete Dietl
> I was not even considering specifying the base of the the resulting
> expansion.  I was assuming it would always be base 10.  I don't have
> any good way to specify the output form.
>
> I was only considering the parsing of input (constant) values: whether
> we wanted to support 0xfff, 0o777, 0b111 as well as base 10.  I don't
> want to support "traditional" octal values that start with plain 0... I
> believe that's always been a bad idea and it's especially bad in the
> context of makefiles where values are all strings right up until the
> moment they're parsed.

I definitely agree with 0x 0o 0b.

As for converting between bases, that could always be a separate
function like `$(convert-base number,radix)` where radix is one of: 2,
8, 10, or 16



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Paul Smith
On Mon, 2020-05-25 at 10:10 +, Edward Welbourne wrote:
> > > Mult-base support: should we support only base 10 integer
> > > constants in
> > > expressions, or also hex/octal constants?
> > I vote for decimal, hex, and binary.
> > Octal if you really want it.
> 
> A case for octal and bitwise and/or is that they're what you need to
> manipulate chmod permissions.  Of course, that'd also require being
> able to *expand* the resulting number as octal ...

I was not even considering specifying the base of the the resulting
expansion.  I was assuming it would always be base 10.  I don't have
any good way to specify the output form.

I was only considering the parsing of input (constant) values: whether
we wanted to support 0xfff, 0o777, 0b111 as well as base 10.  I don't
want to support "traditional" octal values that start with plain 0... I
believe that's always been a bad idea and it's especially bad in the
context of makefiles where values are all strings right up until the
moment they're parsed.

> I would tend towards defining a
> 
>   $(compare before, after, rise, same, fall)
> 
> which evaluates to rise if before < after, same if before == after
> and fall if before > after.

That's interesting but honestly I'm not sure I see the advantage of
doing something like this, over simply supporting the standard
operators with a normal conditional function.  It will certainly be
much more familiar to people.  I guess it's helpful in the less common
situation where you want to do three different things for <, ==, and >,
but it's more annoying for the more likely scenario where you want to
use <= or >=... you have to write the result twice.




Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Tim Murphy
On Mon, 25 May 2020 at 18:34, Pete Dietl  wrote:

> Question about 64-bit, what happens when compiling make for a 32-bit
> system? I don’t think c90 has `stdint.h`... maybe there’s something in
> gnulib. Anyway, would we want to support 64 bit integers even on 32-bit
> platforms?
>
> If at all possible, I think.

Tim


Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Pete Dietl
Question about 64-bit, what happens when compiling make for a 32-bit
system? I don’t think c90 has `stdint.h`... maybe there’s something in
gnulib. Anyway, would we want to support 64 bit integers even on 32-bit
platforms?


Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Edward Welbourne
Sam Kendall (25 May 2020 18:07) observed:
> If you have relational or equality operators, what does the boolean
> result look like? If the result is 1 for true and 0 for false, then
> you get a bad surprise: $(if $(math =,5,6),yes) expands to yes. If the
> answer is some nonempty string for true and empty string for false,
> then you can't do math on the result because it isn't a number. I
> think this has come up before in the discussion.

Definitely empty/non-empty for false and true; if you want to do
arithmetic, use an explicit $(if condition, 1, 0) expression rather than
taking for granted that true is 1 and false is 0 (an arbitrary
convention that happens to be widespread (and useful), not an inevitable
universal truth).

Eddy.



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Sam Kendall
I'd like to raise some questions that I think any proposal ought to answer.
I'll assume a straw man proposal: there's one function, and it takes one of
the following forms:

$(math OPERATOR,VALUE1,VALUE2)
$(math OPERATOR,VALUE1)

A binary operator (first form) is one of + - * and /. The only unary
operator is "-". There might also be equality and relational operators. A
value is an optional "-" followed by one or more decimal digits. It
represents a 64-bit signed integer.

I'd like to see a proposal that's as simple as possible and that includes
use cases. I also like fatal errors in dubious cases, because you can
always relax such a rule later and still be backward compatible.

---

Can an input include whitespace? If so, where?

What happens with an unparseable input such as empty string, foo, or 0.5?
Precedent suggests a fatal error. For example, any of those strings as the
first arg to $(word ) produces a fatal error.

What happens with an out-of-range input such as 9223372036854775808?

What happens upon overflow, e.g., $(math +,9223372036854775807,1)?

How do you input the most negative integer? In other words, is
-9223372036854775808 a valid value?

What happens upon division by zero?

What are the rounding rules for division?

If you have relational or equality operators, what does the boolean result
look like? If the result is 1 for true and 0 for false, then you get a bad
surprise: $(if $(math =,5,6),yes) expands to yes. If the answer is some
nonempty string for true and empty string for false, then you can't do math
on the result because it isn't a number. I think this has come up before in
the discussion.

--Sam


Re: Tail call elimination

2020-05-25 Thread Edward Welbourne
Pete Dietl (22 May 2020 09:18)
> As for a name for $(cond), we could call it
> $(alu ...)
> And put arithmetic and logical operations in it :)

Amusing as this is, I don't think it's a good name !

> I don’t like using $(cond)
> Because because I sort of want to option to implement cond like in Scheme.

There are already $(if, test, yes, no) evaluating to yes if test is a
non-empty string, no if it is empty; $(or conds,...) evaluating to the
first non-empty condition, empty if all are empty; and $(and conds...)
evaluating to the first empty condition, else the last parameter.  So no
need for cond.  I would tend towards defining a

  $(compare before, after, rise, same, fall)

which evaluates to rise if before < after, same if before == after and
fall if before > after.  That packs all of the <, <=, >, >=, == and !=
tests into one; when you want the cases where two come out the same,

  $(if $(compare $(a), $(b),,y,y),ge,lt)

will evaluate to ge if $(a) >= $(b), else to lt, so that repeating y
saves repeating a potentially long ge text.  Obvious similar usage can
handle the other "use same value in two cases" options.

On the need for a named function: note that $*, $(*), $(*D), $(*F) and
likewise for $+ all have meanings already, so overloading them to also
be the multiplication and addition operators sounds imprudent, even if
it is possible.  I think $(math op, args) makes sense, so as to have
only one entry-point in both code and documentation.

I think each operator should initialize a result to its first argument
then use the operator to combine the current result with each successive
argument; so $(math *, 7) evaluates to 7, $(math /, $(size) 1024 1024)
turns a size in bytes into a size in MiB and $(math -, $(total) $(subs))
gives the residue when each sub has been subtracted from a total.
But then I've been influenced by Lisp, so I would think that.

I'm sure there's a quote somewhere about every language eventually
growing an implementation of Lisp.  Perhaps it's best to stop short of
actually dong that fully, though ...

Eddy.



Re: math expressions (was: Re: Tail call elimination)

2020-05-25 Thread Edward Welbourne
>>> Bit Manipulation:
>>> --
>>> * and
>>> * or
>>> * xor
>>> * complement
>>> * left shift
>>> * right shift
>>
>> Maybe.  I have a hard time coming up with uses for these, other than
>> possibly the shift operators (but multiplication/division can be used
>> instead).

Pete Dietl (20 May 2020 18:21)
> Yeah I was thinking the use case could be a little obscure,
> but maybe for some sort of version parsing where bits
> are strangely encoded.
>
> But again I'd say that it's pretty easy to implement.


>> Again, the questions in my email yesterday need to be addressed.

> I totally missed that email somehow. I'll address it in another email.

>> Mult-base support: should we support only base 10 integer constants in
>> expressions, or also hex/octal constants?

> I vote for decimal, hex, and binary.
> Octal if you really want it.

A case for octal and bitwise and/or is that they're what you need to
manipulate chmod permissions.  Of course, that'd also require being able
to *expand* the resulting number as octal ...

Eddy.