It feels absurd to have this occur in the parser, as if you can somehow account for all the cases via guessing what people I mean. You absolutely must have a grouping operation like {} at least available as a fallback.
I feel like this is a lesson people keep learning over and over across programming languages: don't let your syntax try to infer the intended meaning of what was typed, just do something simple and predictable.
So (b) seems like the only sane choice, but having the grouping operation being e^(abs(x)) is also crazy. You need something like TeX's e^{abs(x)}.
Personally I think the "best" workaround for this is to decouple the text representation and the representation the editing happens in. Allow people to type e^abs(x) and then the editor translates that into e^{abs(x)} while letting you edit it as an exponential, but if you're working on the underlying text file then you have to write e^{abs(x)}. For that matters, you can just have the editor represent it as a literal superscript.
(My hunch is that this is generally much-needed across languages: let the editor do some of the parsing work. I think there's much to be gained by separating the two, because you can keep the parser of the actual language simple while still getting all your editing-efficiency improvements out of the editor).
Typst has made some basic choices, which as someone who typsets a lot of math, makes it a no go.
- The use of space character to also act as the escape character (latex use backslash) [1]. Not only does it cause confusion, I have to now escape everything $F=ma$ become $ F = m a $ in typst. Complex math equations will be complex no matter what - why make simple equations harder to type to make it slightly easier to type complex ones.
- The lack of these grouping brackets (latex uses curly parenthesis).
What I want from my typesetting language is "typsetting completeness". While there might be sane defaults, I want to be able to control every decision made by the typesetter by escaping and grouping things as needed. If the language doesn't have these features, by definition, it is not complete.
[1] Latex also has to use space to act as ending delimiters. $\alpha x$ is correct and $\alpha\beta$ is correct, but $\alphax$ is not. But the solution to this is to allow $αx$ which some flavors of tex do.
> What I want from my typesetting language is "typsetting completeness". While there might be sane defaults, I want to be able to control every decision made by the typesetter by escaping and grouping things as needed. If the language doesn't have these features, by definition, it is not complete.
Then LaTeX is not complete. Macros don’t have to respect the grouping provided by curly braces in math mode, therefore you only have the illusion of control. Nobody in practice actually inspects the full package dependency chain needed to typeset a nontrivial document.
Here’s a proof of concept: https://tex.stackexchange.com/questions/748416/how-can-i-aut...
Yes it is not. I think a replacement for latex is needed, but it needs to make better design choices than Typst.
That said, Typst has many good things, like easy to write methods, which this new language should adopt.
As an author of a different math typesetting tool (mathup) I explicitly made the choice of making simple expressions simple to type at the expense of making complex equations less intuitive. But I still have the same problem as OP, where simple expressions break because the intuitive behavior is the opposite of what my parser does.
AsciiMath (what my tool was inspired by) tries to be smart about this by parsing a/f(x) differently from a/x(f) and it looks like typst is making the same choose. I on the other hand opted to rather stay consistent. My reasoning is that the tool is fast enough, and I rarely (actually never) type my math expressions outside of an interactive experience where I can’t view the rendered result as I type, so I can spot my mistakes immediately (usually fixed by adding a space, or surrounding something with parens).
> Typst has made some basic choices, which as someone who typsets a lot of math, makes it a no go.
For me, breaking from not just a 40-year-old history of mathematical typesetting but also from the American Mathematical Society recommendations is the dagger. Plus doubling work if you want to reuse what you wrote to render MathJax or KaTeX.
> $\alpha x$ is correct and $\alpha\beta$ is correct, but $\alphax$ is not.
Like you said, braces can be used so all of the following are valid: ${\alpha}x$, $\alpha{x}$ or the odd $\alpha{}x$.
I am the author of a (somewhat) competing parser called mathup[1] which has a similar syntax. I based mine heavily off of AsciiMath which has {: group :} as a fallback grouping operator. I kept it, but if I would have done it over I would have replaced it with { group } and used {: group :} for curly brackets.
I had a similar dilemma before I released 1.0.0 last spring, and decided against special cases like these. In Mathup binary operators (^, _, and /) always operate on exactly one group after the operator, regardless of (what I believe is) the author’s intention. So 1/2(x, y) is the same as 1/x(i, j) is the same as 1/f(x, y). I only have a couple of exceptions regarding spacing on trig functions, and (what I believe is) the differential operator. But if you want an implicit group to e.g. under a fraction, in a superscript, you must either denote that with spaces e^ x-1, or with parens e(x-1) [I courteously drop the parens from the output in these troubled expressions].
1: https://mathup.xyz
I complained about this before and people dismissed me as an old timer. I did doubt myself as well to be honest. Its bittersweet to be correct.
I hate recurse to authority, but after a markup slash programming language has been written by Don Knuth and a macro system for it has been developed by Leslie Lamport, maybe one should take some notes so as to why things were done in a certain way?
They're not infailable, though. For example, TeX's primitive for fractions is actually {a \over b}, LaTeX's \frac is a macro on top of that. The consequence is that while typesetting a formula, the engine does not know the current text size, since an \over further down the line may put the entire thing into a numerator. Dealing with this can be quite a pain when writing math macros.
I actually think Typst should ignore the design of TeX and LaTeX more—and especially the well-meaning advice of LaTeX veterans who have only ever known one way of typesetting.
The situation reminds me of how Julia’s evolution was guided in some aspects by some opinionated and vocal {Python, R, MATLAB} developers who never had any intention of transitioning to Julia, whether or not their advice was implemented.
I was not implying they should make the same design choices, but there should be a deeper understanding of the underlying problems.
Case in point: backslashes and braces in TeX were there for a reason. You can say they make TeX code look ugly, and you would not be wrong. But when you throw them away without addressing the reason they were introduced, well, you end up with blog posts like this one.
The backslashes are not really relevant to the problem discussed in the post. The ambiguity between symbols and argument-taking macros exists just the same in LaTeX. Consider:
LaTeX just happens to do what the post calls "runtime parsing" because LaTeX doesn't really distinguish between different compiler stages at all. If you look at a macro, you can't know whether it will eat up the following braced argument.In fact, not using backslashes for symbols can actually give an _edge_ with this problem because it would allow distinguishing `pi` and `#abs` (option E in the post).
What are some examples of the Julia design issues you mention?
For me one is that one can write `for i = 1:3` is one when `=` means assignment otherwise (at least `for i in 1:3` is available.
This seems like a counter-example. The `=` was for time the only syntax (presumably taken by MATLAB--which in turn adapted it from IDL/Fortran--that initially Julia was heavily influenced from) with `in` (and `∈`) added afterwards (`in` being the only syntax used by the much more popular {Python, R}). Imo `=` alone was fine since as you say `=` means assignment, just within `for` it's an assignment applied iteratively. Opposite to that, `in` is also used as membership operator (`1 in [1, 2, 3]`) that is entirely different from its `for` role.
agree, I'm fine with Typst throwing out the old ways and doing the new ones... just, do your research; do it right
The problem is what is “right” in the minds of people using the old thing is sometimes very biased.
> Personally I think the "best" workaround for this is to decouple the text representation and the representation the editing happens in. Allow people to type e^abs(x) and then the editor translates that into e^{abs(x)} while letting you edit it as an exponential, but if you're working on the underlying text file then you have to write e^{abs(x)}. For that matters, you can just have the editor represent it as a literal superscript.
I'm pretty sure that's how LyX does it, possibly others as well.