02-10-2014 12:16 AM
I've been really busy and finally found time to respond...
AristosQueue wrote:
Daklu wrote:
I don't see execution locking as a use case with much value beyond convenience (requires less code) or a band-aid (work-around to poor design or actor abuse).
That to me is more than sufficient value. It is an absolute gem in real-world situations.
My favorite example is
* set minimum
* set maximum
* set value
* set range (min and max as a pair)
* set range and value
If the author of the class is reaaaaaaally forward thinking when building a by-ref architecture, he will build all five of these. But more commonly, only the first three of these will be exposed. That's the nature of programmers. Minimum returns an error if it is greater than the current Maximum; value returns an error if it is out of range. That is a more than sufficient API for the by-value class, and when it is by-value, it can easily be wrapped in a helper function for setting both ("If newmin > curmax then set max first else set min first. Then set value."). People who think of the by-ref case as anything special are very rare until long later when it bites them.
We have very different ideas about what a good api looks like. I don't implement compound operations like a Set Range function in the api unless the hardware directly supports the function. Why? Because people have different requirements about how that function ought to behave, depending on the situation.
Suppose the current value is 10 and the current range is (8, 12), and someone tries to set the range to (15,20.) Should it recognize the current value is not in the new range and return an error? Should it change the range and change the value to 15? Should it change the range and leave the value at 10? All three options are valid and could be considered correct depending on the situation. If I implement the function to do one of those things, then not only is my function useless for those who need one of the other implementations, but it's going to cause confusion for those who assume I have implemented it to behave in one of the other ways.
And as long as you're trying to make it more convenient for end users, why aren't you providing a "Set Minimum and Value" and "Set Maximum and Value" functions?
BTW, you keep referring to by-ref designs. Can you describe what part of your system is by-ref? Are you sharing the object controlling the hardware among multiple actors?
AristosQueue wrote:
Daklu wrote:
Wrapper --> Device MHL: Set A=1; Set B=2; Set C=3; Take Measurement;
Device Subactor --> Device MHL: <SomeMsg>
...
Thanks to the custom message written by a graduate student who didn't understand the intracies of the instrument actor, your expensive system has just burned out, the grant money dried up, tenure was denied, and you're standing on a freeway offramp with a cardboard sign that reads, "Will conduct experiment for food."
If any one of those four messages takes a long time to execute, then any one of them could have caused the burn out on its own and the *handling* of such messages would need to have turned into a state handling system within the actor itself. In other words, if this happens, the burn out is NOT the grad student's fault. It is the author of the original actor's fault for making that handling synchronous. If it takes 20 minutes to execute Set B=2, that should have been turned into a "post a message to my actor core to begin moving to 2" and then get the synchronous code out of the way.
I agree the burn out could have occurred anyway--it's an inherent risk that can't be avoided because it takes time for information to travel from point A (the sensor monitoring loop) to point B (the actor's MHL where the measurement is actually taken.) Originally I was thnking even if each Set message only took 0.1 seconds, bundling the 3 Set messages with a Take Measurement message still exposes the system to 0.3 seconds of risk it wouldn't be exposed to than if all four messages are sent separately. But if all four messages are sent at the same time it's--for practical purposes--the same as one message bundling all four messages. Yeah, so that scenario is a bad one.
02-10-2014 11:01 AM
Daklu wrote:
I don't implement compound operations like a Set Range function in the api unless the hardware directly supports the function.
Hardware? Who said anything about hardware? I'm talking Numeric Control. Or any other field validation. Maybe database table definition.
Daklu wrote:
BTW, you keep referring to by-ref designs. Can you describe what part of your system is by-ref? Are you sharing the object controlling the hardware among multiple actors?
Any talking over a refnum, including actors, is by-reference programming. That is distinct from "by-reference objects" which is a particular reference architecture.
02-10-2014 11:07 AM
Daklu wrote:
And as long as you're trying to make it more convenient for end users, why aren't you providing a "Set Minimum and Value" and "Set Maximum and Value" functions?
A) What? Those two functions are both listed above.
B) Your pronouns in this sentence are problematic. You're combining multiple roles.
You-meaning-AQ-developing-architecture is trying making more convenient APIs.
You-meaning-random-developer-writing-actors might be trying to build a good API but isn't taking any of this discussion into account because he/she has never throught about the problem.
Therefore the real goal is "You-meaning-AQ-developing-architecture is trying to make it easier for you-meaning-random-developer-writing-actors to accidentally write maximally convenient APIs for end users."
I explained how this API comes about in some detail already.
02-10-2014 05:22 PM
AristosQueue wrote:
Hardware? Who said anything about hardware?
Uh... you did, in post 21. A trivial example is a hardware API that has a message for "Set Option A", "Set Option B" and "Set Option C".
I thought your min/max/value example was intended to be a more concrete instance of a hardware api. I'm sorry I misunderstood.
AristosQueue wrote:
Any talking over a refnum, including actors, is by-reference programming. That is distinct from "by-reference objects" which is a particular reference architecture.
So in post 25 where you said, "If the author of the class is reaaaaaaally forward thinking when building a by-ref architecture..." you're not referring to the architecture of the entire application or expecting the actor to be used as a by-ref object, but rather the actor uses a reference of some sort internally, such as a hardware device or a database refnum, correct? Assuming yes, it's still not quite clear to me why you've made a distinction for actors that use references internally. As far as the rest of the world is concerned, they shouldn't care what goes on inside the actor. Why does it matter if the actor is purely by-value or includes a refnum inside it?
I'm really trying to understand the use case where allowing callers to create arbitrary execution locks lets you do things a wrapper doesn't, but I'm not seeing it. Going back to your min/max/value example, let's suppose the author wasn't forward thinking enough to provide a Set Range method or message. You can certainly create one, but inside it's going to use Set Min and Set Max, so it's not much different than sending Set Min and Set Max as separate messages.
AristosQueue wrote:
B) Your pronouns in this sentence are problematic. You're combining multiple roles.
I wasn't combining pronoun roles, but I wasn't very clear either. I meant you-meaning-AQ-proposing-the-API-that-should-be-written.
AristosQueue wrote:
A) What? Those two functions are both listed above.
No they aren't. In your example there are three settings we can adjust: min, max, and value. You proposed three methods for setting them independently,
Set Min
Set Max
Set Value
and two methods for setting some combination of them,
Set Range (min and max)
Set Range and Value (all three settings)
The two methods I suggested are the combinations you left out from your api,
Set Min and Value
Set Max and Value
You claimed Set Range and Set Range and Value should have been written, but ignored the other two combinations. Why? Didn't think about it? You expect setting min/max and value at the same time is an infrequent operation? Setting min/max and value in a single transaction is invalid? I'm just curious why, in your mind, they weren't important enough to be included.