LaTeX, LLMs and Boring Technology
10 points by carlana
10 points by carlana
The main criticism of boring technology is typically that it's "too big, full of cruft, difficult to understand". LLMs really help cutting through the learning curve though, and all that "cruft" is very likely to become useful some time in the future when you graduate from the basic use cases.
Do they? Or do they just help you generate code that's not really that readable, and that you don't understand? I think the ease with which code can be read and understood is much more important than how hard it is to write[1]. We should get rid of the rough corners, not automate them away. This results in worse code long-term.
I also don't see why "cruft" would ever be useful, but maybe we're thinking of different things there.
[1] This is mostly a general point, but I think it applies to markup languages too. You don't publish the first drafts, do you?
For finding the right math symbols, I rarely need to scan reference materials any longer.
Me neither, detypify is pretty reliable. But I also find Typst's symbol names to be pretty obvious and intuitive for the most part - I often just guess and get it right. They also work with autocomplete. If I'm looking for e.g. one of the integral symbols, I can type in integral., and see all the "subsymbols".
Ignoring LaTeX's equation notation and doing their own thing is one of the biggest mistakes Typst makes, in my opinion. LaTeX's notation may not be perfect, but it's near universal at this point with support in almost all math-aware tools.
LaTeX's math notation sucks. I can easily keep up with math lectures when writing in Typst; I can't imagine ever doing this in LaTeX.
The author uses Green's Theorem in the article as an example of something where they can just reach out for an LLM instead of typing out the LaTeX, so let's use it to compare both - it's a nice complex example:
// an usual function of mine for multivariable calculus
#let dvp(a,b) = $(partial #a)/(partial #b)$
$
  integral.cont_C (L dif x + M dif y)
  = integral.double_D (dvp(M,x) - dvp(L,y)) dif A
