-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add #87: Guards #27
base: master
Are you sure you want to change the base?
Add #87: Guards #27
Conversation
I expressed some of my thoughts over gitter, but I'll summarize: It would be good to make a syntax that could later be subsumed by a more general meaning. Namely, treating guards as a type of machine. Implementation-wise this could be hacked in first, As a side note, I'm particularly allergic to the idea of order mattering. No matter what we do I would rather enforce the idea that cases must be disjoint---though they may all be false, only one may be true. Because that's undecidable at compile time, if more than one is true, then the one that runs is undefined. My motivation comes from Smalltalk, where I feel like there is a solution here using submachines. We need two things: delegating the received event to a predicate, and then selecting how to continue thereafter. Delegation can still be made to a C function. Eventually it would be nice to be able to delegate to a machine, but we aren't there. The C function could return true/false, or send an event. I prefer the latter, because it preserves the FFI semantics at virtually no runtime cost, although it complicates the required order of execution. Continuation can be done in the same spirit as Smalltalk: by deferring to another machine. I think the main hangup here is concrete syntax, so I'm going to wander off on a tangent here. Currently, we lack good concrete syntax for sending events to machines, and for getting responses. Sending is postfix, like a method call (which is an apt analogue; in spite of events carrying data, each could be regarded as a method whose data are its arguments). However, that's for concrete events. We have no syntax for variable events. This isn't bad (consider the case of point-free functional programs, or stack-based languages like Forth), but it means that the only place an event is available is as an implicit argument within a side-effect list. Side-effects are either function calls (which may ignore the implicit argument) or events (which universally ignore it). So, if we want execution to depend on an event, it ought to be within a side-effect. I propose hijacking the arrow and become syntax (forbidding nested side-effect lists, at least for now), overloading them so that within a side-effect, the arrow points always to another machine (a named one or an anonymous one) and denotes capturing whatever queue was filled by that side-effect, and giving it to that machine. To stick to the running example, I'm thinking something like this:
Alternately:
While this has a bit of a funny syntax, it would have several benefits:
Thoughts? Rebuttals? |
That's a lot of stuff. Do you think that returning a state in the calling machine is a thing we're going to have in submachines? That seems...not right to me. |
My comment on the "Alternatively" approach is that I don't think it adds a lot to what we already have. The impetus for this is to make conditional dispatch simpler to express in Smudge, and that option still requires the user to call a nebulous Granted, it makes it more explicit which events ought to be sent by that function, but I don't think that's enough of an improvement over the existing syntax to justify a change. |
First, to quickly address your comments about the alternate version, that was just demonstrating that a submachine solution could work either way. Now, regarding returning states. I agree, and I wasn't sure how to go about that. I was more feeling out than advocating. We need two things: 1) a way to choose which events to send, and 2) a way to choose which state to transition to. 1 is simpler, and I feel like many different approaches could be satisfactory. 2 is harder to do well without events. To start, I believe that to do this "right" requires subverting the queue semantics by hijacking new events. That is, the decision must be made based off of information local to the event handling, not information available to the whole machine, like a local queue. Submachines can do that. But returning a state violates a kind of abstraction barrier. My ambition here is to generize this problem in order to create an equivalent to the
Or equivalently,
This would be like a "local state", one the machine couldn't normally wind up in, but can occupy temporarily in order to make a local decision. The syntax chains arrows, and the semantics eats the in-scope event and any local queue. Is that an improvement? |
Oh, even better name for that last syntax proposal: "substates". |
Now I'm wondering if there is a way to have a syntax sugar over that, like |
Alright, I like the substate thing, and adding sugar to the first of the 2 substate proposals is a good approach. I'm not a huge fan of the bit where we add events though. What if the user wants an event called true? Maybe we can scope the event to just the substate? Submachines inherit the events of their parents, so that would be a difference from a special case of submachines. I think it's worth while to also include a default case, maybe named Here's a suggestion for the sugar as a starting point:
|
No description provided.