Discussion:
Juxtaposition in l3fp
aparsloe
2014-06-08 09:53:42 UTC
Permalink
Should l3fp use juxtaposition *at all* to indicate multiplication? I am
an enthusiast for l3fp. I am using it constantly (in LyX using LyX's
instant preview to evaluate formulas), but that has simply heightened my
unease about using juxtaposition to indicate multiplication,
particularly as part of a kernel package.

Most people using numbers have their mental reflexes shaped either by
mathematical usage or calculator or spreadsheet usage. The last two, to
my knowledge, don't allow juxtaposition. Multiplication must be
explicitly indicated with an asterisk.

Mathematical usage is variable and often irregular but there is a
certain core understanding. In a polynomial like 2x^3-5x^2-9 it is
universally understood that the cubing and squaring applies only to the
x, not the coefficients. In l3fp, however, because juxtaposition has the
highest precedence, the coefficients are "glued" to the x so that it is
2x that is cubed and 5x that is squared (e.g. on putting (2+3) for x).
Usually the answers from "normal" and l3fp evaluation will be
sufficiently different to alert one to the fact that something has gone
wrong, but occasionally they will be "in the same ball park" and may
lead to overlooking an error.

For instance scaling paper sizes or text blocks may lead one to seek the
length of the diagonal of a rectangle, say the initial one with sides
21cm and 29.7cm and a larger one with sides 1.2 times greater. What is
the larger diagonal? By similarity, it is 1.2 times the length of the
smaller diagonal. It is very easy to write 1.2(21^2+29.7^2)^.5 (with
1.2\times\sqrt{21^2+29.7^2} in mind), evaluate it with fp and get
39.85cm. This is wrong but not too obviously different from the correct
43.65cm.

Juxtaposition also produces conflicts with established practice
(calculators, spreadsheets) for function calls. Yes, sin2pi evaluates to
0 as does sin(2pi), but sin(2pi)(2pi) = 0.978... does not, so that a
function's argument is not delimited by parentheses, even when
parentheses are used. That also breaks a long-established practice and
seems like a source of error for the unwary.

I find myself now shunning juxtaposition and making a point of
explicitly indicating multiplication with an asterisk, even in cases
like 2*pi -- in other words making it a habit of mind precisely to avoid
these "traps for the unwary". I imagine the juxtapositional horse has
well and truly bolted, but I find myself wondering if it still might be
possible to graft a strict "calculator front end" onto l3fp to align its
operations with more familiar habits of mind?

Andrew Parsloe
Lars Hellström
2014-06-09 12:25:07 UTC
Permalink
Should l3fp use juxtaposition *at all* to indicate multiplication? I am an
enthusiast for l3fp. I am using it constantly (in LyX using LyX's instant
preview to evaluate formulas), but that has simply heightened my unease
about using juxtaposition to indicate multiplication, particularly as part
of a kernel package.
Syntactic sugar: may look like yum, but it can hurt you. :-)
Most people using numbers have their mental reflexes shaped either by
mathematical usage or calculator or spreadsheet usage. The last two, to my
knowledge, don't allow juxtaposition. Multiplication must be explicitly
indicated with an asterisk.
You conspicuously omit programming languages, which I would put as a
forerunner of spreadsheets (the less about said, the better), and probably
also of modern calculators that attempt to display formulae. So it probably
all boils down to "because that's how it was in FORTRAN" (which, if memory
serves, ignored spaces).

A data point of possible interest is MetaFont, which has some cases of
juxtaposition as a high priority operation (e.g. 2/3x means two thirds of
x). Since it's Knuth, it's probably very consistent, but not necessarily
intuitive.
Mathematical usage is variable and often irregular
Oh yes. One of the really big mistakes people make when trying to implement
mathematics is believing that the mathematical formula language is
consistent, just because it is precise. Juxtaposition can denote pretty much
*anything* (depending on context), and because juxtaposition is
multiplication, it follows that pretty much anything can be regarded as a
kind of multiplication. ;-)

