How to make objects?

What I mean is, how can I create something which has methods which can access shared state?

Currently this is the approach I’ve taken:

#let new-vault(state: (:)) = (
  with-notes: (..sink) => {
    let notes = state.at("notes", default: ()) + sink.pos()
    new-vault(state: state + ("notes": notes))
  },
  with-style: fun => {
    let styles = state.at("styles", default: ()) + (fun,)
    new-vault(state: state + ("styles": styles))
  },
  // ...
)
#let vault = new-vault()

#vault = (vault.with-notes)(
  // ...
)
#vault = (vault.with-style)((body, ..sink) => {
  // ...
})

This works, but it has that ugly (dict.method)(args) syntax. Also, having to reassign every time isn’t the best, but I doubt there’s anything to be done about that. Is there a better way to get bundled state and methods than this?

1 Like

Hello @gabe!

I believe it is enough to rely on the internal get and update methods of the state, see “Managing state in Typst”.

Instead of defining internal methods as a dictionary, you simply define them as functions in your library.

#let vault = state("vault", (notes: (), styles: ()))
#let notes(vault, notes) = context {
  let v = vault.get()
  v.notes = v.notes + notes // or something else
  vault.update(v)
}
#let styles(vault, styles) = ... //same

Perhaps, there is something I misunderstood in your question so don’t hesitate to tell me!