"The Fear" Of Dialecting PRINT

I've talked in the past about how I think PRINT of a BLOCK! is a pretty limited dialect, in that its hands are kind of tied because it allows just any evaluation, not required to be in a GROUP!. Compare this with PARSE, which strictly controls evaluations.

One thing that occurs to me that could be done without really making that much of a ripple in SPACED/UNSPACED/DELIMIT would be if THE-WORD! could mean "mold this":

>> value: [a b c]

>> print ["Value is:" value]
Value is a b c

>> print ["Value is:" @value]
Value is [a b c]

Note this is a suggestion for the direct dialect behavior, not of a THE-WORD! that gets generated:

>> print ["Value is:" the @value]
Value is @value

The idea that every stringy type that isn't a TEXT! form with their delimiters is something I've been assuming for a bit, in a "WYSIWYG" kind of mentality.

One technical question interfering in the evaluation raises is what to do about infix, such as something that is looking to pick up the THE-WORD! on the left.

>> @value left-quote
== @value

>> print ["Value is" @value left-quote]
Value is @value  ; this is presumably what the output should be

This would mean that while SPACED was looking at the pending evaluations, it would have to do something along the lines of notice it was a THE-WORD!, do the evaluation, and then ask if the evaluation moved by only one unit. There's actually more to worry about than that, because pure invisible comments would be evaluated as well...

Such interactions are complex, and raise a lot of questions about just how dialect-y you can get when you let people write any evaluative material in a block like that. But requiring GROUP! would be rather heavy-handed, and if literal inspections were done then at least if that's not what you wanted, you could use a group.

If this isn't good, is any PRINT (SPACED, DELIMIT) dialecting good?

People certainly want to use literal TAG! in unspaced:

unspaced [<b> "bolded text" </b>]

So the idea of using tags for control codes or saying how many digits of precision to print integers with would probably be unpopular. Is PRINT never going to aspire to more, and is that the job of a higher level print format routine?

If that's the mindset, then this THE-WORD! proposal is probably the only change that might be considered for squeaking by, but if it's the only irregularity it's probably not worth it. (?)

I've held off on doing anything interesting in PRINT for some time now, based on the... fear. :ghost:

It's the fear that if we give meaning to parts in the "print dialect", that there will be potential for confusion if we evaluate a freeform expression in the middle of that dialect that uses one of those parts.

>> block: [a b c]

