Live data from Hacker News

FSL: A programming language to make complex finite state machines easy to create

fsl.tools

51–60 of 74 posts

Re: FSL: A programming language to make complex finite state machines easy to create

#51
post #33

Earlier quoted context omitted.

Hi, I'm the author. I just haven't made the site because the repo is complete I'll go change the site. It had never been released, announced, or indicated. This is being shared because there's a complete programming language in active use by many people

Where is the repo? Its not available at all from the website

So the thing is, FSL isn't released or announced. You're actually meant to be looking for the main implementation, `jssm`, which has been out for seven years. FSL is the new re-bake I started a year ago, and haven't gone public with yet.

https://github.com/StoneCypher/jssm

It's under the github link under libraries

I added some top material to the site to make what's happening clearer

Re: FSL: A programming language to make complex finite state machines easy to create

#52
post #26

I feel like we don’t need a novel language for this. There’s already a pretty-well-known language that’s almost a DSL for “making complex finite-state machines easy to create”: Erlang. I know that sounds wacky, so let me pitch you on that idea :) In ‘primitive’ Erlang (i.e. Erlang without OTP), each FSM state is just a function, that can contain its own event loop (`receive` statement) to accept input, and then can t…

> I feel like we don’t need a novel language for this.

Well, there's like 50 others, many of whom are in heavy use in industry, so, I guess I feel like a lot of people think this is useful.

.

> I feel like Erlang is already a great language — almost a DSL — for “making complex finite-state machines easy to create.”

Erlang is almost my favorite language.

I've tried using both of its finite state machine libraries. I do not find them to be usable. The results are extremely verbose, and if one goes over around 30 states, I cease to be able to debug them.

The natural implementation of the TCP/IP state machine in FSL is eight lines; 315 bytes. The TCP/IP Erlang state machine example floating around is like ten times that size.

I find debugging that thing exhausting.

.

> It’s very easy to write a static analysis pass to verify that a primitive Erlang module like this constitutes an FSM “and no more”

It's not clear to me why you would want this

.

> Honestly, ignoring all the stuff about concurrency, Erlang source code / BEAM bytecode is an almost perfect abstract machine for reifying various computational formalisms

It can't implement anything without Okasaki juggling. You and I are in strong disagreement here.

FSMs are a great example. You either need to reach outside the Beam VM with `hipe_bifs:array` or you need to copy the entire machine state every time you want to mutate it.

.

> And, if I were implementing something like Cloudflare’s Edge Workers “but for FSMs”, it’d be an extremely easy decision to standardize on (a restricted, static-analyzed at submit-time sub-ISA of) BEAM bytecode.

At Cloudflare's scale, the inability to implement mutably would become a serious performance problem.

Re: FSL: A programming language to make complex finite state machines easy to create

#53
post #26

I feel like we don’t need a novel language for this. There’s already a pretty-well-known language that’s almost a DSL for “making complex finite-state machines easy to create”: Erlang. I know that sounds wacky, so let me pitch you on that idea :) In ‘primitive’ Erlang (i.e. Erlang without OTP), each FSM state is just a function, that can contain its own event loop (`receive` statement) to accept input, and then can t…

I do not know anything about erlang, but I’m intrigued about your proposal. Could you make a github repo with an example project implementing your solution?

There are two FSM implementations in the standard library. Just use those.

Re: FSL: A programming language to make complex finite state machines easy to create

#54

What's the significance of the history of Japan to this project?

There isn't any. This site wasn't meant to be public yet.

I just posted some youtube videos I enjoy to make sure the build toolchain was placing youtube videos correctly.

Re: FSL: A programming language to make complex finite state machines easy to create

#55
post #26

I feel like we don’t need a novel language for this. There’s already a pretty-well-known language that’s almost a DSL for “making complex finite-state machines easy to create”: Erlang. I know that sounds wacky, so let me pitch you on that idea :) In ‘primitive’ Erlang (i.e. Erlang without OTP), each FSM state is just a function, that can contain its own event loop (`receive` statement) to accept input, and then can t…

> I feel like we don’t need a novel language for this. Well, there's like 50 others, many of whom are in heavy use in industry, so, I guess I feel like a lot of people think this is useful. . > I feel like Erlang is already a great language — almost a DSL — for “making complex finite-state machines easy to create.” Erlang is almost my favorite language. I've tried using both of its finite state machine libraries. I d…

> I've tried using both of its finite state machine libraries.

I'm not talking about gen_fsm or gen_statem — note how I said "without OTP" above. I'm talking about writing Erlang the way it was originally conceived before proc_lib existed — where each process has a module that's exclusively responsible for its own receive loop, rather than being a delegate module for a generic receive-loop manager framework (proc_lib).

