ACTION! Mold Shows Cached Name (If Available)

Since the label used to reference the function may be cached in the cell, I'm making MOLD give that if it's there, plus the parameter list:

>> mold reduce [1 2 :help]
== "[1 2 #[action! {help} ['topic /doc]]]"

It's useful, and it also will help make any bugs or oversights in the feature more obvious--if you see things with labels that seem wrong, please report it (but make sure you've read this whole post first...)

Remember: It's The Name Last Accessed Through

Function value cells that were produced and never given a name won't have a label, so it just omits it:

>> mold reduce [1 2 func [x] [print [x]]]
== "[1 2 #[action! [x]]]"

Remember this isn't the name that the function was defined with (SET-WORD!s do not manipulate the cache). It's the name the action was last accessed through:

>> foo: :help
== "[1 2 #[action! {help} ['topic /doc]]]"  ; here, accessed through :help

>> mold reduce [1 2 :foo]
== "[1 2 #[action! {foo} ['topic /doc]]]"  ; but here, accessed through :foo

We might review the question of if SET-WORD!s update the cache. I'm open to it, but there are some complications various places if we do that.

Don't Forget to Be Impressed: The Feature is Robust!

>> f: make frame! :append

>> f/value: 10

>> reeval make action! f [a b c]
== [a b c 10]

>> reeval make action! f 12-Dec-20120
** Script Error: append does not allow #[datatype! date!] for its series argument
                 ; ^-- neat!

>> make action! f
== #[action! {append} [series /part /only /dup /line]]
             ; ^-- now you can keep tabs on what the magic is doing...

Originally I left the label feature out of the 2020 accomplishments list, but that was an oversight. It's going to matter to help legibility of debug stacks, when you are creating and using these things in mid-expression...it would suck if such power tools showed no name information.

Be Aware: Of Function Derivation Issues...

This could mean that temporary names that aren't meaningful get exposed, e.g. when writing something that makes derivative functions:

>> greetify: func [action] [adapt :action [print "HELLO THERE!"]]
== #[action! [action]]  ; no cached-name, generated with func [...]

>> friendly-append: greetify :append
== #[action! {action} [series value /part /only /dup /line]]
             ; ^-- note this is {action} from `:action`, not {append} 

>> friendly-append [a b c] <d>
HELLO THERE!
[a b c <d>]

>> mold reduce [1 2 greetify :help]
== "[1 2 #[action! {action} ['topic /doc]]]"

You can see how the parameter name action contaminates to lose the label that a function derivation process started out with. You can use GET to subert this, which doesn't update the label the way accessing through a GET-WORD! does.

>> greetify: func [action] [adapt get 'action [print "HELLO THERE!"]]
== #[action! [action]]  ; no cached-name from a last fetch

>> friendly-append: greetify :append
== #[action! {append} [series value /part /only /dup /line]]
             ; ^-- see this is now {append} and not {action}

This method is used by ADAPT and SPECIALIZE and all those functions. However, it's not perfect because it's a modified version. The label cache is really only a hint.

Why Not Include the Body of the Action

Historical "molding" of an action tried to give its source code. I deemed this as not a useful direction, since the source code lacks bindings you can't get the action back from it. All it does is make blocks that contain actions nigh-illegible.

Red continues this pattern, and doesn't use construction syntax...hence making the representation look like it contains the WORD! func, which is even worse:

red>> append [1 2] :help-string
== [1 2 func [{Returns information about functions, values, objects, and datatypes.} 
    'word [any-type!] 
    /local ref-given? value
][
    clear output-buffer 
    case [
 ...

I don't have any perfect answers here. What you really need is some identity to get at the function. The pointer value is about the best we'd have, though pointers are unstable and you might look them up after a mold and they could be invalid (or point to something different entirely).

For the near term, I think this compact rendering that includes a label is best, and making getting at the function's body done with other tools.

3 Likes