>> print ["The block is: block]
** Error: Unknown rendering for &[block] in DELIMIT

>> print ["The block is:" @block]
The block is [a b c]

>> print ["This is" if get @block ["my fear"]]
This is my fear

There we see @block having nothing to do with molding at all. And yet, there it is--right in the "PRINT dialect"

So what I'm afraid of is that you'll be trying to read a PRINT expression and not knowing when the "magic" dialected parts are going to do their magic, vs. just be a parameter to some function call.

We wouldn't require groups on everything. Just function calls...

>> name: "Roscoe"

>> print ["Your name is" name]  ; no parentheses needed
Your name is Roscoe

>> print ["Your backwards name is" (reverse name)]  ; need parentheses
Your backwards name is eocsoR

There's an added benefit: if you see something like print ["foo" baz bar], you know baz and bar aren't functions. They have to resolve to non-function values, so you can read that with more confidence as to what's going on.

But Is The Fear :ghost: Justified? Or "Trust The User"?

The only mechanical problem with mixing dialected-interpreted values with code is that it screws with infix. Because the dialect is going one item at a time--consuming types that it recognizes--and then calling out to the evaluator when it sees things it doesn't--it could consume an item that people thought was meant for the left hand side of a function. That's not the end of the world.

I dunno. Beyond just the fear of confusion, we could also open up dialecting for paths and chains. I feel like there's a lot of cool things we can do with PRINT and giving meanings to things...

 >> string: "abcdef"

>> print ["What about limiting prints?" string:3]
== What about limiting prints? abc

So how oppressive would it really be if any function calls in PRINT were in GROUP!s?

Dialect With Fear, Or Dialect Without Fear, But... Dialect

You'll have a hard time convincing people your "dialected" language is all that when C's printf() is kicking your butt in the features department. So we're way behind schedule on having a featured PRINT with intelligent formatting as a dialect.

My instincts say that using GROUP!s for function calls isn't that oppressive, and cleans up some edge cases like infix meddling with the code. When I have complex expressions in PRINT I usually parenthesize them anyway.

So I'm eyeing the concept of requiring the groups.

1 Like

This is the current behavior of tags in the web console:

>> name: "World"
== "World"

>> print ["Hello" <b> name </b>]
Hello <b> World </b>

This doesn't seem that useful to me, compared to letting them pass through to the HTML.

If you actually wanted the tags literally and didn't want to use strings, maybe quote them?

>> print ["Hello" '<b> name '</b>]
Hello <b> Hello World </b>

Anyway...I was wondering if you have a smart terminal if it could piggy-back on a subset of HTML instructions to do things like bold or other features. Though it's pretty grotesque for doing things like color:

print [<span style="color:green;"> "Yuck." </span>]

Apparently custom elements are on the rise. Firefox let me put <green> elements in and style them as green:

print [<green> "Legit?" </green>]

Sooo... I guess that's one way of going after a short form for at least common colors.

It's kind of a nuisance when the color is not fixed:

color: pick [blue red green] 3

print [... "How to apply COLOR to this text?" ...]

You could solve that I guess with helper functions:

color: pick [blue red green] 3

colorize: func [color [word!] content] [
    return spread reduce [as tag! color, content, as tag! join "/" color]
]

print [colorize color "This is one way to go about it"]

That feels kind of...dirty. Like PRINT's interface should be lower-level and be able to speak in terms of the color directly, without there being some sort of parser that has to find and pair up tags.

But I don't know what that low level language would look like.

The above shows a little snippet of my fear, just in terms of getting involved in the design of these language parts that introduce questions of how much or how little processing PRINT implementations have to do.

In the web terminal, if you say write stdout you don't get any HTML processing...it escapes everything so you get monospaced text of any characters you write. Hence if PRINT is going to subvert that it has to know when and why.

Right now, PRINT never subverts. If you want to spew HTML directly to the console you have to use a lower-level replpad-write routine (there's no real reason why this couldn't be exposed as print:html or print:raw or similar).

But it's quite possible for PRINT to do a subset of behaviors... for instance:

image

So you get your HTML without giving up auto-escaping.

(This calls into question my choice to use bold for the output of write stdout, because bold might be meaningful for you to apply as a style if we start going down this road. Maybe some slight indenting and slightly different size--or another subtlety--would be a better choice than the bolding.)

Should I "Just Do It"?

I'm reluctant because I'm hoping some big great better idea will come along.

But this has been really my only idea for a few years, and I haven't moved on it.

I don't think that big better idea in the sky is coming. In the meantime we have all the ability to write colors and such to the terminal and browser and just aren't using it, while Red and Oldes R3 have gone down the path in their very non-HTML-embracing ways.

What About Format Specifiers?

We can't use things like CHAIN for number:8 to say print to 8 places, because number could be a function with 8 as a refinement.

But other things are on the table. 8:number for instance.

We might ask some other philosophical questions, like, how often do you really want to print just the number 2, literally? Is it rare enough that you'd be willing to give up 2 for the PRINT dialect as some kind of modifier?...and use '2 or "2" if you really needed to literally print the number 2?

I think these questions are important to ask, because PRINT should really be a flagship of dialecting.

Some might say that PRINT isn't that, and it's PRINT FORMAT that is the fancy thing. But as I've tried to lay out here, there's no formulation of PRINT as "do some process to the input that will be handed to stdout", because writing to stdout is something more narrow...whereas what PRINT wants to do is higher level. This means that there can't really be a PRINT FORMAT unless FORMAT produces some complex object that can be mapped to the various capabilities of the output terminal. And defining that object seems like more of a futile design exercise than just defining PRINT in a way that it can use component operations but ultimately have your environment configured with a PRINT that knows its medium and does what it needs to.