Revisiting the "Obvious": Quoting To Suppress Array Splicing?

A while ago, @IngoHohmann made a sensible-sounding suggestion:

I pointed out that unfortunately this wouldn't have the desired behavior at the callsites... because the evaluation of the parameter would strip the quote off before APPEND saw it:

>> '[d e]
== [d e]

>> append [a b c] '[d e]
== [a b c d e]

For APPEND to "see the tick", it would have to change its parameter convention to take its argument literally...which is not desirable...or you have to use a function that adds it:

>> quote [d e]
== '[d e]

>> append [a b c] quote [d e]
== [a b c [d e]]

You Could Ask: "So What?"

We've been expressing a willingness to use an ONLY operator to signal an intent to add things "as is":

>> only [d e]
== [[d e]]

>> append [a b c] only [d e] 
== [a b c [d e]]

But optimizing that to an extreme would be hard, and weird. The more I look at it, the more reluctant I am to push the optimizations to the point of not using a series node. e.g. the "one series node" optimization is about as far as I may feel comfortable pushing ONLY.

On the other hand...generic quoting is already written, and systemically optimized, even to multiple levels (up to 3)...and does no allocations. And QUOTE will be something users are already familiar with.

Plus, you at least have the option when writing expert-optimized code to use the learnable idiom of two ticks when you have a literal:

>> append [a b c] ''[d e]
== [a b c [d e]]

Ok, But, It Makes QUOTED! Another Interfered-With Type :frowning:

Let's say you're running through a block of items that contains quoted things and want to append them've now got another type that APPEND chooses to muck with if you don't say /ONLY or QUOTE:

data1: [1 2 <skipme> x y 'z]
data2: []

for-each item data1 [
    if not tag? item [
        append data2 item

>> data2
== [1 2 x y z]  ; oops, 'z got turned into plain z

Still.. what happened to 'z would have just as easily happened to [z]. So how much worse is losing of a level of quote than losing the containership of a block?

Rebol2 messed with your BLOCK!s, GROUP!s and ANY-PATH!s if you forgot to say /ONLY. Now it would mess with your BLOCK!s and your QUOTED!s.

I'm not in love with this aspect...but just pointing out that there's been no perfect answer to the problem, yet. So having an imperfect property doesn't rule something out automatically.

Main Point: Stepping Back From The Abyss of Optimization...

Using the sunk cost of work on QUOTED! vs. making a "magic" kind of block came to me while thinking about something related.

Imagine you have a function that takes actions to run, and you want to pass that something that just returns a constant value.

One way to do this today is to make a specialization of the IDENTITY function:

>> three: specialize :identity [value: 3]

>> type of :three
== #[action!]

>> three
== 3

But it feels a shame for such an action to take up more space and load the GC than just the simple number 3 would take. So we can imagine an overlaying cell formats, and how to "lie" about being an ACTION! when the cell is really an INTEGER!.

But oh what a tangled web we weave... trying to engineer this deception has so many problems it becomes hard to count them all. You can set meta information on actions, but this integer-action has no place to put it. If you convert it to a real ACTION! on demand, then each such conversion would get a new identity...putting the inefficiencies aside, that's a semantic problem because actions are expected to have individual identities, and these just don't.

It would be much simpler if you had written the routine that was willing to take an action to also take a QUOTED!.

This makes a good argument for why QUOTED!s should answer to the same questions that an action might...just minus that one lie of "I am an action!"

>> a: func [] [return just x]
>> q: just 'x

>> do :a
== x

>> do :q  ; colon not needed, but shows same flow as when using an action
== x

>> parameters of :a
== []

>> parameters of :q
== []

I guess the point I'm trying to make is that while it might seem a bit dissatisfying to have to handle a QUOTED! or an ACTION!, it seems that the places where you would have actual trouble with it is anywhere such methods don't make sense...and those points are exactly where a "fake" optimized action would break down.

This line of thinking took me to where I thought that making an optimized BLOCK! that doesn't have the implementation character of a BLOCK! (e.g. a series node) is a mistake in a similar vein. If you demand this particular axis of efficiency, you should use the systemic mechanism of a QUOTED! to get it...or say it's not worth it.

So Does Mucking Up QUOTED!s Beat the /ONLY Option?

I'm not feeling convinced.

The only thing I think I've convinced myself of is that the fake no-node block trick I was considering is bad for the health of the system. We are making 1-element blocks somewhat efficiently, but they're not free. So I wanted to write up the thinking behind that...and share the rest in case it triggered any brainstorms.