Show the Love for SHOVE

So the 2019 idea of SHOVE... got a bit out of control.

It was at one point used to implement ME and MY:

>> some-variable: 10

>> some-variable: me + 20
== 30

The idea was that ME would take its left hand side literally, and then be variadic on the right to [+ 20]. It would GET the variable, then pass it to SHOVE, along with the variadic feed on the right.

Binding bugs in the too-complicated shove code led to scrapping that and expressing ME and MY as macros:

me: enfix macro [@left [set-word! set-tuple!] @right [word! tuple! path!]] [
    return reduce [left, plain left, right]
]

my: enfix macro [@left [set-word! set-tuple!] @right [word! tuple! path!]] [
    return reduce [left, right, plain left]
]

So that just turns [some-variable: me +] into [some-variable: some-variable +]

And [some-variable: my append] becomes [some-variable: append some-variable]

(Though I suppose technically, there's no reason ME needs to enforce an argument on the right... (some-variable: me) could be legal, although useless.)

Anyway, Without ME and MY, SHOVE Had No Uses

Once ME and MY no longer used SHOVE, the only place it appeared was in tests, that broke often and caused me grief.

Due to a recent change they're all completely broken

At frustrated moments, I've wanted to delete it completely. But... I'll try to not be hasty, and keep any useful parts.

Enfix No Longer A Necessary Applicatoin

So this isn't going to be an issue SHOVE needs to solve any longer, thanks to The Big Alien Proposal :flying_saucer:

You will be able to freely use enfix operations with refinements, because they will be done with CHAIN!s, and the head of the chain can be tested for enfix in a way that's no more or less broken than testing a word for enfix.

This might not seem too palatable for operators:

 a =:strict b

But not so useless: what about things like ACCESSOR? These take a SET-WORD! on their left, and I can reasonably see them taking refinements.

a: alias:weak $var

Anyway, you won't need shove to give refinements to enfix functions anymore.

So the most logical implementation of this is to have SHOVE take one unit of material on the left as a hard literal... and then decide what to do with it.

But if it takes its left as hard (or even soft) literal, then consider this:

>> 1 + 2 * 3
== 9   ; e.g. (1 + 2) * 3

>> 1 + 2 >- lib/* 3
== ???

The nature of literal arguments means that >- will out-prioritize the 1 + on the left, and act like:

>> 1 + (2 >- lib/* 3)
== 7

So what are the options, here?

  1. The main version of SHOVE (>-) takes its left hand side as a hard literal, and then treats the parameter how the right hand side wants (hard literal, soft literal, evalative). A second version of SHOVE (->-) takes its left hand side evaluatively...and either does not work with functions that take their first argument literally, or gives them the evaluative product (like an APPLY would).

  2. Flip that around: the main version of SHOVE (>-) takes its left hand side evaluatively, and you use a special version to take the left hand side literally.

  3. Say screw it: SHOVE isn't used that often and you should get used to the fact that it may take the left more tightly than you're used to. Be glad you have it at all, and just write (1 + 2) >- lib/* 3 if getting 9 out is so important.

  4. Ignore reality and try to make one native that incoherently attempts to serve all the purposes and then is specialized as three distinct operators.

For reasons that elude me now, in 2019 I went with [4].

From where I stand today, [3] is the obvious answer. Think about it: if people are going to have to modify their callsite, what's lower cost:

  • to teach them what a new alternative operator is called and how it works, and add one or more symbols to the callsite to get it... or...

  • to have them add exactly two symbols of ( and ) which they already understand fully?

Given the new string proposal for using -{...}- and --{...}-- etc. for strings (alongside -"..."- and --"..."--), it seems to me that -<...>- is going to make more sense as a form of TAG! which allows embedded < and >, as well as spaces at the head and tail.

tag: -<
    My modern multi-line tag,
    which can have > and < in it
>-

So SHOVE will need another syntax. ->- is still available, I guess.

>> 1 + 2 ->- lib/* 3
== 7

Thanks to TAG!, arrow words are pretty scarce. I hate to use something important like <- or >> or >>= for something this niche.

I'll mention that I still have a vague wish for >> as a "console operator", for some kind of wild trick that enables copy and paste replaying of console transcripts.

Anyway, I'll go with ->- for now, just to get things moving.