Because that's where I lose the most time with LaTeX: packages often mess with the (piles of) global state in ways that sometimes conflict, and the only "solution" seems to be that, if you're very lucky, sometimes conscientious package authors will try to "detect" (through various hacks) whether some other known-conflicting package has already been loaded and adjust accordingly. I didn't see any mention in TFA of any module system or even local variables in Typst to contain this explosion of complexity, so I suspect it will be just as bad in this respect as LaTeX is once there are as many plugins available.
Do you have specific examples?
Sorry I can't be more specific. I definitely have memories of reordering \usepackage{} statements until "it worked"...
See also <https://latex.org/forum/viewtopic.php?t=25156>.
1)pstcol has to be loaded before graphicx (I forget the reason but it just does)
2) if I use pdftricks I have to unset the "clipbox" command because it conflicts with the one in adjustbox.
As you say in another comment, given how latex reports errors debugging these can be a Fun time.
I don't think Typst has a lot of global state to get corrupted. Like, if one package defines a variable `foo` and another package defines a variable `foo`, and you use both of them (and don't try to import `foo` from both), it's not like those `foo`s are going to conflict with each other. Is that the sort of issue that LaTeX packages run into?
Likewise, you don't modify typesetting in Typst by modifying global state like you do in Latex. You use `set` and `show`, which are locally scoped. You never need to, like, set the font size, then write some stuff, then remember to set it back. You just put `set font(size)` around precisely the stuff you want to be bigger.
However, if you have a need to override something globally (eg. a global heading font, or spacing at the paragraph level), there is really no way to do it other than doing it globally.
How would Typst solve this without having the same problem? Eg. how can I have a package that sets every "the" in red colour, without it interfering with a package that sets every "the" in blue or titlecase?
Perhaps it's structured better (I would hope so, with ~40 years of learnings since TeX was introduced), but the problem seems unavoidable if you allow things like the above.
Exactly.
Broadly, the things you might want a package/plugin to do can be categorised as "local" (e.g., add some new type of content in a fixed-size box that the layout engine can then treat the same way as it treats any other such box) or "global" (e.g., change where floats appear). Making local effects play together can be easily handled with standard PL ideas like lexical scoping, but doing the same for global things is much harder: it strongly depends on exactly what knobs (API) the base typesetting engine provides. We now have design patterns like Observer to help make creating such "global" effects simpler, assuming that their effects are genuinely orthogonal, but what if they aren't?
A plugin that sets each "the" to red clearly conflicts with a plugin that sets each "the" to blue: at most one of them can "win", so which is it? Does it depend on which plugin was loaded first? If so, that's no better than LaTeX, and will become an ever-growing headache as the ecosystem grows.
OTOH, a plugin that sets each "the" in italics can sensibly interoperate with a package that sets each "the" in bold -- and can even produce the same results regardless of which was loaded first, because these effects "commute". These effects could be implemented by having the base engine expose an event that can be listened to by any interested plugin.
ETA: The main reason LaTeX is a pain is because it makes no real attempt (that I can see) to manage any of the inevitable complexity of "global" effects. (Admittedly, this is a tough design problem.) I don't yet see signs of anything better from Typst, thus I assume it will become roughly as painful as LaTeX in time.
More generally, if your system generates errors left and right, you end up making it hard for users to find a combination of packages that work. It's better to make them work error-free as much as possible. And the concept of "overriding" is natural and useful.
I think typst does make a nice attempt at managing global effects. It's nowhere near perfect but works pretty well already. For example it's super easy to implement your example with two packages, one applying bold and the other applying italic:
Template from package A: #show regex("\bthe\b"): set text(style: "italic")
Template from package B: #show regex("\bthe\b"): set text(weight: "bold")
You can use both templates in any order, typst will correctly render "the" in italic bold.Just loading a package in Typst won't perform side-effects. Instead what they can do is giving you some function that will apply the styling to any content passed to it. It will be up to you to choose to wrap your whole document in such functions in order have them apply globally, which can be done conveniently with something like `#show: foo_template`, where `foo_template` is the aforementioned function.
This still has a chance of "incompatibility", like in the blue/red example, because you might do this with two functions from two different plugins. However it is up to you to do this, and it will hopefully be clear that you're modifying global styles in two different ways with a specific order between them.
To be fair though I should mention that some packages will expect you to use `#show` with their functions, so sometimes it will be difficult to avoid using it multiple times.
There's still potential for conflicts, for example content can contain elements that represent a state update such as incrementing a counter. Packages can define their own states for internal use, and the namespace is global, so they can interfere with each other if they don't follow good practice (prefixing state names with __package-name for example). And show rules can replace an element of content with another one, for example one package can replace verbatim code with a figure, and another package can format verbatim code. What happens if you mix them without limiting their scope?
But so far, I think the compatibility problems in typst are more of the "well, what do you expect?" kind. Compare to LaTeX where sensible code is broken when a package makes a small changes somewhere deep in the macro pile of cards.
For example someone here mentioned the example of one package changing "the" to red and another changing "the" to blue. This can be done declaratively in typst, and won't cause an error, but the result will depend on the order of declarations.
>compatibility issues in LaTeX often come from packages that redefine the same macros in incompatible ways
Absolutely. A related but more subtle problem occurs when macro A ordinarily calls a macro B, but a package redefines A not to call B at all (perhaps reimplementing part of B itself), and then, when the user includes a second package that redefines B, this latter package appears to have no effect.
Based on your explanation of Typst having a global namespace, I would expect such conventions (like a function A that by convention calls a function B, both of which can be redefined by any package) to arise in Typst just as they have done in LaTeX. (This risk would be much reduced if Typst didn't have functions as first-class values, but from the TFA, I see that it does.)
>Compare to LaTeX where sensible code is broken when a package makes a small changes somewhere deep in the macro pile of cards.
LaTeX has grown "a macro pile of cards" because (a) the base LaTeX system was not comprehensive/expressive enough to let users express everything they wanted to do "within the system" (i.e., by merely twiddling existing knobs in a composable way) and (b) because it is possible (indeed, relatively straightforward, at least initially) to make them.
Maybe Typst has a much more comprehensive and well-designed set of knobs, in which case the conditions will not arise that encourage the same "macro pile of cards" to form. Otherwise, I don't see any reason to expect that it will wind up any different.
(You may wonder how functions can be pure if they can increment counters.... The way it works is that you call the function and put the return value in the stream of content of the document. And this value can be something that says "increase counter X by Y". And when you read the counter, typst applies all such "counter instructions" that are in the document so far, and gives you the result.)
The special knobs that typst provides are the "set" and "show" rules. With "set" rules you can change the default values of elements created later in the same scope. For example "#set text(fill: red)" will make it so that all text created later in the same block of code without a specified color will be red. With "show" rules you can define transformations that will be applied to elements created later in the same scope. For example "#show math.equation: it => figure(it, caption: "An equation")" will wrap every equation in a figure with the given caption.
I think the main reason LaTeX is a pile of cards is because TeX is terrible as a general purpose programming language. Just an example: the fact that a macro called with particular arguments will behave differently depending on the current state of catcodes is a craziness that's hard to imagine when you think in terms of "normal" programming. And the whole ecosystem of amazing packages that make LaTeX so useful, they need to do the kind of things you'd normally do in a normal programming language, so these packages end up working around the oddities of TeX in ways that make the whole thing a pile of cards.
With its design based on pure functions, I'd say typst is at the other end of the spectrum in terms of how easy it is to write code that works reliably without interference from other people's code.
Jupyter-to-PDF sounds like a perfect match here!
This trips people up a lot once they do anything involving cross-referencing or bibliographies. But for some reason some people use latex for a long time and never hear about latexmk, which automates all that, and can even "watch" your files so you can edit and save and see your PDF refresh all in real time. (I've only used latex for papers or blog math, not big books; I can't imagine waiting a minute per change back in college, let alone on modern hardware...)
However, it also had index issues.
Interesting! Would you share your solution and/or tell us a little more about it? Thanks!
I find the whole system to be a bit house-of-cards and I’d love to try alternatives. What’s your workflow for using Typst with Jupyter?
Pandoc does a decent job with connecting markdown to Typst. I have a few filters that I run to convert the notebook to markdown and some other filters that I run to change the output from Pandoc.
What I enjoy about Typst is the fact that the code is easy to write and read. Even code from some third-party library or template is easy to understand. There is a world of difference between this and LaTeX, which abstracts over TeX, and whose inner workings remain obscure even to experienced developers having used LaTeX over decades for tens of documents.
The compilation of Typst documents is indeed also extremely fast compared to LaTeX.
The runtime and libraries are lightweight and easy to install, compared to LaTeX distributions.
Writing custom logic or even a fully-fledged template with Typst is easy to do from day one.
The only reason I still see to use LaTeX nowadays is writing books and papers whose editor only accepts LaTeX.
I've switched to Typst some months ago and not once have I thought it might have been a mistake. The only thing I regret is that there is no automatic migration of older LaTeX documents to Typst.
Editors still have to be improved, though the Vscode plugin is absolutely usable.
Apologies if this is a stupid question, I've never used typst.
I hope that Typst at least allows you to nest elements without any issues.
It's:
- Fast—Compiling my books would take around 1 minute (I often had to compile twice due to indexing). With Typst, it takes less than 5 seconds.
- Easy to write—I actually don't write it, I wrote a bunch of Pandoc plugins to tweak the output from Pandoc (I write all my books in Jupyter these days, so lots of markdown).
- Easy to read—I've used LaTeX for years (and wrote a bunch of tooling around it) and still couldn't tell you when to use a { or a [. Typst is very readable.
- Easy to script—Okay, I did write some Typst the other day. I migrated my LaTeX-based invoicing system to Typst. I created a list of objects with pricing and count and was able to throw it into a table easily. It has less code than my LaTeX version, which was using a library, and is easier to read. (I did need to write a function to properly format $ because that doesn't exist. A few rounds with AI made that easy.)
- Has great error messages—If you've used LaTeX, you know what I mean.
My needs are different from others, but I'm writing PDFs that need to be printed into a real book that looks professional. This includes front matter, footnotes, callouts, page numbers, page headers and footers, and indexes. I don't do a lot of math-heavy stuff, so I can't comment on that. And the widow/orphan support is a little weak.
Otherwise, I'm happy to never use LaTeX again!