I occasionally get conflicted when using a language that isn't Rebol (happens from time to time) and get to thinking, hm—would life be easier in Rebol if this thing worked this way?
To illustrate my current instance, in Rebol you send a message as follows:
send foo@bar.baz "A Message"
It's always been one of the killer one-liners, very concise, most elegant. Using refinements, you can start to build up a more complex message:
send/subject/attach foo@bar.baz "Hi Foo!" "A Message" %me.jpg
Still relatively concise, but starting to fill out a little. As you sculpt your message, it starts to get a bit messy:
send/subject/attach/header
[foo@bar.baz eric@bar.baz]
"Hi Folks! – Chris"
"A Message"
make object! [X-User-Agent: join "Rebol " system/version]
That's the current prescribed way to send an email (line feeds are optional here, but become essential as component parts start to add up).
Rebol is nothing if not versatile though, we can dream of an alternate approach using dialects:
send [
; no delimiters required, we can discern recipients
; by the use of the email! datatype:
foo@bar.baz eric@bar.baz
; two string! values indicate the first as the subject
; second as the message
"A Message"
"Hi Folks!"
; a few attachments courtesy of the file! datatype
%me.jpg %you.jpg %the-world.jpg
; and then some set-word!/value headers
X-User-Agent: "Rebol"
]
Sans comments:
send [
foo@bar.baz eric@bar.baz
"A Message"
"Hi Folks!"
%me.jpg %you.jpg %the-world.jpg
X-User-Agent: "Rebol"
]
Pretty spiffy, but dialects get a bit tricky as you start to pull in conditional arguments, external data, further customisation. We can build that up somewhat procedurally:
send collect [
keep foo@bar.baz
if "Monday" = pick system/locale/days now/weekday [
keep eric@bar.baz
]
keep subject ; 'subject defined elsewhere
keep {A Long Message}
keep read %photos/
keep compose [X-User-Agent: (join "Rebol " system/version)]
]
Seems reasonable, except we lose a bit of expressivity as the implicit metadata offered by datatypes is obscured by the additional code. Even just the addition of words not of our current domain (collect
, keep
).
Which brings me to the object-based world (which seemingly covers the way the popular languages out there approach things). In this composite, non-existent Language X, we recover some of the expressivity through the explicit use of named actions:
message = mailer.new
// pity poor language X, only one string type:
message.addRecipient 'foo@bar.baz'
if (today = 'Monday') { // assumed 'today value
message.addRecipient 'eric@bar.baz'
}
message.subject = "A Message"
message.body = "Hi Folks!"
message.attach filesystem.read 'photos/'
message.header['X-User-Agent'] = 'Language X'
message.send
// Rebol's SEND function needs a return value with some
// status feedback. For another day...
if (message.isSentOk) {
print "Hooray!"
}
Beauty is in the eye of the beholder: this approach leaves you in no doubt what each line is for, yet simultaneously (to my eyes) appears heavy-handed. We get to our destination procedurally, send
happens after we've established the details of the message. In my moments of doubt, I wonder if having send [...]
states the intent before we're ready.
You could easily transliterate the Language X approach to Rebol, or have it inform the approach taken by a dialect:
mailer [
new message
add recipient foo@bar.baz
if today = "Monday" [
add recipient eric@bar.baz
]
subject: "A Message"
body: "Hi Folks!"
attach read %photos/
send
probe status
]
My question then is: Is the Language X object approach/influence something to covet, or does one or other Rebol approach retain enough expressivity as complexity increases?
PS: Not just mail—I think about this with regard to the <canvas>
tag and the idea of a procedural graphic format as opposed to the explicit <svg>
.