It seems tricky to use the state object (https://typst.app/docs/reference/meta/state/) for functions, because there is no location to provide to at() when trying to read the state.
#How to mutate a state across function calls?
45 messages · Page 1 of 1 (latest)
depends a bit what you want to do, but update has access to the previous value
embeding a state into a content doesn't require a location either
for everything else there's #locate
Thanks. But update() can't return the value, but just provides the value to its callback...
yes, this is a limitation due to how state/mutations happen in typst
basically I'm looking for a mechanism to replace pass mutable states around among functions. In Typst, functions are all "pure", so the arguments are all read-only..
there's state + locate right now
okay, thanks
there's been a few discussions about allowing stuff like user defined methods, that would be able to mutate the object they're called on (like dict.remove)
that would be very useful
note the reason you don't have direct access to state is because they aren't really evaluated synchronously
states are computed really late, and when you're working with them you're kinda only working with references/placeholders
counters work the same way
You need to pass the location as a parameter to the functions
And then the first function to call them will provide the actual location
Since it will inevitably return content
You might wish to use some context dict
Ti simplify here
To*
To be fair though, I believe it’d be nice to have some sort of way to specify that a function needs. A location
And have it automatically be passed through some sort of dependency injection mechanism
But that’s another discussion
Oh.. okay, appreciate the inputs. So it's very complex compared to other languages.
For example, if I want function f() to call g(), which recursively calls itself with a mutable state object passed throughout the stack, that's undoable because all functions on the call stack have the same location, which is the location representing where f() is called in the text body:
#let g(state) => { ... g(state) }
#let f() => { ... g(state) }
Lorem ipsum #f() lorem ipsum
not rlly
sure, locate() would give you the same location
but nothing stops you from having f and g take a "location" parameter as well
then you can use them from anywhere
having control mutations would be nice, ultimately the issue is that state are not such a good proxy for global mutables
but also you just like, return stuff
some language don't allow mutations at all and are fine with that
well yeah , haskell & friends are notable for encouraging taking and returning state objects
haskell is ... borderline because do notations allows a lot of things to feel like mutations
pretty close to typst's state actually
but yeah, for most stuff you don't need mutation
recursion with mutation really doesn't come often
to be fair though
global mutables arent that easy to solve anyway
rust has some problems with those too
global mutable states are baaaaad
rust's issue is safety, but for typst memoization is a real issue too
also, while global mutable state would be useful for the scripting part, it would not be particular nice for the document part because suddenly you need to ensure that all content is evaluated in the correct order, so that the mutations are in the correct order