3 ms·
I really don't mean to be dismissive of your contribution, so please take this in the best light possible: Yuck. Use continuations with anonymous fns that tell
by sillysaurusx 6y ago
I really don't mean to be dismissive of your contribution, so please take this in the best light possible:
Yuck. Use continuations with anonymous fns that tell the GUI what to do next. The state is in the closure implicitly!
I wish I had an articulate counterargument, but just look at this: https://xstate.js.org/docs/#promise-example https://xstate.js.org/docs/#promise-example
Statecharts are a formalism for modeling stateful, reactive systems.
Beautiful is in the eye of the beholder, and never moreso when the programmer is blind to the cost of repetition and state.
Arc got it right. http://www.paulgraham.com/arcchallenge.html http://www.paulgraham.com/arcchallenge.html
Write a program that causes the url said (e.g. http://localhost:port/said http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying "click here." When that is clicked it should lead to a third page that says "you said: ..." where ... is whatever the user typed in the original input field. The third page must only show what the user actually typed. I.e. the value entered in the input field must not be passed in the url, or it would be possible to change the behavior of the final page by editing the url.
(defop said req
(aform [onlink "click here" (pr "you said: " (arg _ "foo"))]
(input "foo")
(submit)))
- diggan 6y agoIn no way was that dismissive, I thank you for providing another perspective, that's always welcome in my book! I don't necessarily agree with all the implementation details of xstate, in particular to where the logic tend to be located in practice, and the reliance on the Actor model for many things in the wild. I rather try to guide people to Statecharts as a paradigm overall, and if you happen to use JS, I think xstate is probably the most mature library there. But as all libraries/frameworks, they can be over-relied upon. If you're in the Clojure/Script world, which is where I mainly locate myself, then https://lucywang000.github.io/clj-statecharts/ https://lucywang000.github.io/clj-statecharts/ is all you need and so far the library I've had the best luck with.
- sillysaurusx 6y agoI came back to edit my comment and remove the harsh words, but you left a very kind response. Sorry. This is actually a fascinating example: https://lucywang000.github.io/clj-statecharts/docs/get-started/ https://lucywang000.github.io/clj-statecharts/docs/get-start... ... because it highlights precisely my criticism. ;; define the machine (def machine (fsm/machine {:id :lights :initial :red :context nil :states {:green {:on {:timer {:target :yellow :actions (fn [& _] (println "transitioned to :yellow!")) }}} :yellow {:on {:timer :red}} :red {:on {:timer :green}}} :on {:power-outage :red} })) I just ... don't understand why anyone would do it this way. The code itself already says what to do. Adding this sort of data only subtracts from clarity with no additional flexibility. You might argue that the data model makes it flexible. But I look at that and go, that's what a function is for. The only thing you need is `(println "transitioned to :yellow!")` inside of a function called transition-to-yellow, or if you're feeling adventurous, a function called transition-to which takes yellow as an argument.
- Folcon 6y agoFrom my perspective, it's better as a data structure because I can do more with it. It's much easier for me to introspect, and I can easily build dynamic state-machines by changing a data structure, take a look at interceptors[0] as an example. There the stack is dynamically alterable based on what is within the request and each piece of middleware can look at the current context, analyse it and behave accordingly. I write a lot of workflow based systems with dynamically changing functionality based on user input. This sort of thing is invaluable in that context. - [0]: http://pedestal.io/guides/what-is-an-interceptor http://pedestal.io/guides/what-is-an-interceptor
- diggan 6y agoI guess your comment highlight the real problem of trying to describe tools for handling complex scenarios with just simple examples, they often don't make sense because the first thought is always "Why not just have one function instead of all of that?". If you're just printing some text to the console when doing one thing, then surely one function is enough. Once you start having some state and different views depending on values, normal state machines might be enough. But eventually, your application might grow so much in scope that you want to have state machines nested in other state machines, and you want to avoid the classic "state explosion" that you end up with when using state machines, then Statecharts are a very useful tool. But before that, do the simplest thing that can work for your use case, complexity is evil and all that... Statecharts are simply a tool for handling complex and intertwined state, not for simple stoplights. Unless those stoplights are all connected to each other and also control/read other state machines, then Statecharts might be right for you. Not sure if you took a look at the links I put before, but the https://statecharts.github.io/ https://statecharts.github.io/ website has a "Why should you use statecharts?" section with small descriptions and links to more elaborate information as well. Might give you a better view than what I can give.
- Folcon 6y agoThank you for this, I didn't know this existed for clojurescript =)... Much appreciated!
- davidkpiano 6y agoXState creator here, what kinds of implementation details do you not agree with? Curious to know.