Lars Hellström
Joseph Wright
2014-06-09 12:35:14 UTC
Permalink
Post by Lars Hellström
Should l3fp use juxtaposition *at all* to indicate multiplication? I am an
enthusiast for l3fp. I am using it constantly (in LyX using LyX's instant
preview to evaluate formulas), but that has simply heightened my unease
about using juxtaposition to indicate multiplication, particularly as part
of a kernel package.
Syntactic sugar: may look like yum, but it can hurt you. :-)
Most people using numbers have their mental reflexes shaped either by
mathematical usage or calculator or spreadsheet usage. The last two, to my
knowledge, don't allow juxtaposition. Multiplication must be explicitly
indicated with an asterisk.
You conspicuously omit programming languages, which I would put as a
forerunner of spreadsheets (the less about said, the better), and
probably also of modern calculators that attempt to display formulae. So
it probably all boils down to "because that's how it was in FORTRAN"
(which, if memory serves, ignored spaces).
A data point of possible interest is MetaFont, which has some cases of
juxtaposition as a high priority operation (e.g. 2/3x means two thirds
of x). Since it's Knuth, it's probably very consistent, but not
necessarily intuitive.
Mathematical usage is variable and often irregular
Oh yes. One of the really big mistakes people make when trying to
implement mathematics is believing that the mathematical formula
language is consistent, just because it is precise. Juxtaposition can
denote pretty much *anything* (depending on context), and because
juxtaposition is multiplication, it follows that pretty much anything
can be regarded as a kind of multiplication. ;-)
Lars Hellström
I guess Bruno can say more, but I suspect that requiring explicit "*"
for multiplication might have a benefit in terms of code complexity (no
need to allow for other cases). An obvious question for me is would such
a position lead to problematic cases? The comparison with MetaFont is
probably a useful one in this regard.
--
Joseph Wright
Bruno Le Floch
2014-07-10 23:20:48 UTC
Permalink
Hello list,

Sorry for the >1 month delay. This is a followup to the thread asking
whether letting juxtaposition denote multiplication was a good idea.
I think it was, but I made a big mistake in making juxtaposition be
multiplication with a _different precedence_ than the asterisk.
Post by Joseph Wright
Post by Lars Hellström
A data point of possible interest is MetaFont, which has some cases of
juxtaposition as a high priority operation (e.g. 2/3x means two thirds
of x). Since it's Knuth, it's probably very consistent, but not
necessarily intuitive.
I guess Bruno can say more, but I suspect that requiring explicit "*"
for multiplication might have a benefit in terms of code complexity (no
need to allow for other cases). An obvious question for me is would such
a position lead to problematic cases? The comparison with MetaFont is
probably a useful one in this regard.
From reading (short) old discussions on when I decided to allow
juxtaposition, MetaFont was indeed an inspiration for making
juxtaposition bind very tightly. Another inspiration was pgfmath,
which allows juxtaposition for dimensions only, and treats a number
and its dimension as a single operand for any operation:

\input pgfmath
\pgfmathparse{.25pc^2}
\show\pgfmathresult % gives (.25*12pt)^2 = 9.0

In l3fp, I pushed the idea to its extreme, allowing juxtaposition for
things other than units, and I kept the precedence as being the
tightest possible.

As Lars rightfully says it's "consistent, but not necessarily
intuitive". Andrew has given several cases where my choice leads to a
terrible behaviour for l3fp, and there is basically no case where the
current behaviour is better (well, there was one abusive one: with
this rule, exp.5ln(...) computes the square root, but now that is not
needed).

I'm keen on leaving juxtaposition = multiplication, because that
allows to use dimensionful numbers directly inside fp expressions (pt,
in, ... are defined as floating point constants). I believe that we
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.

Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?

Best regards,
Bruno
Joseph Wright
2014-07-11 06:39:02 UTC
Permalink
Post by Bruno Le Floch
I'm keen on leaving juxtaposition = multiplication, because that
allows to use dimensionful numbers directly inside fp expressions (pt,
in, ... are defined as floating point constants). I believe that we
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow

2x + 1
2pt + 3cm

but with

2x^2 + 2 = 2*(x^2) + 2

so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
--
Joseph Wright
Bruno Le Floch
2014-07-11 16:23:06 UTC
Permalink
Post by Joseph Wright
Post by Bruno Le Floch
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow
2x + 1
2pt + 3cm
but with
2x^2 + 2 = 2*(x^2) + 2
so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
Yes you did. Cf my other email: how should the change happen?

