Trailing Slash Is A Winner For Defused Actions

I really like this trailing slash thing, meaning "get me the action as is and don't run it AND guarantee it's an action".

>> replace [a 1 a <baby>] word?/ <ice>
== [<ice> 1 <ice> <baby>]

That's to me just about perfect:

  • You're passing the parameter of what to replace as being an antiform action, so it will be called on the elements.

  • It does NOT take a parameter (notice the slash dividing it from what comes after it? that's a strong semiotic hint that <ice> is not a parameter to word?)

  • ...and it's an antiform, so you know it doesn't occur literally in the block.

Before this existed, I was using MATCHER which made an antiform action for a datatype:

>> replace [a 1 a <baby>] matcher word! <ice>
== [<ice> 1 <ice> <baby>]

That's slower, not as brief, and a bit more opaque about the mechanics.

It's useful if you have a datatype in your hand and need to convert it to a function, or if you have a more complex type construction:

>> replace [a 1 a <baby>] matcher [word! integer!] <ice>
== [<ice> <ice> <ice> <baby>]

If you make such a call often, you wouldn't want to regenerate the function each time:

>> word-or-int?: matcher [word! integer!]

>> replace [a 1 a <baby>] word-or-int?/ <ice>
== [<ice> <ice> <ice> <baby>]

Anyway, I'll also say that the REPLACE "ALL" semantic being the default is a big improvement.

2 Likes

Looking at this, I started to compare it to the & syntax that's been used in PARSE.

>> parse [2 4 6] [some &even?]
== 6

I haven't really warmed up to it very much.

So I wondered... what if PARSE used the trailing slash notation, assuming that meant run a function as a typechecker?

>> parse [2 4 6] [some even?/]
== 6

I find that more palatable than the leading-ampersand, for the reasons mentioned (looks better, and puts the slashy "barrier" at the end to semotically indicate "no parameters taken").

Though it doesn't have the generalization to other types:

>> parse [2 4 6 <eight>] [some &[even? tag!]]
== <eight>

But that could be done with a MATCHER combinator:

>> parse [2 4 6 <eight>] [some matcher [even? tag!]]
== <eight>

And arguably that's a lot more literate and less-symbol-y. It better bridges the non-PARSE code with the PARSE code. (Though MATCHER would take its argument literally, e.g. the BLOCK! you pass it like [even? tag!] isn't being processed by the block combinator. Such combinators are not that common--ANY is another example--but I think they should be allowed.)

When you put this together with the idea of types as antiforms, it might mean being able to reclaim the & symbol entirely for something else.

1 Like

A post was split to a new topic: How To FIND With A Matcher Function in Ren-C?