On Wed, 23 Aug 2017 09:48:14 BST roger peppe <rogpe...@gmail.com> wrote:
> On 23 August 2017 at 09:40, roger peppe <rogpe...@gmail.com> wrote:
> > On 23 August 2017 at 09:23, MartinG <gar...@gmail.com> wrote:
> >> Thanks for the fantastic explanation folks.
> >>
> >> I wonder if I can ask advice on how to improve my use case.  I have a stru
> ct
> >> type that represents a state machine and each state is handled by a
> >> different method on that type, each with the same signature  I use a
> >> function variable to represent the current state and it is simply set to
> >> point at one of the methods.  The state is modified frequently, hence my
> >> problem.
> >>
> >> The options I can think of are:
> >>
> >> 1) Define another type (probably based on int or similar) representing the
> >> current state and switch on that instead of using a function type.  This
> >> feels inelegant and avoids using function types on one of the scenarios th
> ey
> >> seem to be designed for.
> >> 2) Define non-method related functions with a similar signature, but that
> >> also take my base type as an additional parameter.  I believe this will
> >> avoid the allocation, but also feels wrong because these functions really
> >> "belong" to my base type so should be methods.
> >>
> >> Any other possibilities?
> >
> > You could use method expressions.
> >
> > For example:
> >
> > https://play.golang.org/p/9H1n-CevNJ
> 
> Actually, it occurs to me that using method expressions in this way is
> actually more powerful, because the state can be manipulated independently
> of the state transitions. You could use this, for example, to fork the
> state machine and run it concurrently from an arbitrary state.

I find regular functions much cleaner (and a closer analog of
a digital FSM).  See for example:

    https://play.golang.org/p/MpX_lNT4rS

Basically

        type state func(inputType) state

        func reset() { return initial }

        func initial(i inputType) state {
                if needChange(i) { return stateOne }
                return initial
        }

        func stateOne(i inputType) state {
                // etc. etc.
        }

        func main() {
                s := reset()
                for s != nil {
                        s := s(readInput())
                }
        }

and so on. This is a Mealy machine, where the next state
depends on the current state and current input (in s/w not
much use for a Moore machine unless you are driving/simulating
some regular physical process, in which case you don't need
any input parameter).  If you want a side effecting FSM, pass
in a ptr to some mutable state.

Since these are essentially pure functions you can run them in
parallel. I tend to think use of methods requires more
boilerplate and is more obfuscating.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to