Regards,
Bruno
Joseph Wright
2014-07-11 16:38:55 UTC
Permalink
Post by Bruno Le Floch
Post by Joseph Wright
Post by Bruno Le Floch
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow
2x + 1
2pt + 3cm
but with
2x^2 + 2 = 2*(x^2) + 2
so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
Yes you did. Cf my other email: how should the change happen?
As I said there, with a 'breaking' change (which sometimes simply can't
be avoided) all we can do is warn that there is one. Write the code and
test properly and I'll worry about the release announcement :-)
--
Joseph Wright
aparsloe
2014-07-12 02:02:25 UTC
Permalink
Post by Joseph Wright
Post by Bruno Le Floch
Post by Joseph Wright
Post by Bruno Le Floch
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow
2x + 1
2pt + 3cm
but with
2x^2 + 2 = 2*(x^2) + 2
so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
Yes you did. Cf my other email: how should the change happen?
As I said there, with a 'breaking' change (which sometimes simply can't
be avoided) all we can do is warn that there is one. Write the code and
test properly and I'll worry about the release announcement :-)
--
Joseph Wright
I'm swimming away out of my depth here, but I wonder if you need to
break anything?

My original email on juxtaposition was prompted when I "stubbed my toe"
on a case where the rigorous application of juxtaposition and its
precedence level led to a very unintuitive outcome. Once I had
re-established equilibrium, I thought to myself: OK, that is how l3fp
does things. Juxtaposition at the highest precedence level is applied
rigorously (with perhaps one exception). I can adjust my code. The user
doesn't need to know about what is happening in l3fp. It is after all
part of l3kernel, part of the engine.

I concluded that email by wondering if it might be possible to graft a
more intuitive front end onto l3fp -- call it l3calc, say. By way of
analogy, there is l3keys in l3kernel and l3keys2e in l3packages. Have
you considered such an option? l3calc would spend most of its time
putting parentheses around terms and asterisks between them. But nothing
would be broken, as a change in precedence level in l3fp will entail.
The "hairy-chested" could continue to use l3fp; less macho types might
prefer the more intuitive interface of l3calc.

Andrew
Bruno Le Floch
2014-07-12 03:13:02 UTC
Permalink
Post by aparsloe
Post by Joseph Wright
Post by Bruno Le Floch
Post by Joseph Wright
Post by Bruno Le Floch
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow
2x + 1
2pt + 3cm
but with
2x^2 + 2 = 2*(x^2) + 2
so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
Yes you did. Cf my other email: how should the change happen?
As I said there, with a 'breaking' change (which sometimes simply can't
be avoided) all we can do is warn that there is one. Write the code and
test properly and I'll worry about the release announcement :-)
--
Joseph Wright
I'm swimming away out of my depth here, but I wonder if you need to
break anything?
My original email on juxtaposition was prompted when I "stubbed my toe"
on a case where the rigorous application of juxtaposition and its
precedence level led to a very unintuitive outcome. Once I had
re-established equilibrium, I thought to myself: OK, that is how l3fp
does things. Juxtaposition at the highest precedence level is applied
rigorously (with perhaps one exception). I can adjust my code. The user
doesn't need to know about what is happening in l3fp. It is after all
part of l3kernel, part of the engine.
Can you expand on that one exception? I don't see what it is.
Post by aparsloe
I concluded that email by wondering if it might be possible to graft a
more intuitive front end onto l3fp -- call it l3calc, say. By way of
analogy, there is l3keys in l3kernel and l3keys2e in l3packages. Have
you considered such an option? l3calc would spend most of its time
putting parentheses around terms and asterisks between them. But nothing
would be broken, as a change in precedence level in l3fp will entail.
The "hairy-chested" could continue to use l3fp; less macho types might
prefer the more intuitive interface of l3calc.
Andrew
I disagree. Implementing a parser with all the properties we need (in
particular, expandability) is difficult and requires a lot of code,
which would have to be essentially duplicated from l3fp into a
hypothetical l3calc for a very minimal advantage if it is just
correcting the precedence of juxtaposition. Is there any other change
that such an l3calc should make (basically, what else should we change
in l3fp)?

Making a breaking change to l3fp is not great, but hopefully this
particular aspect has not been used too much (I'd be more wary of
forbidding juxtaposition altogether), and won't break any document.

