Taking Advantage of DELIMIT's BLOCK! Behavior and GET-BLOCK!

I finally put my foot down and said that BLOCK! in DELIMIT has the behavior of don't evaluate, just squoosh everything together.

>> spaced ["abc" [d e "f"] "ghi"]
== "abc def ghi"

You can always REDUCE if you want evaluations, but there's also GET-BLOCK!...

>> spaced ["abc" :["something" 1 + 2] "ghi"]
== "abc something3 ghi"

And with the magic of GET-BLOCK! branches, you can even opt in or out of these things! Don't forget to use COMMA! if you think it will look better...

>> spaced ["abc" if true :["something" 1 + 2] "ghi"]
== "abc something3 ghi"

>> spaced ["abc", if false :["something" 1 + 2], "ghi"]
== "abc ghi"

Let's Look At What Old Code Had To Do

Here's some code for making a log file name from pieces in the tests:

log-file: log-file-prefix

if code-checksum [
    append log-file "_"
    append log-file copy/part skip mold code-checksum 2 6
]

append log-file "_"
append log-file copy/part skip mold test-checksum 2 6

append log-file ".log"
log-file: clean-path log-file

How about we tidy that up?

Here Is What We Can Confidently Write In The New Way

log-file: clean-path unspaced [
    log-file-prefix
        if code-checksum :["_", copy/part (skip mold code-checksum 2) 6]
        "_", copy/part (skip mold test-checksum 2) 6, ".log"
]

Not only is it cleaner, it's more efficient! This lets us build as we go along, without having to keep expanding string memory on each APPEND...fewer function calls. It's better all around!

I think we can make a JOIN using the "REPEND" replacement optimization equally efficient:

log-file: clean-path join log-file-prefix :[
    if code-checksum :["_", copy/part (skip mold code-checksum 2) 6]
    "_", copy/part (skip mold test-checksum 2) 6, ".log"
]

It Could Be Even More Efficient, If We Wanted...

Given the GET-BLOCK! optimizations, a minor tweak could boost things:

log-file: clean-path unspaced [
    log-file-prefix
        if code-checksum ':["_", copy/part (skip mold code-checksum 2) 6]
        "_", copy/part (skip mold test-checksum 2) 6, ".log"
]

It's a subtle difference, but we're having the IF statement evaluate to a GET-BLOCK!...instead of having a branch that evaluates a GET-BLOCK! to make a block.

We can make DELIMIT evaluate get-blocks as it goes, folding them into the output without generating intermediate series...much like REPEND.

This could be a little wild, in terms of performing evaluations when you didn't intend them:

data: [a b c :[format hard drive]]

...

for-each item data [
    print ["The value is" data]
]

But that's really just the tip of the iceberg on how many ways the system is not safe against injection attacks. But if you're working in a secure situation, you could use a guarded layer whenever dealing with external data, to limit execution. I think that concept (which I have called "Build Your Own Safety") is likely what people who want to use the language in more secure scenarios would have to do.

(After all, even the most secure programs have to at some point run on an "insecure" CPU. A flexible and fast Ren-C could be the basis for designing a more secure language on top of it...)

2 Likes