From a terminology perspective, it would definitely be helpful if Rebol stuck to common names when things are common. It's unfortunate that Red is perpetuating calling Generic Functions ACTION!s.
Does your overall 'crap' verdict extend to the PORT! datatype concept and structure itself
In the moment, I was just speaking out of annoyance with the implementation. Failure handling was nearly non-existent, and authoring of correct code even impossible if you assume no failures. (I'd argue that the absence of a READ/PART in the TCP scheme is indicative of a kind of fundamental misunderstanding of how sockets work...but at least I have added that feature.)
The very broad idea of using generics is fine and likely appropriate: to be able to say write port data
instead of what most languages would get with file.write(data)
or socket.write(data)
, it's all right. When you're going for English-like syntax and trying to get the number of typed characters (and visualized glyphs) down, it seems like a sort of lower-limit.
But when you have refinements (e.g. /PART or /LINES on READ), where then only the file port implements it and it just gets dropped otherwise...it's very frustrating to look at it and have to ask:
- "How many of these refinements are there in the long tail? If more get added, will every existing PORT! be responsible for it?"
- "If code lives in the generic READ to handle something like READ/LINES regardless of port type, how can it be abstractly implemented to build the result block one string at a time vs. read the entire binary data at once?"
- "What does it mean when we can't take for granted the result of READ or WRITE will be bytes...e.g. in the progressive scenario of building a block above?"
It's very difficult to see how READ and WRITE can serve so many masters. So this seems to me to require at least some level of separation of a byte-stream transport layer which you can stack up, and then some other articulation for codecs (including streaming ones).
The READ/WRITE level in my view might be ideally a much more accessible way of doing C++ iostreams, with "insertion" and "extraction" operators. If you look at Boost.ASIO it does the same sort of thing as Rebol TLS, where you chain together a TLS stream on top of a TCP stream.
As for how you get from there to encoding or decoding Rebol structure, well maybe that's what codec design is for. And maybe you can attach codecs to ports (perhaps disabling READ and WRITE at the byte level so you don't muck it up, and only let you use LOAD and SAVE?)
There may be great potential for designs here, but someone has to do it. I was hoping it wouldn't be me. :-/