SPLICE vs. QUOTED! as Currency

The SPLIT function has... a lot of potential things you can split by:


>> help split
USAGE:
    SPLIT series dlm :into

DESCRIPTION:
    Split series in pieces: fixed/variable size, fixed number, or delimited

RETURNS: [<null> block!]

ARGUMENTS:
    series [any-series?]
    dlm [
        <opt> "just return input in a 1-element block"
        block! "parse rule"
        @block! "list of integers for piece lengths"
        integer! "length of pieces (or number of pieces if :INTO)"
        bitset! "set of characters to split by"
        char? text! "text to split by"
        quoted! "literally look for value"
        splice! "split on a splice's literal contents"
    ]

REFINEMENTS:
    :into
        If dlm is integer, split in n pieces (vs. pieces of length n)

Lots of design questions, there...

But I want to draw attention to [quoted! splice!], specifically.

The idea here is that you can split a list up based on literal values:

>> split [a b c * x y * z * * m n o] the '*
== [[a b c] [x y] [z] [] [m n o]]

Why does it use a QUOTED! for a literal value? Well, because if it didn't we couldn't split based on any of the things that already have meaning... like INTEGER! or BLOCK!

>> split [a b c 3 x y 3 z 3 3 m n o] the '3
== [[a b c] [x y] [z] [] [m n o]]

>> split [a b c [?] x y [?] z [?] [?] m n o] the '[?]
== [[a b c] [x y] [z] [] [m n o]]

And of course, since it generalizes it generalizes to quoted things, but you have to mentally subtract a quote level there as well:

>> split [a b c '@ x y '@ z '@ '@ m n o] the ''@
== [[a b c] [x y] [z] [] [m n o]]

If we weren't using THE, you'd have to do even more quoting math on the quote:

>> split [a b c '@ x y '@ z '@ '@ m n o] '''@
== [[a b c] [x y] [z] [] [m n o]]
  • The first quote suppresses the evaluation to pass in the double quoted thing to SPLIT
  • The second quote tells SPLIT you mean the unquoted thing is what you literally want to match
  • The third quote is the "real" one you're looking to match literally on

Nifty SPLICE! Frees You From Mental Quoting Math

>> split [a b c 3 x y 3 z 3 3 m n o] ~[3]~
== [[a b c] [x y] [z] [] [m n o]]

>> split [a b c [?] x y [?] z [?] [?] m n o] ~[[?]]~
== [[a b c] [x y] [z] [] [m n o]]

>> split [a b c '@ x y '@ z '@ '@ m n o] ~['@]~
== [[a b c] [x y] [z] [] [m n o]]

...and it also generalizes to more than one item...

>> split [a b c $ * x y $ * z $ * $ * m n o] ~[$ *]~
== [[a b c] [x y] [z] [] [m n o]]

So when I look at that, it makes me think "Is there really a reason to offer both QUOTED! and SPLICE!?"

Might we bring back the fabled ONLY (or JUST?) for creating a singular SPLICE! ?

>> item: <*>

>> only item
== ~[<*>]~

You could use regular splice syntax as ~[foo]~ instead of the 'foo.

And if your value was in a variable, you'd use only var (or just var?) instead of quote var.

I Think I've Convinced Myself

:hammer:

Using SPLICE! to speak out of band about literal items--to push that out of band in dialecting instead of using QUOTED!--makes sense.

In this case in particular... since SPLICE has to be supported anyway. This is the meaning that a single-element splice would be forced to take.

It reduces the mental math, and also frees up QUOTED! to mean something else.

1 Like

I'll mention a potential additional (or alternative?) application of ONLY... as a validation predicate that you have exactly one item.

>> only spread [a b]
** PANIC: ONLY received more than one item

>> only ()
** PANIC: ONLY received zero items (not one)

And it would allow you to pass-thru a single-element splice:

>> only ~[a]~
== \~[a]~\  ; antiform (splice!)

I thought of this because in changing REDUCE to default to N-expressions-in producing N-values-out, that means the default predicate function for REDUCE is no longer IDENTITY. Because I'm allowing predicate functions to opt out or splice with their results.

>> reduce:predicate [[1 2] [3 4]] spread/
== [1 2 3 4]

>> reduce:predicate [null 1020 null] opt/
== [1020]

This means the default predicate function needs to be something that rejects anything that's not exactly one value.

Interestingly, this means that single-element splices are okay in REDUCE without a predicate, it's just when you have a splice with more or less than one item you have a problem:

>> reduce [~[1]~ ~[2]~]
== [1 2]

>> reduce [~[1]~ ~[2 2]~]
** PANIC: SPLICE! used in REDUCE w/no predicate must be 1 item
** Near: [~[1]~ ~[2 2]~ **]

>> reduce [~[]~ ~[2]~]
** PANIC: SPLICE! used in REDUCE w/no predicate must be 1 item
** Near: [~[]~ ** ~[2]~]

This made me think that the default predicate for REDUCE could be ONLY, and that ONLY could more generally be the kind of thing you could use to assert things were just one item.

The only thing that seems a bit of a problem is that I can imagine a lot of cases where you want an item as-is that's not in a SPLICE!. So you might imagine something more like:

>> only 1
== 1

>> only ~[1]~
== 1

>> only ~[2 2]~
** PANIC: ...

>> only ~[]~
** PANIC: ...

>> only ()
** PANIC: ...

So there's two different notions, "singularness" and "singularness in a splice".

What I like about the word ONLY is that it really takes away the notion of dialected meaning. It's a way of saying "I know you might have a meaning for BLOCK! or QUOTED! or whatever else, but this is an antiform that's holding the thing... and by containing it singularly, it really means "just the thing". That makes it feel the the right fit for the splice, and a general commitment within the system to say that SPLICE! is interpreted literally wherever it is accepted.