#How to mutate a state across function calls?

45 messages · Page 1 of 1 (latest)

gloomy flower
pseudo beacon
#

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

gloomy flower
#

Thanks. But update() can't return the value, but just provides the value to its callback...

pseudo beacon
#

yes, this is a limitation due to how state/mutations happen in typst

gloomy flower
#

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..

pseudo beacon
#

there's state + locate right now

gloomy flower
#

okay, thanks

pseudo beacon
#

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)

gloomy flower
#

that would be very useful

pseudo beacon
#

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

rugged flicker
#

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

gloomy flower
#

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
rugged flicker
#

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

pseudo beacon
#

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

rugged flicker
#

well yeah , haskell & friends are notable for encouraging taking and returning state objects

pseudo beacon
#

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

rugged flicker
#

to be fair though

#

global mutables arent that easy to solve anyway

#

rust has some problems with those too

pseudo beacon
#

global mutable states are baaaaad

rugged flicker
#

yeah

#

lol

pseudo beacon
#

rust's issue is safety, but for typst memoization is a real issue too

cunning prairie
#

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