$
\newcommand{\dvp}[2]{\frac{\partial{#1}}{\partial{#2}}}
\oint_C (L\, dx + M\, dy)
= \iint_D \left(\dvp{M}{x} - \dvp{L}{y}\right) dA
(The LaTeX version lacks the upright "d" in derivatives, because I didn't want to use up more space. Typst's dif also ensures the spacing is correct.) To compare:
integral.cont and integral.double are much more intuitive than oint and iint, mostly for the previously mentioned reasons.\left( and \right) are absolutely horrible - Typst just mostly does the right thing by default (but you can still manually specify a bracket pair with lr).\frac{}{} is also horribly verbose for something that's used in math all the time. Compare Typst's (e^x - e^(-x))/2 to \frac{e^x - e^{-x}}{2}.I get it, LaTeX is ubiquitous, I also have to still use it from time to time. I usually just write it directly - but I have friends that write equations in Typst first and then use pandoc to convert them to LaTeX, because that's just so much more convenient.
LaTeX's success is not a reason not to develop alternatives, IMO.
On that note,
LLMs will easily answer questions like [...] or "write the latex for Green's theorem, integral form".
I don't think this is necessary with Typst. Besides, I'm not really convinced of how useful LLMs are here?
Some more minor points:
I feel like having to ask LLMs for help with TikZ is just a sign that TikZ's syntax isn't quite there, compared to CeTZ and Typst's vast array of specialized packages that tend to make stuff pretty easy. Anecdotally, I've rewritten some TikZ diagrams in CeTZ, and the resulting code was IMO much more readable - but I have very little TikZ experience; maybe the original code was just bad. I won't linger on this point.
I don't really get using LLMs to populate LaTeX tables? I usually had scripts output data that can be directly consumed by Typst. I actually often output it as a Typst structure, which I then processed in the code to generate a table. This separates the presentation from the content - and I can really easily mess around with how exactly I present any given data. (also, there's CSV support :D)
Typst absolutely is a "real programming languages"; I even wrote a FEM solver in it once. That was obviously a silly exercise (and an attempt to only use one language for my homework, instead of different languages for the solver and pdf) - but it is actually plenty powerful for most of the things I want to do in a document.
One of the killer usecases for me is generating graphs in the document itself. I've very heavily used this for my Statistics notes - all the function graphs were generated directly in the document. They use the styling of the surrounding document, are easy to modify, literally just specify the equation I want to graph and figure out the rest. It's great
I'm worried that LLMs will make us stick with "good enough" tools, when I think our tooling could still use a lot of work and polish.
I remember thinking that IDEs filling out boilerplate for you was silly - sure, this helped you write code, but the boilerplate also makes the code hard to read - and that just hides the problem. That's solving one of the symptoms, instead of the core problem. I hoped people would wisen up - but we've just made the problem much worse.
I have no opinion on the slop-aspect of the article (and indeed mostly agree with you there), but I feel like defending LaTeX a little bit here. Ignore this if you don't care.
Me neither, detypify is pretty reliable. But I also find Typst's symbol names to be pretty obvious and intuitive for the most part - I often just guess and get it right.
I'm sure you know that detypify is just a clone of detexify, which does more or less the same thing. I have to say, though, that symbol names are mostly just a matter of practice. I have been indoctrinated by LaTeX long enough that I often experience exactly the same effect you describe -- guessing symbol names and they end up being what I want.
LaTeX's math notation sucks. I can easily keep up with math lectures when writing in Typst; I can't imagine ever doing this in LaTeX.
This surprises me. Writing LaTeX fast is something that lots of people have extensively written about; it's not all that complicated, just comes down to having the right snippets. I reckon that, in lectures where notation is not too involved, none of this is necessary -- I can certainly type \oint_C faster than I can type integral.cont_C.
The author uses Green's Theorem in the article as an example of something where they can just reach out for an LLM instead of typing out the LaTeX, so let's use it to compare both - it's a nice complex example:
[…]
(The LaTeX version lacks the upright "d" in derivatives, because I didn't want to use up more space. Typst's dif also ensures the spacing is correct.)
The upright "d" seems to be a convention dependent on the field, I've not really seen it in maths, but rather in engineering or physics . Either way, I don't think defining \newcommand{\dif}{\,\mathrm{d}} is that space consuming, if you want that kind of behaviour. In general \newcommand*{\dif}{\mathop{}\!\mathrm{d}} would be better, I guess, but for your specific example they are equivalent.
This is also what I see a lot of people struggle with: not just the fact that a macro-expansion language is unfamiliar to them (and yes, \relax, \expandafter, and friends are horrible), but also that typesetting is actually complicated. When to use \mathord, \mathrel, \mathbin, \operatorname, \mathpalette, and so on are real choices. These are not "language features" as such, they are typographical features. Typst will either have to wrangle with these (or similar) concepts -- and expose them to the user -- as well, or produce documents that aren't up to par with LaTeX. This may be fine, even; I'm sure there are lots of people who don't care and/or couldn't tell the difference, but I'm just trying to convey that being almost infinitely malleable is how LaTeX even managed to survive all of these years.
To compare:
- I think integral.cont and integral.double are much more intuitive than oint and iint, mostly for the previously mentioned reasons.
As mentioned above, these just sounds like "this thing is more familiar than this other thing" to me. Perhaps it's my unhealthy preference for short names, I don't know.
- \left( and \right) are absolutely horrible - Typst just mostly does the right thing by default (but you can still manually specify a bracket pair with lr).
But \left( and \right) are almost never the right thing to do, from a typographical perspective! They just look pretty bad, most of the time. You rather want your parentheses to be a bit smaller than the equation itself (aligning to something like the "main part", discounting small-ish ascenders and descenders). It seems to me that one system trusts the user to know what they are doing, and another one is trying to offer "help", which perhaps makes easy things easier, but also seems to make everything more complicated a bit more mediocre.
- \frac{}{} is also horribly verbose for something that's used in math all the time. Compare Typst's (e^x - e^(-x))/2 to \frac{e^x - e^{-x}}{2}.
A lot of the times I write / in LaTeX I actually mean it (say, quotienting a ring by an ideal or something). I certainly use that a lot more often than \frac, which basically only comes out when I have to design an exercise sheet for students. This is basically the same point as above: typst feels like a system designed for, say, developers, who don't have to write certain kinds of maths. This just so happens to be the type of maths that I write constantly, so perhaps that's where the friction enters.
LaTeX's success is not a reason not to develop alternatives, IMO.
This is certainly something that I agree with. TeX and LaTeX have a lot of warts and dark corners; something that is genuinely better would be nice (although it would still be hard to replicate all of these years of packages), I'm just not convinced typst is that something. Certainly not from a typographic perspective, at least right now.
it's not all that complicated, just comes down to having the right snippets
This is not something I had to ever bother with. I just kinda write with no special preparation (apart from general knowledge of Typst).
Either way, I don't think defining
\newcommand{\dif}{\,\mathrm{d}}is that space consuming, if you want that kind of behaviour.
I agree, but that would still make the comparison unfair towards LaTeX. Maybe I could've just used d x in Typst instead of dif x to avoid this... I wrote the first one without really thinking.
Typst will either have to wrangle with these (or similar) concepts -- and expose them to the user -- as well, or produce documents that aren't up to par with LaTeX.
https://typst.app/docs/reference/math/class/?
As mentioned above, these just sounds like "this thing is more familiar than this other thing" to me.
Let me rephrase - more discoverable? That's probably more objective. I admit that "which name is better" is subjective and I'm very biased (although I do prefer Typst's descriptive names, e.g. union inter without vs \cup \cap \setminus).
Something you'll probably agree is better is the notation for the various arrows? I can just do |-> instead of \mapsto, ==> instead of \Longrightarrow, etc.
Also, compare f : RR -> RR for a function on the reals, compared to LaTeX's f\colon\mathbb{R}\to\mathbb{R} (an example taken directly from undergradmath).
But \left( and \right) are almost never the right thing to do, from a typographical perspective! They just look pretty bad, most of the time.
If you want that, you can just escape the bracket as \(.
But also, I'm not sure if I agree. Looking at the AMS Style Guide 13.6, "Fences should preferably be as large as the material they enclose in displays", so I'm not the only one :p
I think this optimizes for the common case. When I needed to I did use lr's size argument to finetune the bracket size, if it got too large.
A lot of the times I write / in LaTeX I actually mean it (say, quotienting a ring by an ideal or something).
You can escape it too, \/ - e.g. RR[X] \/ (X^2 + 1).
I think that single extra character is a good price to pay for fractions being much simpler to write.
Something like that, yes, at least for some of those macros I mentioned. \mathpalette lets you adjust the display of the macro based on the math-mode (inline or display) and position (subscripts et al), but I would assume that typest also has an equivalent for that.
This link helps me make a point, though: peeking at the source code for dif, it seems that it's defined in a different fashion entirely (a squishy thin space, followed by a roman "d", which is more or less what \mathop{}\!\mathrm{d} also does). I wonder if that's because its behaviour does not fit any of the options for class: you'd (sometimes) want space before the d, but not after, which I guess is the opposite of what unary would do. This is sort of what I mean when I say that things are inherently complex, and at some point you'll have to wrangle with primitives anyways.
Let me rephrase - more discoverable? That's probably more objective. I admit that "which name is better" is subjective and I'm very biased (although I do prefer Typst's descriptive names, e.g.
union inter withoutvs\cup \cap \setminus).
I've always found the names for \cup and \cap to be extremely cute and really rather mnemonic, but yeah, especially with proper editor integration the fact that typst is more discoverable is almost certainly true.
Something you'll probably agree is better is the notation for the various arrows? I can just do
|->instead of\mapsto,==>instead of\Longrightarrow, etc.Also, compare
f : RR -> RRfor a function on the reals, compared to LaTeX'sf\colon\mathbb{R}\to\mathbb{R}(an example taken directly from undergradmath).
I guess I don't feel this particular pain because snippets (which I feel are fair to talk about, since we are talking about editor integration elsewhere) have become so second nature to me for LaTeX entry. Converting : to \colon, -> to \to, and so on while in math-mode are things that I've stopped actively thinking about, so has letting my editor visually replace them with their Unicode counterparts. Perhaps this is why I'm not all too bothered with the admittedly cleaner syntax of typst, and rather concerned with what I'm getting out at the end.
But also, I'm not sure if I agree. Looking at the AMS Style Guide 13.6, "Fences should preferably be as large as the material they enclose in displays", so I'm not the only one :p
I think this optimizes for the common case. When I needed to I did use lr's size argument to finetune the bracket size, if it got too large.
Maybe the AMS Style Guide is wrong :>
This could just be an idiosyncrasy of mine, but I very much prefer not using \left…\right wherever possible (grepping through the source code of my thesis says there are around there times more occurrences of \\\(b|B)ig*l? than there are of \\\left). Compare something like
\[
  \bigl( X \xrightarrow{\ f\ } TY \xrightarrow{\,Tg\,} T^2Z \xrightarrow{\ \mu\ } TZ \bigr)
\]
to
\[
  \left( X \xrightarrow{\ f\ } TY \xrightarrow{\ Tg\ } T^2Z \xrightarrow{\ \mu\ } TZ \right)
\]
A perhaps even more egregious example is
\[
  \left(\left(\frac{a}{b}\right)^t\right)^m
\]
vs
\[
  \Bigl(\left(\frac{a}{b}\right)^{\!t\,}\Bigr)^{\!\!m}
\]
I think one can adjust the algorithm with which \left…\right chooses the size, but it'll never be perfect.
peeking at the source code for dif, it seems that it's defined in a different fashion entirely (a squishy thin space, followed by a roman "d", which is more or less what \mathop{}!\mathrm{d} also does).
...so? I looked up "latex upright d macro", clicked the first result, and it defined it pretty much exactly as you said. I don't think it's a big deal?
I guess I don't feel this particular pain because snippets (which I feel are fair to talk about, since we are talking about editor integration elsewhere) have become so second nature to me for LaTeX entry. Converting : to \colon, -> to \to, and so on while in math-mode are things that I've stopped actively thinking about, so has letting my editor visually replace them with their Unicode counterparts.
Why not skip the middleman and just use : instead of \colon and -> instead of \to? :p
In general I'm skeptical of these kinds of editor features (so also, relying on LSP hints, etc), because you're not going to always be viewing the code in an editor. Git diffs/patches are probably an obvious example - or chats, lobste.rs comments (:p), etc.
As for your examples - you could set the size manually, or you could also set up some LaTeX-style functions:
#let biglr(b) = $lr(size: #1.5em, (#b))$
#let Biglr(b) = $lr(size: #2em, (#b))$
$
  biglr( X -->^f T Y -->^(T g) T^2 Z -->^mu T Z ) \
  Biglr( (a/b)^t )^m
$
If you really hate the automatic sizing you can disable it with #set math.lr(size: 0%), but I don't really know why you would want to do that. It's not "required", your manual tweaks will always override it. It's just an (IMO) sensible default.
I also wanted to try just changing the logic that math.lr uses to decide on the size - in general tools like measure and show/set rules are pretty powerful - but that doesn't seem possible to do from within Typst (yet?).
the boilerplate also makes the code hard to read
Objectively, is this actually true? Golang is very readable, terser languages tend to appeal to a much smaller minority.
I mean, e.g. if err != nil { return err } being too verbose is a very common complaint:
There's a large spectrum here, with old Java on one end, and APL on the other (or perhaps Jelly? :p). People have very different opinions about what's the sweet spot, and honestly I don't really know where I stand either - but I do think that Typst is a lot closer to that sweet spot than LaTeX.
Boilerplate or lack thereof is a completely different axis from terseness. Rust is not particularly terse, but my Rust code tends to have very little boilerplate.
In general I think, and have for a long time, that boilerplate is purely bad. If it exists, something is wrong. So when 90% of people saying LLMs are code for code cite boilerplate generation, I conclude that LLMs are worthless for code.
Disclaimer: I did not read TFA, so make fun of me if you want.
I want to comment about math mode notation. You've made me reconsider my stance a little bit.
Without question there are some terrible designs in math mode such as \left( as well as questionable idiosyncrasies such as \vdash and \dashv, \leftarrow and \Leftarrow, as well as my favorite, \big and \bigg . But as the author says in your quote, so many of us are used to the nomenclature that I was surprised Typst decided to rename everything. I do think it's time we had a better typesetting language, but I would hope that I could avoid having to detypify my way back to the point of fluency in the symbols I use.
Now I want to be careful here: I'm not trying to say other people should suffer because I have already done my suffering. But if I were designing Typst I would at least try to offer some way for people to write "the old way" and have it translated --- perhaps even offering a way to do this in-editor for those who prefer reading one or the other.
This was all my initial reaction to Typst. Your side-by-side comparison has made me realize that this is mostly wishful thinking. I think I can at least appreciate their decisions more now. If you start changing the obviously bad parts of TeX like \left( you'll then ask yourself why \ is necessary in the first place and once you've started to make things finally seem sane, you'll be so committed that \oint and company will be on the chopping block. And anyway if I were redesigning it, the objection that \oint is descriptive of the symbol could be easily solved by making the semantic name integral.cont point to the same symbol as integral.o (or some perhaps saner naming scheme).
Now all of that said, I'm still a bit of a TeX apologist, so I will point out that some of this whole \fracas (as it were) could actually be a lot nicer. There certainly are exceptions to this, but my overall understanding is that braces in TeX are just for grouping and can be omitted if not necessary, much like how in Haskell foo(a)(b) is the same as foo a b.
So your example would more fairly be (e^x - e^(-x))/2 to \frac {e^x - e^{-x}} 2. And looking at this, I feel basically like fractions are doomed to being bad when written out (it's a taste thing, but I might prefer TeX's for familiarity). The theorem you use as an example would also be more fairly
\left(\dvp M x - \dvp L y\right)
(the rest is the same). Legibility of this method is arguable and I won't insist upon one over the other. But at least in terms of typing (e.g. for lecture notes) I find being able to take these shortcuts makes my life a lot easier. I am still SOL when the document doesn't compile...
I would argue that Typst is the boring technology here. It produces the same beautifully-typset documents as LaTeX, with a developer experience informed by 40 years of progress in programming language design. Nothing about Typst is surprising, if you're accustomed to modern development tools. In fact, it's what most developers expect.
What I like most about the Rust community is that they have collectively agreed that "we can have nice things", and built them.
Typst is not hard to learn. LaTeX on the other hand is notoriously painful. If we can't manage to write LaTeX without relying on LLMs powered by massive data centers controlled by giant tech companies, isn't that an indication that it's time to move on?