3 ms·
Yet another idea. SEND(VAR c: CHANNEL OF T; v: T) and RECEIVE(VAR v: T; VAR c: CHANNEL OF T), i.e. just a single send/receive, not built-in select, and data fl
by Rochus 3y ago
Yet another idea.
SEND(VAR c: CHANNEL OF T; v: T) and RECEIVE(VAR v: T; VAR c: CHANNEL OF T), i.e. just a single send/receive, not built-in select, and data flows from right to left.
SELECT( { VAR vN: Tn; VAR cN: CHANNEL OF Tn [;] } { VAR cM: CHANNEL OF Tm; vM: Tm [;] } ), i.e. distinguish receive or send by the order of value and channel, instead of an explicit number or a boolean separator. Still a boolean param could be added to allow non-blocking selects.
- 082349872349872 3y agoThis looks like it may wind up reinventing select(2), for which one should maybe consult poll(2) to see where that approach wound up. The underlying problem is that Oberon lacks an unordered select (WHILE ELSIF comes close but has the unfortunate —in this case, but not for many actor scenarios— repetition). Maybe something could be done with a CASE Poll(...) OF ... END? If life were a Ponyhof, I would ask for something along the lines of: PROCEDURE sendit(text: STRING): BOOLEAN; VAR fail: BOOLEAN; FailChan: CHANNEL OF BOOLEAN; BEGIN fail := FALSE; FailChan := After(TimeOut); SELECT SENDABLE(TxChan) THEN SEND(TxChan, text) | RECEIVABLE(FailChan) THEN RECEIVE(fail, FailChan) END RETURN fail END sendit; but that'd obviously be too large a change.
- Rochus 3y agoThanks. I'm neither happy yet with the SELECT() function. Concerning your proposal, I would rather not introduce a completely new control structure. But one could - like Wirth with the type CASE statement in Oberon-07 - reuse the WITH statement like: WITH SEND(TxChan, text) DO | RECEIVE(FailChan, fail) DO END where I would just have to change the Guard a bit like Guard = qualident ':' qualident | SEND ActualParameters | RECEIVE ActualParameters and even ELSE is available. What do you think?
- dfawcus 3y agoI had a read of the page after you updated it. I find the proposed SELECT function to be unwieldy, to the extent that one would really want some syntax added instead. Assuming I'm correctly inferring from the above, the WITH looks better. Presumably one could have multiple SEND and/or RECEIVE function clauses in the WITH statement, so acting as an equivalent to the Go Select? What would ELSE do? It it acting the same as the default clause in a Go select, i.e. allowing for a non-blocking call? The one other question with the above is how would one detect a closed channel when the RECEIVE clause hits?
- Rochus 3y ago> Presumably one could have multiple SEND and/or RECEIVE function clauses in the WITH statement, so acting as an equivalent to the Go Select? Correct. Here is the specification: https://github.com/oberon-lang/specification/blob/master/The_Programming_Language_Oberon%2B.adoc#with-statements https://github.com/oberon-lang/specification/blob/master/The.... You can have an unlimited number of guards. > What would ELSE do? It it acting the same as the default clause in a Go select, i.e. allowing for a non-blocking call? Correct, that's the idea. > how would one detect a closed channel when the RECEIVE clause hits? EDIT: I added yet another build-in procedure which returns the closed state of a channel. A blocking WITH would continue if no channel was ready to communicate, but at least one was closed.
- 082349872349872 3y agoI like repurposing WITH, as it already had the semantics of selecting a single branch out of an unordered collection of guarded branches (or the ELSE as complement).
- Rochus 3y agoThanks for the feedback. What do you think about the SELECT function? Should I drop it in favour of the extended WITH statement?
- 082349872349872 3y agoI would drop the SELECT as proposed, in favour of extended WITH. A potentially useful SELECT function (if runtime-variable communication graphs are of interest, which they may not be?) would be one which took an array of channels and directions (à la poll), or similar data structure, as a parameter. Edit: I also suspect that the semantics of channel closure are unlikely to be as simple as you are hoping. (but maybe do something like tcp sockets, and force a consumer to drain the channel before orderly closure?) (between array riders and lack of display access to variables in enclosing scopes, OBERON SA seems to have evolved in a direction converging upon C?)