Historical Redbol did not have generic TUPLE!. So that meant it used paths for everything...whether you were specifying a refinement to a function, or doing a member selection out of an object, or coordinate out of a pair, or...whatever.
So far what Ren-C has done is to shift it such that tuples are for member selection, and pathing is for refinements only.
A new twist is that a terminal-slash in a path (e.g. the last element is a BLANK!) means "APPLY the action". This is especially helpful when wanting to run a non-isotopic action in the new "activated actions" model:
>> block: reduce [reify :print]
>> block.1
== #[action! {print} [line]]
>> block.1/ ["The terminal slash comes in handy!"]
The terminal slash comes in handy!
So if you have a non-isotopic action in your hand, the slash can run it. But under the current rules, your arguments and refinements need to go in a BLOCK!.
Terminal Slashes Could Provide Safety...
With the above, the pattern you would use to say you were going to run something like APPEND/DUP out of LIB would be this:
>> lib.append/dup [a b c] [d e] 2
== [a b c [d e] [d e]]
But this means that you're on the hook for simple tuple references running, which you may not have expected:
>> if integer? obj.something [print "What if SOMETHING is an ACTION! isotope?"]
Boo!
** Error: Some error coming from OBJ.SOMETHING running
One way of stopping this would be to say that if you were going to call a function that was a member of an object, you'd have to use a terminal slash, otherwise you'd get an error.
>> if integer? obj.something [print "Clearer error if it's an ACTION! isotope"]
** Error: OBJ.SOMETHING is an ACTION! isotope, use OBJ.SOMETHING/ if intended
That would make field selection on the whole feel "safer". But at the cost of looking at a lot of terminal slashes, and nowadays that also forces you to use APPLY and pass your arguments in a BLOCK!.
More Succinct: Allow PATH!s to Pick The Action, Too
If something like lib.append/dup is clearly an action (due to the use of refinements) it wouldn't need the terminal slash, like lib.append/dup/. You already know an action is being run.
So what if you said lib/append instead of lib.append/ ?
Of course, under such a rule, lib/append becomes conflated with a situation where LIB is a function and you're applying the /append refinement. This does break away from a rule like "slashes always mean refinements".
That kind of sucks...BUT...it's still far less conflated than it was before. Remember, historical Redbol used slashes for EVERYTHING.
The new rule could be "slashes always mean from here on out, what we're talking about is function invocation". So it's either picking a function to run, or narrowing it down by means of a refinement.
The advantage here system-wide would be that you could use field selection without worrying about it, as foo.bar, meaning "I want that field and I don't want any functions to run". If there's no slash, there's no invocation.
I almost feel like the weird exception is worth it, because it would save a lot of bulletproofing that would otherwise be required on objects. But it's also clearly a bit bent.
The Other Direction: Terminal Dot as Invocation Suppressor
There's a possibility for saying "this reference is not an invocation", which could apply to WORD!s and to TUPLE!s alike. That's the terminal dot.
>> x: append.
** Error: APPEND. reference ends in dot but it's an ACTION! isotope
It has one downside of kind of being close to being a comma.
But the bigger reason I don't like this is just the mental tax that comes into effect. It's the same as how I didn't like the creeping desire for correctness, meaning people putting colons in front of things in a fairly ad-hoc way. We'd like the obvious code to just work.
I think the LIB/APPEND compromise may be worthwhile to get this correctness-by-default situation.
Possible Objection: Value/Function Invariance?
We might say that forcing you to distinguish at the callsite whether you are calling a function or not, prevents you from taking something that was a plain value previously, and substituting it with a function that calculates that value.
Under this principle, it's a feature that you "don't know" if obj.something is an action isotope or not...and making you commit to which it is by saying obj/something is bad.
It's kind of a narrow case--since you have to know at the callsite if it's a function that consumes arguments. So it could only be argued for arity-0 functions. And if the function doesn't return the same value every time, you're subject to some semantic questions.
I think that the answer here is that "accessor" functions (getter/setter) wouldn't count in this, if they existed. They would use the tuple syntax but stay "behind the scenes".