Regards,
Bruno
aparsloe
2014-07-12 04:46:59 UTC
Permalink
Post by Bruno Le Floch
Post by aparsloe
Post by Joseph Wright
Post by Bruno Le Floch
Post by Joseph Wright
Post by Bruno Le Floch
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
To be clear, continue to allow
2x + 1
2pt + 3cm
but with
2x^2 + 2 = 2*(x^2) + 2
so for your example 25pc^2 requiring braces (0.25pc)^2?
Post by Bruno Le Floch
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Seems OK to me (if I've understood correctly).
Yes you did. Cf my other email: how should the change happen?
As I said there, with a 'breaking' change (which sometimes simply can't
be avoided) all we can do is warn that there is one. Write the code and
test properly and I'll worry about the release announcement :-)
--
Joseph Wright
I'm swimming away out of my depth here, but I wonder if you need to
break anything?
My original email on juxtaposition was prompted when I "stubbed my toe"
on a case where the rigorous application of juxtaposition and its
precedence level led to a very unintuitive outcome. Once I had
re-established equilibrium, I thought to myself: OK, that is how l3fp
does things. Juxtaposition at the highest precedence level is applied
rigorously (with perhaps one exception). I can adjust my code. The user
doesn't need to know about what is happening in l3fp. It is after all
part of l3kernel, part of the engine.
Can you expand on that one exception? I don't see what it is.
I found myself on occasion wanting to substitute a number in expressions
where pi is followed by other terms. For instance the fine structure
constant is 2pi e^2/hc (where e is the electronic charge in this case)
but direct substitution of values for e etc. simply provokes an
"Undefined control sequence" message. Since numbers are not (as far as I
understand) elements of control sequences, this felt like an unnecessary
limitation. (But I'm not familiar with the underlying constraints. Hence
the "perhaps".)

As I've tried to indicate, I've come to realise that what matters is
clarity in what the rules are and the rigour of their application. My
concern was with people who might, at present, use a (clunky?) package
like calc, or fp, coming across l3fp, being seduced (like me) and coming
a cropper (as I did). The proposed change will certainly reduce that
possibility.

Andrew
Bruno Le Floch
2014-07-15 14:00:07 UTC
Permalink
Post by aparsloe
Post by Bruno Le Floch
Can you expand on that one exception? I don't see what it is.
I found myself on occasion wanting to substitute a number in expressions
where pi is followed by other terms. For instance the fine structure
constant is 2pi e^2/hc (where e is the electronic charge in this case)
but direct substitution of values for e etc. simply provokes an
"Undefined control sequence" message. Since numbers are not (as far as I
understand) elements of control sequences, this felt like an unnecessary
limitation. (But I'm not familiar with the underlying constraints. Hence
the "perhaps".)
Not sure what you mean here. Doing \fp_show:n { 2pi e^2/hc } gives two errors:

\LaTeX3 error: Unknown fp word pie.
\LaTeX3 error: Unknown fp word hc.

Doing

\fp_const:Nn \c_aparsloe_e_fp { 1.60217657e-19 }
\fp_const:Nn \c_aparsloe_h_fp { 6.62606957e-34 }
\fp_const:Nn \c_aparsloe_c_fp { 299 792 458 }
\fp_show:n { 2pi \c_aparsloe_e_fp ^2 / ( \c_aparsloe_h_fp
\c_aparsloe_c_fp ) }

works (except that since I've used values in SI units for e, h, c, the
formula for the fine structure constant is missing a factor of
sqrt(4pi*epsilon0)).
Post by aparsloe
As I've tried to indicate, I've come to realise that what matters is
clarity in what the rules are and the rigour of their application. My
concern was with people who might, at present, use a (clunky?) package
like calc, or fp, coming across l3fp, being seduced (like me) and coming
a cropper (as I did). The proposed change will certainly reduce that
possibility.
I'm not sure what change you propose (besides the precedence of
juxtaposition, which will change soonish), and it will be helpful if
you clarify.

