Closed itamarst closed 10 years ago
+1 - I ran into trouble with this because the example suggests rich inputs are not needed.
Thanks. I agree that this is a problem which needs to be addressed. So far I haven't come up with a plan that involves being able to get rid of IRichInput
and the related APIs/support code. The only hint of an idea that has occurred to me so far is that maybe there could be either an input in self.inputs.iterconstants()
or IRichInput.providedBy(...)
check to determine whether an input is merely an input symbol or a rich input object of some sort.
The idea of adding this kind of type checking doesn't hold any strong appeal for me so I'd to think of (or have suggested :smile:) a better solution. Perhaps in the process of writing more documentation about how to use rich inputs and why they're a good thing some further ideas will come up.
Ah ok, I was in the process of writing those checks. Should I not?
While perhaps IRichInput is a worthwhile thing, it seems like it would be easier for someone starting out, learning the library, to just use symbols, so it'd be nice to support both even if one were preferred.
I think it might be premature... or maybe not? Just because I implemented the feature doesn't make me an expert on it. :wink: I'm tempted to say that writing some documentation first makes more sense - on the other hand, adding the checks doesn't really commit machinist to anything (all mistakes can be fixed!). So if you'd like to pursue this, please feel free. :smile:
How about receive()
takes two arguments, a required input symbol and an optional rich object?
Separately, when writing docs (or code?) it might be nice to show (support?) the shorthand "just use the class of the rich input as the interface" case which covers the large number of users who won't want to write extra boilerplate.
@exarkun: Oh hm... I have half of a doc change in process, but it seemed really long and boilerplatey (and I didn't understand the point of IRichInput
or the inputContext
), so I got distracted by this so that the doc could be shorter. Hang on, will at least submit a work-in-progress PR.
@itamarst: I've no particular objection to having it take two arguments, but the symbol is already required to be the return value of the symbol
method on the rich object. It'd be the same checks anyway, right? (because machinist would want to enforce that the symbol passed matches the symbol returned by the rich object?)
I'm somewhat confused as to what you mean in the latter paragraph by "the class of the rich input as the interface" - doesn't the rich input object passed to receive
need to be an instance?
symbol()
from rich input requirements.receive(symbol, richobjects=[...])
i.e. you can optionally pass in a list of rich objects.@itamarst Oh, ok. I don't actually know what rich objects are for, exactly, so I don't know how to evaluate that, but that does explain the 2 parameters to receive. :) Thanks!
Yea, this discussion reinforces my hunch that documenting what rich inputs are for is a good first step. :smile:
The changes in the referenced pull request to make the documentation correct, though, do strongly suggest to me that requiring a rich input instead of just an input symbol, even in trivial cases, is annoying and should be fixed.
@exarkun Random questions based on my having no idea what rich inputs are:
If these don't make sense, apologies. Was just thinking of rich inputs as a box I need to ship stuff in. I understand in the USPS system why I need boxes for shipping things (so they don't break and they stack nicely), but I also prefer to buy things pre-boxed so I don't have to box them before sending them out.
Actually I'd prefer to have other people box AND ship things out for me. :)
Update: oh oops, you beat me by a minute. :) Well, let me know what I should do. The checks are almost done, but I'll go do something else for now.
is there a 1-to-1 mapping between symbols and rich input?
Nope. You can have multiple rich inputs for a single input symbol. An example of this is a state machine running some kind of negotiation over a network. The negotiation can fail because of an error, fail because the peer rejects your request, fail because of a timeout, etc. The state machine input for all of these might just be a failure
symbol. The rich input might be different for each in order to represent details about the failure (eg for logging, to let an output that generates a network message include correct parameters, etc).
if not, then maybe accepting both would work because the user doesn't always want to provide a rich input for all symbols?
This does seem plausible, maybe not in the way you meant :smile:. The application I have that uses machinist has both the many-rich-inputs-to-1-input-symbol case as well as cases where there really is no rich input (though it still uses them because the API requires it; iow, it has cases where it would be simpler if it were allowed to pass an input symbol instead).
Nope. You can have multiple rich inputs for a single input symbol. An example of this is a state machine running some kind of negotiation over a network. The negotiation can fail because of an error, fail because the peer rejects your request, fail because of a timeout, etc. The state machine input for all of these might just be a failure symbol. The rich input might be different for each in order to represent details about the failure (eg for logging, to let an output that generates a network message include correct parameters, etc).
Oh ok! That makes sense. Gives me a little more idea about what rich inputs are for anyway :)
Contrary to the example, rich inputs are required by the public API of the FSM. Personally I'd prefer not to have to create a whole bunch of
trivialInput
objects for cases where I really don't need rich inputs, but if that's not going to happen the example should be fixed.