That kind of Erlang code produces simple, easy-to-analyze bytecode. It doesn't integrate well with supervisors or whatever, but interoperation with the rest of the Erlang/OTP ecosystem isn't the point. You don't call into arbitrary slap-dash non-formalized libraries within code that's supposed to represent a mathematical formalism. (E.g. you wouldn't call an arbitrary library from within a PEG grammar DSL. This is why e.g. Yecc's Erlang callbacks happen after parsing, rather than instead of parsing. If they happened instead of parsing, you'd break the formalism of the parser, and wouldn't be able to trust that your grammar does in practice what it was proven to do in theory any more.)

Instead, you create your own little world inside the formalism, that maybe imports a few reusable pre-proven abstractions compatible with the formalism, or that opaquely maps into pre-proven abstractions that exist within the prover (e.g. Z3's bit-vectors.) Abstractions are available in most-any other interpreter / prover / generator / whatever-er for the same formalism.

> FSMs are a great example. You either need to reach outside the Beam VM with `hipe_bifs:array` or you need to copy the entire machine state every time you want to mutate it.

Why are you mutating something outside the FSM from within the FSM? If the only state isn't "the state" (i.e. what box you're in on the FSM diagram), then what you have is not an FSM (in the computability-theory sense) any more.

The point of an FSM is to reduce the "power" of reasoning needed to prove things about the abstract machine — and so to be able to make guarantees that Turing machines cannot make, like being able to prove termination — by constraining what side-effects an operation within the abstract machine can have. An FSM can only switch its state among one of a usefully-enumerable number of options, e.g. the set of functions in a module, or the possible values of a single machine-register. A pushdown automaton can only switch its state among the sets of all possible sequences of such usefully-enumerable options (i.e. stacks of FSM states.) Etc.