Regards,
Bruno
aparsloe
2014-07-15 22:02:51 UTC
Permalink
Post by Bruno Le Floch
Post by aparsloe
Post by Bruno Le Floch
Can you expand on that one exception? I don't see what it is.
I found myself on occasion wanting to substitute a number in expressions
where pi is followed by other terms. For instance the fine structure
constant is 2pi e^2/hc (where e is the electronic charge in this case)
but direct substitution of values for e etc. simply provokes an
"Undefined control sequence" message. Since numbers are not (as far as I
understand) elements of control sequences, this felt like an unnecessary
limitation. (But I'm not familiar with the underlying constraints. Hence
the "perhaps".)
\LaTeX3 error: Unknown fp word pie.
\LaTeX3 error: Unknown fp word hc.
Doing
\fp_const:Nn \c_aparsloe_e_fp { 1.60217657e-19 }
\fp_const:Nn \c_aparsloe_h_fp { 6.62606957e-34 }
\fp_const:Nn \c_aparsloe_c_fp { 299 792 458 }
\fp_show:n { 2pi \c_aparsloe_e_fp ^2 / ( \c_aparsloe_h_fp
\c_aparsloe_c_fp ) }
works (except that since I've used values in SI units for e, h, c, the
formula for the fine structure constant is missing a factor of
sqrt(4pi*epsilon0)).
Post by aparsloe
As I've tried to indicate, I've come to realise that what matters is
clarity in what the rules are and the rigour of their application. My
concern was with people who might, at present, use a (clunky?) package
like calc, or fp, coming across l3fp, being seduced (like me) and coming
a cropper (as I did). The proposed change will certainly reduce that
possibility.
I'm not sure what change you propose (besides the precedence of
juxtaposition, which will change soonish), and it will be helpful if
you clarify.
Regards,
Bruno
OK, my example, has misled. I simply wondered why pi2 (for instance) is
not acceptable to l3fp? And in the same vein, why is (3)2 not accepted,
whereas (3)(2) and 3(2) are accepted? This rejection by l3fp of
"trailing numbers" felt to me like an oversight in the otherwise
rigorous application of juxtaposition.

Andrew

aparsloe
2014-07-11 08:27:01 UTC
Permalink
Post by Bruno Le Floch
Hello list,
Sorry for the >1 month delay. This is a followup to the thread asking
whether letting juxtaposition denote multiplication was a good idea.
I think it was, but I made a big mistake in making juxtaposition be
multiplication with a _different precedence_ than the asterisk.
...
Post by Bruno Le Floch
In l3fp, I pushed the idea to its extreme, allowing juxtaposition for
things other than units, and I kept the precedence as being the
tightest possible.
As Lars rightfully says it's "consistent, but not necessarily
intuitive". Andrew has given several cases where my choice leads to a
terrible behaviour for l3fp, and there is basically no case where the
current behaviour is better (well, there was one abusive one: with
this rule, exp.5ln(...) computes the square root, but now that is not
needed).
Actually, I've found this "abuse" quite a handy device, and despite the
introduction of the sqrt function to l3fp, for n-th roots, exp(1/n)ln
has a certain convenience.
Post by Bruno Le Floch
I'm keen on leaving juxtaposition = multiplication, because that
allows to use dimensionful numbers directly inside fp expressions (pt,
in, ... are defined as floating point constants). I believe that we
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Best regards,
Bruno
Thanks for the response Bruno (but "terrible" is a strong word). The
suggested new precedence would certainly take care of the examples that
tripped me up and that seemed like traps for the unwary.

There is one other precedence which troubles me a little. I read an
expression like

ln(1+1/n)^n

as 'raise (1+1/n) to the n-th power then take the logarithm' ( =
n*ln(1+1/n) ). l3fp treats this as

( ln(1+1/n) )^n

I realise that in the absence of clarifying parentheses there is an
inherent ambiguity in such forms which needs to be resolved in a fixed
manner one way or the other. I question whether l3fp has chosen the
intuitive way, or the way of customary practice. For instance we write
("incorrectly" but the practice is universal) sin^2 x rather than sin
x^2 when we want to square the sine of x, presumably because sin x^2
suggests the sine of x^2. In short, should the precedence levels of
function calls and raising to a power be interchanged? With your
proposed change to juxtaposition's precedence, this would bring l3fp
into line with customary "habits of mind".*

Andrew

