string | alt string | tag | file | note |
---|---|---|---|---|
`"value=(v)"` |
`{value=(v)}` |
`<value=(v)>` |
` %"value=(v)" ` |
|
@"value=(v)" |
@{value=(v)} |
@<value=(v)> |
@%"value=(v)" |
1 |
&"value=(v)" |
&{value=(v)} |
&<value=(v)> |
& %"value=(v)" |
2 |
/"value=(v)"/ |
/{value=(v)}/ |
/ <value=(v)> / |
/%"value=(v)"/ |
|
="value=(v)"= |
={value=(v)}= |
=<value=(v)>= |
= %"value=(v)" = |
|
^"value=(v)"^ |
^{value=(v)}^ |
^<value=(v)>^ |
^ %"value=(v)" ^ |
&
can't be an operator then@gtzip the question of value in Red is a good one. We tend to think in terms of little strings, and bits of code we compose
or rejoin
. While we don't have measurements, we do have evidence that non-developers understand, and can effectively use, templates (e.g. mail merge). Where blocks of code are normal for us, they are foreign to others, flipping the model on its head. No longer are there placeholders within a string of text, but there are interspersed bits of text and expressions. In my own work, I've used external templates more than internal, not counting rejoin/reform
cases where devs are the only consumer.
I also noted to @hiiamboris that a key elements is the WYSIWYG aspect. Rejoin/reform
make you look at every text snippet to make sure you have leading trailing spaces right. That's probably one of my most common mistakes in formatting. The other place that's huge is in multiline string formatting. e.g. templated email bodies. Compare this R2 build-markup
example
body {
The <%PROCESS_NAME%> process sent DISKPART the following commands:
<%mold MARKUP_1%>
The DISKPART result was:
<%mold MARKUP_2%>
}
with something like
body [
"The " <%PROCESS_NAME%> " process sent DISKPART the following commands:^/^/"
tab <%mold MARKUP_1%>
"^/^/The DISKPART result was:^/^/"
tab <%mold MARKUP_2%>
]
We can put the former in a user's hands, and if errors aren't dangerous, e.g. malformed fields, they can still deal with it. The latter, based on my experience, is not user friendly. It can be especially confusing because the blank lines in the template do not affect the output.
#composite
my reaction was "why would we ever want that?". But then with every print
or rejoin
I was using in my code I had this thought "what if..". Then I started using my experimental implementation, and after some time I believe it's a total must have.
I think this Red version is a little closer to the R2 example
body rejoin [{
The } PROCESS_NAME { process sent DISKPART the following commands:
} mold MARKUP_1 {
The DISKPART result was:
} mold MARKUP_2 {
}]
The direction that the 'delimiters' point around the code parts feels a little odd to me, but I don't know if it's good or bad. You do get accurate syntax-highlighting this way, which is nice.
Composite syntax :point_up:
On the chance that we want to support @"..."
syntax for ref!
someday, let's not do that.
Double sigils, head+tail are unattractive to me, and those with spaces required are problematic from a general "whitespace separates values" standpoint.
If it's a macro, I don't mind it looking like one, with a leading #
sigil. The editorial "change/insert" mark is ^
, which is a problem in Red. #^^
seems...icky ~
is close to "transpose", but that meaning isn't a great match for "substitute".
I still like aspects of the backtick, but #` is pretty subtle. #`` less so.
The number of bracketed string types in Red makes the other options quite ugly. As a more traditional macro it could also work for composing blocks at compile time. More thought required.
@greggirwin Let's see, I am currently working on Rebol on a way to send remotely the current command and start it there from inside the called function:
get-command-line: func [
"Returns a block ready to be transmitted that replicates the current function start parameters"
fname [word!] "The name of the functions"
args [block!] "The argument words inside a block"
refinements-block [block!] "The refinement block in the form [/refname [arg1 arg2] /refname [arg3 arg4]]"
bound-word [word!] "A word of the caller function context"
/specs
the-specs
/local
out-data
remote-command
refs
argument-refs
arguments
argg
command-line
in-block; block with refinements
] [
args: copy args
refinements-block: copy refinements-block
remote-command: to-path fname
;--- Here we neutralize functions in words on reduce
;
forall args [
if word? first args [change args to-get-word pick args 1]
]
;--- Here we neutralize functions in words on reduce
;
forall refinements-block [
if block? in-block: first refinements-block [
forall in-block [
if word? first in-block [change in-block to-get-word pick in-block 1]
]
]
]
refs: copy []
arguments-ref: copy []
arguments: reduce append copy [] args
parse refinements-block [
any [
set ref refinement! set argg block! (
if true = first reduce [get in bound? bound-word ref] [
append remote-command to-word ref
append arguments :argg
]
)
|
set ref refinement! (
if true = first reduce [get in bound? 'server ref] [
append remote-command to-word ref]
)
|
skip
]
]
command-line: mold/all reduce compose [remote-command (arguments)]
]
afunction: func [a b /c d e] [
probe get-command-line 'afunction [a b] [/c [d e]] 'a
]
>> afunction/c 1 2 3 does []
"[afunction/c 1 2 3 #[function! [][]]]"
Many things are still not there in Red to redo this but it is maturing from day to day.
third bound? 'a
to get the needed argument for get-command-line
but there is a terrible bug: if you ask the context of a local word of a function, it is returned without the first word of the context.>> a: func [b c][probe bound? 'b]
>> a 1 2
make object! [
c: 2
]
bound?
behavior. I've posted my refine
experiments in the past, which may be applicable. It looks like you're trying to bind parts of a remote call to different contexts, but I don't know why you'd do that. If you're making remote calls, you shouldn't know anything about the server side.
I am experimenting into creating commands that can be run either locally or remotely:
A command could be run as
command/ref arg1 arg2 refarg1
but if you write
server: HTTP://192.168.0.22
command/ref/remote arg1 arg2 refarg1 server
Then command
creates a block with its name and parameter, and executes it remotely. Then it receives the result from the remote server.
Using a refinement to make it remote seems to be the complicating factor. As far as you're concerned, a call is complete (command/ref arg1 arg2 refarg1
), correct? So you can store that internally as a block, and make the remote part separate if it's used.
my-call: [command/ref arg1 arg2 refarg1]
do my-call ; local
RPC reduce [my-call 'on server] ; remote, semi-dialected block for fun.
RPC
does all the magic and the func is none the wiser.
RPC
sends the block to the server who do
es it, and returns the result.
I don't know about RPC
function but I remember having seen it in Cheyenne.
Yes, refinement is the complication factor but I have chosen to have it on purpose. I have already made experiments with:
Mostly I have experimented creating functions whose arguments is a block or an object containing the arg/value pairs and build the internal function context bypassing the function interface, doing everything by hand. It worked well but the experiment goals is to pass regular Redbol commands and bind them to a remote object with contains the "allowed" commands and I want to take into the picture passing refinements too.
This It is the most difficult thing as I have no way to get a make
specs with refinents as set words.
RUN-REMOTE
. You simply provide a block of code and it Is executed remotely and you receive the return value./remote
refinement set and passing the server address, so they recreate the command needed to run themselves. This to not change the current usual coding, otherwise everything would become run-remote compose [command/arg (arg1 arg2 arg3 refarg)]
apply
syntax. I will try.
/remote server
the command just dispatches the request to an execution server`
@greggirwin Another option to transfer the current function context words and refinements and the values, is to use the set
syntax. It is perfect for keeping trace of refinements:
ctx: [[a b c /red ref-arg] [a b c false false]]
You have just to convert /red
to word before executing set
When words-of
and values-of
will be implemented for function it will be easy to write
ctx: reduce [words-of context? 'ref values-of context? 'ref]
Also set
words argument could accept refinements, so you can simply write:
set ctx/1 ctx/2
By far my most common case for filenames is date-naming them, which isn't a good match for
composite
and handled better byformat
.
It's good until you want to customize it a lot.
[[keys][values]]
split form with refinement you have to make a last management of the keys block to extrapolate the refinements, change to words and build a separate refinements block in case you would need this information.
It's good until you want to customize it a lot.
I guess I've always customized them a lot, because it's so helpful IMO. e.g. zero padding counts and ISO8601 formatting dates, so lexical sorting works.