Different Internal Names for Parameters in Function Spec

If a function calls an argument something like /ALL, you end up in an annoying situation of losing access to the default ALL. This ends up with me often writing things like:

foo: func [
    bar "some ordinary-named argument"
    /all "description of this"  ; comment with STERN WARNING about rename
        [integer! block!]
][
   all-FOO: :all  ; capitalization helps draw attention to the switcheroo
   all: :lib/all
   all [... all-FOO ...] then [...]
]

This is ugly, laborious, and failure-prone. Some of the routines that do this are complex, and it's hard to see the whole thing when you've got /all and "description" as the first thing you see. Hence despite the STERN WARNING, you're still likely to forget and try to reference the parameter via ALL, getting the native instead.

Mechanically this implementation isn't even really ideal...even better would be some way of preserving the definition of whatever ALL was when the function is defined, without having to remember where it came from (or know if it was locally overridden). That requires code to run prior to the execution, e.g. static initialization:

foo: func [bar /all <static> all-saved (:all)] [
    all-FOO: :all
    all: all-saved
    all [... all-FOO ...] then [...]
]

That's a mouthful, and costs an extra variable for doing the swap. (Note: would be nice if swap 'all 'all-foo worked, taking WORD!s)

This is a real problem, so can the spec dialect do better?

I'd wondered if having extended paths might be a way of doing this; the first path word is the public name, with the second being the private:

foo: func [bar /all/all-FOO] [
    ...
    all [... all-FOO ...] then [...]
]

One thing that kind of displeased me about it is that if you did this with a normal parameter, it would get a slash in it. But tuples might avoid that. Also, the necessity to draw attention to it is less...because you see it up in the parameter list, so there's less odds you'll overlook it. So the capitalization can probably be dropped:

foo: func [bar.bar-foo /all.all-foo] [
    all [... all-foo bar-foo ...] then [...]
]

It might not be the most beautiful thing in the world, but this is a real problem that is very frustrating when it comes up. And when you encourage people to play with words, they shouldn't be afraid to reuse them in refinements if they make sense.

Objections? Better ideas? :cricket: :cricket:

1 Like

While reading this, I had the thought, that tuples might be useful here, so I think this is in support of your idea.
I'm a bit surprised at how integral tuples seem to become to the features of whatever ren-c morphs into :wink: as tuples have been one of the lesser useful datatypes of Rebol (at least to me).

2 Likes

I'm also surprised. While I think dots are visually better for member selection most of the time, I had thought they'd be wasted as a synonym for PATH!-ing...such that always-inert TUPLE! would have more value. But generalized quoting has come along, and making blank-headed pathtuples inert offers two whole new classes of inert word...that are also inert sequences.

Being able to leverage their distinctness as a way to avoid execution of functions for anything with a "dot to the right of it" is looking pretty amazing. Being able to annotate things as "always a function" vs. "never a function" with ending in . or / is a way forwards on a problem I've been trying to crack for a long time.

The ability to institute these changes is a culmination of fiddling the system to be ready for all this. As I like to say, I'm looking forward to going head-to-head with Red at the Science Fair some day in the future... and then we'll see who the crazy person is.

( Well... that would me. But at the fair, we'll also see who the better designer/programmer is. Also me. :crazy_face: )

3 Likes