* Well, my mind!
Bruno Le Floch
2014-07-11 16:22:15 UTC
Permalink
Post by aparsloe
Post by Bruno Le Floch
Hello list,
Sorry for the >1 month delay. This is a followup to the thread asking
whether letting juxtaposition denote multiplication was a good idea.
I think it was, but I made a big mistake in making juxtaposition be
multiplication with a _different precedence_ than the asterisk.
...
Post by Bruno Le Floch
In l3fp, I pushed the idea to its extreme, allowing juxtaposition for
things other than units, and I kept the precedence as being the
tightest possible.
As Lars rightfully says it's "consistent, but not necessarily
intuitive". Andrew has given several cases where my choice leads to a
terrible behaviour for l3fp, and there is basically no case where the
current behaviour is better (well, there was one abusive one: with
this rule, exp.5ln(...) computes the square root, but now that is not
needed).
Actually, I've found this "abuse" quite a handy device, and despite the
introduction of the sqrt function to l3fp, for n-th roots, exp(1/n)ln
has a certain convenience.
Well, that won't work once we change the precedence of juxtaposition
to be the same as normal multiplication. But IIRC, we added (perhaps
in l3candidates? I'll check) a way for users to define their own fp
functions. This is still experimental. Looking at it, it seems we
don't document \fp_function:Nw and \fp_new_function:Npn anywhere.
Post by aparsloe
Post by Bruno Le Floch
I'm keen on leaving juxtaposition = multiplication, because that
allows to use dimensionful numbers directly inside fp expressions (pt,
in, ... are defined as floating point constants). I believe that we
should change the precedence of juxtaposition-as-multiplication from
what it currently is (the tightest) to being the same as
multiplication. In other words, juxtaposition would behave exactly
identically to adding an asterisk.
Would that make sense? Am I missing something crucial (probably... I
didn't realize when allowing juxtaposition what a mess I was
creating)?
Best regards,
Bruno
Thanks for the response Bruno (but "terrible" is a strong word). The
suggested new precedence would certainly take care of the examples that
tripped me up and that seemed like traps for the unwary.
There is one other precedence which troubles me a little. I read an
expression like
ln(1+1/n)^n
as 'raise (1+1/n) to the n-th power then take the logarithm' ( =
n*ln(1+1/n) ). l3fp treats this as
( ln(1+1/n) )^n
I realise that in the absence of clarifying parentheses there is an
inherent ambiguity in such forms which needs to be resolved in a fixed
manner one way or the other. I question whether l3fp has chosen the
intuitive way, or the way of customary practice. For instance we write
("incorrectly" but the practice is universal) sin^2 x rather than sin
x^2 when we want to square the sine of x, presumably because sin x^2
suggests the sine of x^2. In short, should the precedence levels of
function calls and raising to a power be interchanged? With your
proposed change to juxtaposition's precedence, this would bring l3fp
into line with customary "habits of mind".*
Andrew
* Well, my mind!
No. All programming languages in which function arguments are
surrounded with parentheses interpret ln(123)**2 as (ln(123))**2, so
l3fp should as well.

Now the question is how to implement the change in precedence in the
least destructive way. I don't think we can have any warning (well...
that's only mostly true, I have some very experimental code for ugly
expandable warnings). Should we just do the change brutally?

