putState?
Closed this issue · 5 comments
Is there a built-in parser, analogous to putState
(formerly, setState
) in Parsec
that sets the user state and returns nothing? Is there a mechanism to replace user state without performing an explicit mutation/side effect (e.g., userState.tags.push(...)
like in the examples in the readme)?
Nope. It's sort-of by design. In Haskell, there is no way to mutate anything at all, so you have to be able to replace the user state. In F# or similar, you can't just define properties on the state object willy-nilly either, so again you need to have a way to alter it.
In JavaScript though, I think it's not needed and keeping the same user state object throughout the parsing session has advantages. There is no problem of parallelism, since this is totally synchronous JS we're talking about. You need to allocate fewer objects, and there is no problem of erasing data other parsers need to function. It also just seems appealing in terms of API, since that way there is a single, unified method of modifying user state, and you can do it from pretty much any parser/combinator.
If you don't want to add/delete properties from the object whenever you want, you can always create a specific property, e.g. immutable
, and update only that property with a new object every time. The result is quite similar to a putState
parser.
But if you really don't like it, I can just add it in. Can you explain why it's important to you?
My reasoning is twofold: A putState
parser would make it really simple to port things from (F)Parsec. Second, I'd like userState
state to revert if the parser needs to backtrack, and that won't happen automatically if I'm always mutating it in place (right?).
@mgreenbe Interesting! I never really thought about reverting user state. And yeah, you're right, it's probably not possible unless I allow replacing user state in the first place.
Now that I see the reasoning, it's definitely something I'll add. The two techniques can be complementary.
Thanks! This will be a big help to me.
Now there is a replaceState
combinator that fulfills this role. It replaces the state in the context of the parser you're applying it to.