Print

Print


On 9/24/15, Andrew Parsloe <[log in to unmask]> wrote:
> On 25/09/2015 5:14 a.m., Bruno Le Floch wrote:
>> On 9/23/15, Joseph Wright <[log in to unmask]> wrote:
>>> On 23/09/2015 02:49, Andrew Parsloe wrote:
>>>> \int_eval:n { - (1+2) }
>>>>
>>>> gives a "Missing number, treated as zero" message. So does \int_eval:n
>>>> {
>>>> + (1+2) }.
>> As Joseph says, this is due to the syntax of eTeX's primitive \numexpr.
>> Let me answer Will's suggestion of adding "0+" to the start of every
>> \int_eval:n.  That won't cover cases such as \int_eval:n { 1 + ( - (2
>> + 3) + 4) * 5 } where the "-(" construction (with no left-hand
>> operand) appears in the middle of an expression.
>>
>>>> But
>>>>
>>>> \int_eval:n { 0 - (1+2) }
>>>>
>>>> evaluates correctly. If + ( or - ( are the first members of an integer
>>>> argument, an error results; if they are not the first members, they are
>>>> accepted by \int_eval:n etc. I don't know that this is a bug as such
>>>> but
>>>> it certainly feels to me like an untidiness in the l3int interface. It
>>>> means that the order in which component parts of an expression are
>>>> presented to \int_eval:n matters, even though in an arithmetical sense,
>>>> they evaluate to the same number.
>> I agree that it would be better to have a nicer interface, and it is
>> very close to being a bug, but one in eTeX rather than LaTeX3, and not
>> fixable on our end.
>>
>>>> I query too whether an expression like
>>>>
>>>> \int_eval:n { 3(1+2) }
>>>>
>>>> should "evaluate" to 3(1+2), rather than 9, without showing an error.
>> That we could catch.  Heiko once suggested that we include parentheses
>> in our expressions, defining \int_eval:n {#1} as \tex_the:D
>> \etex_numexpr:D (#1) \tex_relax:D .  That would at least produce an
>> error when an expression is terminated early (say because of a ^ or
>> juxtaposition, or space in the middle of a number, etc).
>>
>> Of course that wouldn't help with unbalanced parentheses.
>>
>>>> (Alternatively, I find myself wondering what would be entailed to
>>>> harmonize the integer interface with the fp one (which has no problem
>>>> with these expressions)? Then one could choose whether to evaluate an
>>>> expression involving integral numerals  in l3fp or l3int without having
>>>> to change the expression, as one does at present. For instance, if the
>>>> expression involves an exponent, use l3fp; if not use l3int. This
>>>> choice
>>>> becomes more complicated when the expression itself needs to be
>>>> changed.)
>>>>
>>>> Andrew
>>> The different 'behind the scenes' here is that \int_eval:n is just the
>>> engine \numexpr primitive in a macro wrapper, but \fp_eval:n is
>>> implemented entirely in macros (as there is no floating-point
>>> primitive). Thus while we can alter the parser for fp work, we can't for
>>> int work, or rather not without significant changes. In particular,
>>> there would be a performance implication in parsing int input and doing
>>> the calculations 'by hand'. I suspect int parsing would be easier than
>>> for fp expressions, but even so this looks like a significant effort.
>> I would expect at least a 10x slow-down (rough estimate, I can look
>> into this more if requested).
>>
>>> As Will has commented, we might manage at low cost to avoid the bracket
>>> issue, but allowing \int_eval:n { 3(1+2) } would be rather more tricky.
>>> Indeed, I'd probably say we shouldn't: here I think requiring an
>>> explicit "*" is the right approach. Bruno is best-placed to comment on
>>> the fp implementation here.
>> I actually fear that I probably made a mistake when allowing
>> juxtaposition of this kind in l3fp.  Maybe it is not too late to
>> change.  We never really had time for a discussion of the syntax of
>> l3fp, which I cooked up myself with no outside input.
>>
>>> The reason I'm wary of making any changes, quite apart from effort both
>>> in terms of the team and in terms of TeX when using expressions, is that
>>> life gets more complex when you look at dim/skip/muskip cases. There,
>>> the underlying primitives have particular requirements, thus
>>>
>>>      \dim_eval:n { 4pt * 3 }
>>>
>>> is valid but
>>>
>>>     \dim_eval:n { 3 * 4pt }
>>>
>>> is not. I really don't think we want to implement all of the necessary
>>> parsing for this by hand, so saying that we follow the underlying
>>> primitive requirements is a position I think we are best with in
>>> general.
>> Yeah, getting this \dim_eval:n to work would require pretty much as
>> much work as fp parsing.  The code is mostly available but I would
>> expect something like a 100x slow down.
>>
>>> BTW, as far as I know there is nothing that would be valid for an int
>>> expr. that would fail for l3fp.
>> That is true, so any int expression can be turned into an fp one if
>> you realize that you want to use ^ for instance.  The reverse is not
>> true.
>>
>> Bruno
>>
> Thank you all for your replies, which fill in the background for me. I
> have been using l3fp intensively for a while, but have only recently
> started using l3int in earnest, at least in part for the presumed
> performance gain, when these particular issues have arisen. (Looking at
> those references to 10x slow down, or 100x slow down, might there be
> room in l3kernel or l3packages for an l3timer module?)
>
> Andrew

I typically use l3benchmark, which is not on CTAN but can be found in
the l3trial directory (see
https://github.com/latex3/latex3/tree/master/l3trial/l3benchmark ).  I
never got back to working on it, but there are quite a few
improvements to be had.  Some day, perhaps, I'll have time and it can
be moved to l3experimental.

Bruno