Regards,
Bruno
Joseph Wright
2014-07-11 16:36:33 UTC
Permalink
Post by Bruno Le Floch
Post by aparsloe
Actually, I've found this "abuse" quite a handy device, and despite the
introduction of the sqrt function to l3fp, for n-th roots, exp(1/n)ln
has a certain convenience.
Well, that won't work once we change the precedence of juxtaposition
to be the same as normal multiplication. But IIRC, we added (perhaps
in l3candidates? I'll check) a way for users to define their own fp
functions. This is still experimental. Looking at it, it seems we
don't document \fp_function:Nw and \fp_new_function:Npn anywhere.
That code is not in the public distribution :-) (It's in l3trial, which
is on GitHub/SVN but not distrusted further as it's 'very experimental'.)
Post by Bruno Le Floch
No. All programming languages in which function arguments are
surrounded with parentheses interpret ln(123)**2 as (ln(123))**2, so
l3fp should as well.
Quite: in the same way, while mathematicians write "sin^2 x", in code
you have to go for "(sin x)^2".
Post by Bruno Le Floch
Now the question is how to implement the change in precedence in the
least destructive way. I don't think we can have any warning (well...
that's only mostly true, I have some very experimental code for ugly
expandable warnings). Should we just do the change brutally?
This one is a 'breaking change', so we have to bite the bullet. We are
well outside of the 'no breaking changes' window we have for the TL
freeze, so what will have to happen here is once the code is checked in
I'll make sure the appropriate CTAN update comes with a warning.
--
Joseph Wright
aparsloe
2014-07-11 21:49:35 UTC
Permalink
Post by Bruno Le Floch
Post by aparsloe
Post by Bruno Le Floch
In l3fp, I pushed the idea to its extreme, allowing juxtaposition for
things other than units, and I kept the precedence as being the
tightest possible.
As Lars rightfully says it's "consistent, but not necessarily
intuitive". Andrew has given several cases where my choice leads to a
terrible behaviour for l3fp, and there is basically no case where the
current behaviour is better (well, there was one abusive one: with
this rule, exp.5ln(...) computes the square root, but now that is not
needed).
Actually, I've found this "abuse" quite a handy device, and despite the
introduction of the sqrt function to l3fp, for n-th roots, exp(1/n)ln
has a certain convenience.
Well, that won't work once we change the precedence of juxtaposition
to be the same as normal multiplication. But IIRC, we added (perhaps
in l3candidates? I'll check) a way for users to define their own fp
functions. This is still experimental. Looking at it, it seems we
don't document \fp_function:Nw and \fp_new_function:Npn anywhere.
Regards,
Bruno
A previous version of interface3.pdf included some documentation of
\fp_new_function:Npn and \fp_function:Nw -- in the l3candidates section.
But when I check I see that It's missing from the latest version. On the
basis of this earlier documentation I've used \fp_new_function:Npn for
some simple-minded definitions of the hyperbolic functions and their
inverses.

Andrew
Robin Fairbairns
2014-06-09 12:54:38 UTC
Permalink
Post by Lars Hellström
[...]
You conspicuously omit programming languages, which I would put as a
forerunner of spreadsheets (the less about said, the better), and
probably also of modern calculators that attempt to display
formulae. So it probably all boils down to "because that's how it was
in FORTRAN" (which, if memory serves, ignored spaces).
not entirely. originally designed for programmers writing programs on
cards, and had fixed layout (which card punches could be set up for).

iirc (it's a long time)
cols 1-5 label number or blank
col 6 continuation mark or blank
col 7+ programming statement (optionally continued on next card, as
signified by the continuation mark)

that's what the spec said (modulo my feeble memory). the compiler i
learned with (written by the guy who lectured us on the language) had
some relaxation of the rules. iirc, column 1 blank->code, lines not
restricted to 80 chars long.

the _real_ programming language[*] that ignores spaces, is dna.

robin

[*] note that i don't claim that fortran isn't real...
surreal would be nearer the mark.
David Kastrup
2014-06-09 13:43:46 UTC
Permalink
Post by Lars Hellström
Oh yes. One of the really big mistakes people make when trying to
implement mathematics is believing that the mathematical formula
language is consistent, just because it is precise. Juxtaposition can
denote pretty much *anything* (depending on context), and because
juxtaposition is multiplication, it follows that pretty much anything
can be regarded as a kind of multiplication. ;-)
More like "anything can be regarded as a kind of linear operator with
respect to the following expression".

d/dx is not really something you "multiply" with. Everybody is
comfortable writing and reading x y, but when it is x x, it looks
suspicious.

When you take something like Fourier transforms, linear time-invariant
operators _are_ a multiplication after transform.

If you take the t->f kind of transform electrical engineers prefer
(because you don't need to fiddle with asymmetric or weird scaling
factors), you can basically say

\nabla -> 2\pi \vec f

Which makes little sense on the surface, but a rot written as
\nabla \times transforms to 2\pi \vec f \times, a div written as
\nabla \cdot transforms to 2\pi \vec f \cdot, a gradient written
as \nabla \phi transforms to 2\pi \vec f \Phi, so for a number of
purposes, operator juxtaposition works in a rather multiplication-like
manner.

Of course, like with other mathematical jigglery-pokery in engineering
professions, you'll not find anything in the books used to teach the
engineers, and the books used to teach mathematicians use completely
other terminology and conventions not convenient for the kind of vector
analysis an engineer might want to do.

And the theoretical physicists do something else entirely in order not
to get caught in the crosswinds.

You'll be returning to your regular scheduled topic of LaTeX after the
break.
--
David Kastrup
Loading...