(Note that Erlang/OTP's gen_fsm and gen_statem aren't FSMs in the computability-theory sense, since they pass along a state variable. They can be used as such if you don't put anything in that variable — or even if you put a scalar in that variable and constrain its size — but even if you don't use it, the resulting bytecode still passes that variable along in a way that makes it harder to translate the bytecode into prover lemmas. But all the remote-call stuff to proc_lib code that's not part of the proof already makes that nigh-on impossible, so....)

I think we might be talking about very different things here but both calling them "FSMs." I'm talking about how Erlang's native syntax is really good at expressing https://en.wikipedia.org/wiki/Deterministic_finite_automaton (like non-backtracking regexps) succinctly. What are you talking about?

Re: FSL: A programming language to make complex finite state machines easy to create

#56
post #33

Earlier quoted context omitted.

Where is the repo? Its not available at all from the website

So the thing is, FSL isn't released or announced. You're actually meant to be looking for the main implementation, `jssm`, which has been out for seven years. FSL is the new re-bake I started a year ago, and haven't gone public with yet. https://github.com/StoneCypher/jssm It's under the github link under libraries I added some top material to the site to make what's happening clearer

Ok, thanks, I think there was some confusion that you submitted a non-functional webpage to HN.

Re: FSL: A programming language to make complex finite state machines easy to create

#57
post #56

Earlier quoted context omitted.

So the thing is, FSL isn't released or announced. You're actually meant to be looking for the main implementation, `jssm`, which has been out for seven years. FSL is the new re-bake I started a year ago, and haven't gone public with yet. https://github.com/StoneCypher/jssm It's under the github link under libraries I added some top material to the site to make what's happening clearer

Ok, thanks, I think there was some confusion that you submitted a non-functional webpage to HN.

To clarify for anyone else, the poster and the author are not the same person! The poster looks like they discovered this, and posted it.

Re: FSL: A programming language to make complex finite state machines easy to create

#58

Anyone with experience using finite state machines in production apps want to share their experience? I love the concept, but not sure how to implement a POC so my teams can see the value. We have a few areas that have a ton of dense business logic, and I think something like xState could be beneficial.

It really depends on the quality of the underlying state machine library, and whether you're actually using them at a good time.

Obviously, as the author of one of these things, I'm a pretty big fan of FSMs. And, y'know, even though the entire point of mine is to be easy and convenient to use, I still don't use it very often.

Most jobs aren't for FSMs.

Finite state machines aren't well applied everywhere. There are a lot of cases where you could use a finite state machine, but shouldn't. A chess board is an example: it is a well described state, there's clear right or wrongness to changes, there's no ambiguity or intermediate states, etc. However, managing a board that complicated, dealing with rules like en passant and castling, it'd be a hassle. You don't get enough value out of it, and so it doesn't matter what you're using. Yes, FSMs can handle chess; no, it's not a good choice IMO.

But then, there are times when it's well applied.

When it's something where an FSM is a good choice, and you've used a low-hassle library, my opinion is that they tend to make systems night-and-day simpler.

Consider creating a finite state machine for the state of any single given payment. Now, when the external actor changes their process, the FSM wedges and you get notified, instead of switching to a state that used to be impossible and isn't anymore, in software that isn't ready for that. That's a huge level of immunity to large classes of bugs.

My opinion is that FSMs are well applied when the cost of a state reaching a bad configuration is very high.

You wouldn't use them to manage the image in a paint program.

You would use them to control the airplane's jet being on or off.

If you're in a situation where they're well applied? Now it's going to matter a lot which system you actually use.

I have great respect for `xstate`, by example. It doesn't fit my preferences, but it's fast, robust, and largely bug-free. It's reliable, easy to work with, well documented, and has a good solid community. If you use `xstate` you'll have a good time, most likely.

By contrast, at a previous ruby job, we used a gem I'm not going to name. It was ahem not my favorite. It was slow, it was pretty easy to get it wedged when it shouldn't be, it relied on side state things as storage that weren't fundamental to the language, it was cryptic when it failed, et cetera.

Later, at that job, we switched to a different state machine gem. It was pretty hassle-ful; the datastructures needed to be manually converted because there was a slight difference in how the two gems saw the job which meant automatic conversion wasn't practical.

But we were sure glad we did! Once the other FSM library was in place, things were a breeze, the system was much easier to understand, and to control.

There's more to it than good or bad, though.

If I couldn't use my own, what would I use?

If it was business logic, I'd probably use `stent`. To me it's the easiest to debug, and seems the most robust. Their tracing tools are quite impressive.

If it was a redistributable react control, I'd probably use `fsmx`, or embed a cut-for-case one. Stent is 288k. FSMx is 24k. If it's typescript, I'll probably use `fsmachine` instead, which is 28k.

If I need transactionality, `edium` is my only real world choice.

If I need something that's easy for junior programmers to understand, I'll probably use `javascript-state-machine`.

If I need something to create documentation that's easy for non-programmers to use, it's very likely to be `state-machine-cat`.

And of course, if I could use my own, I'd prioritize it when doing less labor or having a shorter representation of the machine is better. For me, that's pretty much always shrugs `xState`'s light switch is 13 lines; `jssm`'s is a one-liner that's shorter than `xstate`'s import.

So.

What I would recommend is that you pick one that graphs for you, like `stent` or `xState` or `jssm` or `state-machine-cat`, and just try drawing out a rough of your business logic.

Maybe it's well implemented in a state machine. Maybe it isn't.

But once you've tried, it's usually pretty obvious which one it is. And it can be fun to try, y'know? New languages are neat.

If you have a bunch of little moving pieces that follow complicated rules and can't be wrong, there's a pretty solid chance that state machines are for you.

They're one of those tools that the right time isn't common, but when it is the right time, holy WOW do you want them

Re: FSL: A programming language to make complex finite state machines easy to create

#59
post #43

Since I'm here, any tool recommendations for visualizing state machines, and state charts in particular? XState's [1] is ok but only works on the web and offers to export, and I found its layout algorithm a bit sub-par. Writing graphviz code by hand, or using google draw/draw.io/... gets painful very quickly. [1]: https://xstate.js.org/viz/

JSSM has JSSM-viz.

https://github.com/StoneCypher/jssm-viz

If you just want one to use, rather than to embed in your own software, The thing everyone's calling a live editor is actually the JSSM-viz demo. You can use that

https://stonecypher.github.io/jssm-viz-demo/graph_explorer.h...

It's kept outside of the main repo because, like xstate's, it's built on a transcompile of graphviz called viz.js, which is made with emscripten

It's several meg, and not many people want visualization, so I keep them in separate packages

You can get the graphviz code by hitting "dot" at the top, if you want to customize in ways the language doesn't know

Re: FSL: A programming language to make complex finite state machines easy to create

#60

This looks very nice. Currently I’m learning how to use @davidkpiano’s XState. How would you say this compares?

If asked to choose which JS/TS FSM I respect most outside my own, I would have a hard time choosing between `xState` and `stent`. I think it's an excellent choice.

David has done a better job of making a nice setup. His tooling is cleaner. `xState` is slightly faster than `jssm`. `xState` is much more widely used than `jssm` (several orders of magnitude,) meaning that it is more trustworthy. He has more tutorials. He has more community. His documentation is not literally on fire.

I believe that my testing is significantly better. My library offers more features, including some fun exotic stuff like stochastic search. Whereas we both offer datastructure consumers (and they're similar,) I also offer a string DSL that is regularly 1/20 the byte count of the datastructure implementation. Terseness matters a lot to me. My typescript support is better. I have a live editor which I find has high value for understanding and debugging.

I guess in my impression, my biggest thing is the string language (super dense, super easy) and his biggest thing is his community (you can ask people questions)

Otherwise, in my impression we're quite similar. We both offer all the standard things; we both offer a visualizer; our visualizers look pretty similar because they're built on similar underpinnings.

Being honest, I'd say he's winning. But, not by much, and there are clear reasons to choose one over the other according to preferences, so please try both.

Post reply on HN