For a while now I've been a pretty big convert on the look of dots for member selection. It's not just that it's more standard--I think it's visually better. It also lets you be reassured that when you see a slash in a path, that the thing to the left of that slash was a function:
foo.bar.baz
;
; ^-- I may not know what foo.bar.baz is, but at least I know that
; foo and foo.bar are *not* functions
foo.bar.baz/mumble
;
; ^-- Under the convention that slashes are for refinements only, I
; can tell the author intends that (foo.bar.baz) must be a function
foo.baz.bar/
;
; ^-- With Ren-C's path generality, you can even decorate a case
; without refinements to show it's a function.
It Hasn't Been A Rule, but...
So far Ren-C has been allowing you to use slashes wherever you historically could. So the new rules were only applying to dots--restricting them on not being usable on functions.
append.dup [a b c] [d] 2 ; this would cause an error, for instance
However, you could still pick members out of objects with slashes:
>> obj: make object! [field: 10]
>> obj/field ; not obj.field
== 10
I had a feeling this might be prohibited eventually...though it would need to be possible to make Redbol emulation work. So there'd have to be some kind of flag for allowing it.
...But Now, I Might Have A Good Reason To Enforce It
The reason is that in trying to do a good job of building an extensibility mechanism for member selection, it is difficult to make that mechanism able to communicate information about specialized functions in a "light" way.
When pathing is done hardcoded in the evaluator, it can do little sneaky tricks to push the words of refinements onto a stack. It doesn't have to create an entirely new specialized function.
But once you're using a generic interface to usermode functions which can extend PICK*
and POKE*
, that interface has to speak in "reified" forms. We have partial specialization so these refied forms exist... I just feel like what's happening in that case isn't "picking" or "poking". And it's tying my hands to make anything efficient if we say that path dispatch runs through code which might be usermode.
The Flag Will Be Introduced Gradually
I've been experimenting with the flag turning itself on automatically, and giving you a warning. So you only hear about it the first time.
>> obj: make object! [x: 10]
>> obj/x
The PATH! obj/x doesn't evaluate to an ACTION! in the first slot.
SYSTEM.OPTIONS.REDBOL-PATHS is FALSE so this is not allowed by default.
For now, we'll enable it automatically...but it will slow down the system!
Please use TUPLE! instead, like obj.x
== 10
>> obj/x
== 10
What happens when you enable the flag is that it actually turns any PATH! with no ACTION! in the first slot into a TUPLE!, and then permits you to use refinements in TUPLE!s like append.dup
. This is because I'm avoiding creating a separate extensibility mechanism for paths...it just does the not-easy-to-optimize extensibility.
I haven't committed this, and I'd be phasing it in slowly. But as it's phased in, the performance of paths for member selections vs. tuples will degrade. So it's worth knowing about.