Revive possibility of parenthesis-free unary function application #3646
Replies: 4 comments
-
|
To be honest with myself, once |
Beta Was this translation helpful? Give feedback.
-
|
OK, here's one possible guardrail. I would recommend
|
Beta Was this translation helpful? Give feedback.
-
|
Hmm, but there is another possible gotcha: |
Beta Was this translation helpful? Give feedback.
-
|
Note this feature was requested also in #2298, so I'm not the only one ;-) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
There is quite some discussion of the interaction between implicit multiplication and function application in #3379, especially in this comment, the bulk of which is
The eventual conclusion in #3379 was that we would not take any action toward this, in large part because the new chaining operator
?.allows you to force function-application interpretation any place you really want it, so we don't really "need" additional ways to call functions.Nevertheless, I would like to revive the proposal, based on the following three points:
notcorrectly:2 not xis a syntax error ("unexpected operator not") as opposed to parsing as2*(not x)as it should under the designation ofnotas a spelled-out unary operator.2 sin xto mean2*(sin x). Indeed, this is what we teach in algebra class, at least in the U.S. but I suspect in other areas as well.The key source of all of the difficulties has been the poor interaction between implicit multiplication and function application. And the key observation promised by (3) above is that the difficulty goes away if one designates implicit multiplication as right-associative, as opposed to explicit multiplication, which is left-associative. If you combine this decision with an operator that multiplies two operands when possible, but if not, attempts to apply the left as a function to the right, you get many new successful cases. Examples:
sin xapplies the sine function to x2 sin xparses as2*(sin x), as we would want, because of the new right-associativity.2 not xwill work as desired, simply by dropping the special handling ofnotas an operator, and letting it be an ordinary unary function. This change will both simplify the parser and fix the current bug.2 sin x cos xwould parse as2*(sin(x*cos(x)))which is not what is intended. (One would actually like the function applications to bind more tightly -- i.e. have higher precedence -- but there's no way to tell at the time you parsef x g x ywhich of 'f', 'g', and 'x' are going to turn out to be functions: if it happens that 'f', 'g', and 'y' are numbers and 'x' is a function, you want this to bef*x(g)*x(y), whereas if 'f' and 'g' are functions and 'x' and 'y' are numbers, you wantf(x)*g(x*y). ) So you would still have to write2 (sin x) cos x, or as you do now2 sin(x) cos(x), or other similar options.So to summarize, I would propose:
(a+b)x(i.e.(EXPR1)EXPR2) as only multiplication, as it is now, andf(a+b)(i.e.,ACCESSOR(EXPR2)) as only function call, as it is now. (NoteLITERAL(EXPR2), e.g.2(x*y), is only multiplication, and that should stay that way as well.)(f(x)=x^2+x-1/x)(7)(i.e.(EXPR1)(EXPR2)) andf x(i.e.EXPR1 EXPR2) as ambiguous between implicit multiplication and function call, to be determined at execution time. Right now these two constructions are only interpreted as implicit multiplication, but this change will not break any existing implicit multiplications, because multiplication will always be tried first, and only if it is not possible will function application be tried.(EXPR)()as zero-ary function application -- non-breaking as this expression is currently a syntax error.(EXPR)(ARG1,ARG2,...,ARGn)(and similarly for more arguments) as n-ary function application for n >= 2. This change is non-breaking and I have PR'ed it before, but it was not merged due to inconsistency with the unary case, which this proposal would remove.x 3to error when 'x' is a number, since this is likely a typo in which an operator has been left out or an accidental space has been inserted, since nobody ever writesx 3to mean3x. But this desire to make this construct an error is a bit tricky, since under (1)-(3), we would likesqrt 3to work, and such a change is also tangential to the main point of allowing "implicit unary function application" as well as implicit multiplication. I bring it up only in the quest for mathjs to match "natural" expressions that people write; I am not really pushing for this item.I look forward to any comments.
Beta Was this translation helpful? Give feedback.
All reactions