Dialects - Bane or Blessing? (was: Teaching Rebol)
[1/7] from: greggirwin::mindspring::com at: 25-Sep-2002 22:28
Hi Jason, et al
I think dialects are something we're going to learn a lot more about as we
start to really learn how to create and apply them. Since I think dialects
are so important, I'd love to hear some other viewpoints about their pros
and cons. This isn't a rant, or an attack on your view, but your note
inspired me to think a bit and, now, ask more folks here to think a bit and
share their thoughts.
<< My main concern about Dialects is that the new extra vocabulary/syntax to
learn
and lack of indication. >>
How much "indication" a dialect provides will depend on the dialect. The
PARSE dialect provides quite a bit of indication I think, which is valuable
in that context. Defining a grammar isn't the place to have lots of
ambiguity. :)
In a good dialect, there shouldn't be any *extra* vocabulary or syntax. Just
the dialect. The dialects we use in the course of REBOL development (VID and
PARSE) may *seem* to have extra rules because we don't "change gears" when
we use them. We keep thinking in REBOL and we just glom on the extra rules
because you can mix the two so easily. If you had to go to a specific
window, and only valid VID code could be typed there (no embedded REBOL
allowed), maybe it would be less confusing because your brain would switch
modes. It's really hard to think that, as soon as I type "layout [", I'm
writing in a totally different language! Even thinking about it now,
explicitly, my brain doesn't want to wrap around it very well. ;\
<< Great for the original deevloper, but alreadyknwo it inside out. >>
Ahhh, this is where I see the power of dialects coming to the fore. The
original developer needs to design a dialect for a target audience. That
target audience doesn't know anything about REBOL, and the dialect doesn't
look even *remotely* like REBOL. The users could use it for years, then be
exposed to REBOL and not have any idea how to write REBOL code. Just like
any good interface, if the designer does his job well, it will be easy to
use. If not, it will be like command lines of old, or GUIs with layers of
stuff where you can't find anything.
I look at dialects being used by non-REBOLs. Writing new dialects for
ourselves is going to be very empowering, totally cool, and loads of
fun...for us. Regular folks, the ones with "lives" that we hear so much
about, just want to communicate without thinking about *how* they're saying
what they want to say. For us, yeah, we'll want to be careful not to create
dialects that confuse us.
dialect - The form of a [spoken] language, peculiar to a region or social
group.
Thousands, or tens of thousands, of dialects exist in the world today.
People use them all the time without even thinking about them. I'm using one
now. It's what people do. The great thing about dialects is that the goal is
to teach the computer to understand *us* in a meaninful way, rather than the
other way around.
<<...even though the code looks cleaner and is focused on the applcaition
domain closely. >>
You bring up two great things about dialects. I can't improve upon your
statement, so I'll just add a note, or ten, to it.
Domain specific languages are one of the few places where really huge
productivity gains come from. They provide enormous power by letting people
think in terms of a particular context. Two great Wittgenstein quotes:
"The limits of my language are the limits of my mind.
All I know is what I have words for."
"If we spoke a different language, we would perceive a
somewhat different world."
On the tech side, look at Capers Jones 'Productivity by Function Point
Analysis' view on how different languages compare, as to how "productive"
they are in terms of code versus functionality. (bad memory guessimates
here) C is down around 2, C++ ~5, VB/Java ~10, Perl/Smalltalk ~15, SQL ~25,
Excel/Lotus ~50.
I'll let you draw your own conclusions about what these numbers mean. :)
When you write functions, class libraries, etc. what you're really doing is
extending the dialect of their parent language. While that's convenient,
it's only applicable in the *context* of the parent language, or compatible
languages. REBOL dialects don't have to play by those rules. Now, you could
do this with most any language out there, at least to some extent. I've done
it myself. The problem is that those languages tend to be limited,
inflexible, or a lot of work to write. REBOL makes it easy to write
powerful, flexible and, thereby, useful dialects.
What's confusing in some cases, like VID, is that the dialect is generally
used *inside* the context of the REBOL dialect and can also *contain* REBOL
code. It's also extremely flexible and tries to be as smart as possible to
make your life easier (e.g. not caring about facet order if it can figure
them out by datatype, etc.). Think about that recursive notion for a moment
and imagine how confusing it *could* be if done poorly. :)
I very rarely see complaints about the PARSE dialect, though there are
occasionally suggestions for how to improve it. Maybe that's because it has
more clearly defined and visible syntax.
What other dialects are out there? I have a couple, but I should go now
because this is already really rambling and I've been typing slower than I'm
thinking so it's probably not been an easy read. Sorry about that, but
thanks Jason! My brain is bursting!
--Gregg
[2/7] from: al:bri:xtra at: 26-Sep-2002 21:23
Gregg wrote:
> What other dialects are out there?
There's my ML dialect. Here's a little sample from my Wiki script:
print ML compose/deep [
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
html [
head [
title (Title)
link/rel/type/href "stylesheet" "text/css" (%Wiki.css)
script/type/language/src "text/javascript" "JavaScript"
(%Wiki.js) ""
]
(Body)
]
]
Here's a sample of my Fixed dialect (it's used for chopping up fixed width
data files generated by a DOS BASIC program)
Fields: [
"Family Name" 20
"First Name" 25
"Preferred" 12
"Mail to Whom" 35
"Invoices?" logic!
"Reports?" logic!
"Address" [25 20 20]
"Telephone" 19 /with " -()"
"Cellphone" 7 /with " -()"
"Nationality" 3 issue!
"Language" 2 issue!
skip 4
"Year" 2 integer!
"Form" 4 issue!
skip 4
"Gender" 1 issue!
"Birth" 8 date!
"Enrollment" 5 issue!
skip
"First Started" 8 date!
"First Attended" 8 date!
skip 2
"Type" 1 issue!
"Status" 1 issue!
"Caregiver 1 Family Name" 20
"Caregiver 1 Title" 4
"Caregiver 1 First Name" 12
"Caregiver 1 Address" [25 20 20]
skip 20
"Caregiver 1 Cellphone" 6 /with " -()"
"Caregiver 1 Home Telephone" 14 /with " -()"
"Caregiver 1 Work Telephone" 14 /with " -()"
"Caregiver 1 Occupation" 3 issue!
"Caregiver 1 Relationship" 1 issue!
skip 4
"Caregiver 1 Invoices?" logic!
"Caregiver 1 Reports?" logic!
"Caregiver 1 Voting Rights?" logic!
"Caregiver 1 Emergency?" logic!
"Caregiver 1 Living With?" logic!
"Caregiver 1 Legal Guardian?" logic!
"Caregiver 1 Access Rights?" logic!
"Caregiver 1 User Flag 1?" logic!
"Caregiver 1 User Flag 2?" logic!
"Caregiver 1 User Flag 3?" logic!
Here's a very small sample of my eText dialect:
eText Sampler
*************
Author: "Andrew Martin" [Al--Bri--xtra--co--nz].
Date: 7/October/2001
Intent
======
eText is designed as a quick, easy, portable, powerful documentation
language. It's primarily suited for generating high content HTML and WML
pages.
There's loads more examples on my site; just substitute ".txt" for ".html"
on nearly any URL.
And the script for interpreting my CSS dialect (for creating style sheets)
CSS: function [
"CSS generates CSS markup from Rebol words, paths, tags, blocks and
other values."
Dialect [block!] "CSS dialect block."
] [CSS Number Declaration Property Value Value2 Selector Selector2
Selector3] [
CSS: make string! 2000
Number: [integer! | decimal!]
Declaration: [
some [
set Property set-word! (
repend CSS [
tab mold get 'Property
; In the above line "get 'Property" can be replaced
; with "Property" with new Rebol versions.
]
)
some [
[set Value Number %.] (
repend CSS [
#" " Value #"%"
]
)
| set Value file! (
repend CSS [
" url(" replace/all copy Value #" " " " ")"
]
)
| set Value url! (
repend CSS [
" url(" Value ")"
]
)
| [set Value Number set Value2 word!] (
repend CSS [
#" " Value Value2
]
)
| set Value [word! | issue!] (
repend CSS [
#" " mold Value
]
)
] (
append CSS ";^/"
)
]
]
parse Dialect [
any [
[
set Selector word! set Selector2 word! set Selector3 word! (
repend CSS [
mold Selector #" " mold Selector2 #" " mold
Selector3 " {^/"
]
)
| set Selector word! (
repend CSS [
mold Selector " {^/"
]
)
| set Selector block! (
foreach Item Selector [
repend CSS [Item ", "]
]
remove/part back back tail CSS 2
append CSS " {^/"
)
| set Selector path! (
foreach Item :Selector [
repend CSS [Item #" "]
]
remove back tail CSS
append CSS " {^/"
)
]
into Declaration (
append CSS rejoin [
tab "}" newline
]
)
]
end
]
CSS
]
And there's my Build-Tag dialect, which is incorporated into the latest
Rebol versions.
Build-Tag: function [
"Generates a tag from a composed block."
Values [block!] "Block of parens to evaluate and other data."
] [
Tag Value_Rule XML? Name Attribute Value
] [
Tag: make string! 7 * length? Values
Value_Rule: [
set Value issue! (Value: mold Value)
| set value file! (Value: replace/all copy Value #" " " ")
| set Value any-type!
]
XML?: false
parse compose Values [
[
set Name ['?xml (XML?: true) | word!] (append Tag Name)
any [
set Attribute [word! | url!] Value_Rule (
repend Tag [#" " Attribute {="} Value {"}]
)
| Value_Rule (repend Tag [#" " Value])
]
end (if XML? [append Tag #"?"])
]
| [set Name refinement! to end (Tag: mold Name)]
]
to tag! Tag
]
And here's some stuff I've been working on. My XForms dialect for generating
HTML forms in Rebol (it doesn't work very well, but it's an example of a
dialect):
X: Forms [
Logic "Truth?" /Truth
Logic "Falsey?" /Falsey
Field "Line" /Line 10
Secret "Password" /Password 10
Area "Paragraphs" /Paragraphs 40x4
SelectOne "Gender" /Gender [
#"F" "Female"
#"M" "Male"
]
SelectOne "Relationship" /Relationship [
#"F" "Father"
#"G" "Guardian"
#"M" "Mother"
]
SelectOne "Invoices?" /Invoices? [
#"N" "No"
#"Y" "Yes"
]
Date "Birth" /DoB
Output "Age" /Age
Integer "Number" /Number
Output "Total" /Total
Submit "Enter"
] make object! [
Truth: true
Falsey: false
Line: "string!"
Password: none
Paragraphs: trim {A long line of text,
that is several lines long.
It has several lines indeed!
And here's another!}
Gender: #"F"
Relationship: #"M"
Invoices?: #"Y"
DoB: 25/10/1960
Age: has [YMD] [
YMD: system/words/Age now DoB
rejoin [
YMD/Years " years, " YMD/Months " months, " YMD/Days " days."
]
]
Number: 123456
Total: $123.45
]
I'm sure there's more to come, and there's plenty more out there to be
discovered.
Andrew Martin
The dialects are out there! :)
ICQ: 26227169 http://valley.150m.com/
[3/7] from: brett:codeconscious at: 26-Sep-2002 19:47
Hi all,
> I think dialects are something we're going to learn a lot more about as we
> start to really learn how to create and apply them. Since I think dialects
> are so important, I'd love to hear some other viewpoints about their pros
> and cons. This isn't a rant, or an attack on your view, but your note
> inspired me to think a bit and, now, ask more folks here to think a bit
and
> share their thoughts.
Gregg great post. I agree with it all, although I didn't quite understand
what you meant by "In a good dialect, there shouldn't be any *extra*
vocabulary or syntax. Just the dialect."
Last night I spent quite a while making a simple dialect more sophisticated.
It sort of evolved as I thought up interesting extra functionality to add.
But even while the functionality grows, the dialect grammar does not
necessarily grow as fast. A nice property. Leverage.
I'm evolving my dialect because I'm not an experienced grammar designer and
I find that choosing how to the structure of the grammar to be really hard.
But it is good experience. Thinking through these decisions makes me
appreciate just how much VID can be seen as a work of art. It also makes me
realise that having a cookbook for writing dialects in REBOL would be really
great. I've tried searching the internet for information on how to design a
good grammar and to me it seems as scarce as hen's teeth. Yes there's plenty
on how to parse one or compile one but not on how to make one conform to
your goals. It might also be nice to a sort of dialect framework - e.g the
structure of VID could be used in multiple domains so is it possible to make
it resuable as a quick start for someone building a new dialect? I guess
this situation of lack of grammar design information comes about because
designing a language is not ordinarily considered an developer activity -
more a software tools manufacturing activity - or maybe I was just looking
in the wrong place. Maybe REBOL will alter this situation.
In terms of example, at least some of the XML languages can be used to
reflect on. I mean XML is all about adding meta information to your base
information. REBOL dialects are too. So there can be a creative mixing of
ideas there. For me though I think the REBOL dialect approach is easier to
explore because the building blocks so naturally follow and are indistinct
from the supporting language.
In terms of internal REBOL dialects my favourite is VID naturally enough.
PARSE. CONTEXT, SECURE, COMPOSE, BUILD-TAG and rebsite index.r files provide
food for thought too.
Here are some external REBOL dialects I can name straight off:
Ingo Hohmann: TUI Dialect (Produce ASCII sequences)
Andrew Martin: -he just posted his list-
Joel Neely: generate-data (Generate test data from production rules)
David Oliva: Flash (SWF) Project
Gabriele Santilli: PDF-maker
Frank Sievertsen: lego (Lego-Cybermaster Robot control protocol),
irc-protocol, reb-log (Prolog dialect)
> << My main concern about Dialects is that the new extra vocabulary/syntax
to
> learn
> and lack of indication. >>
>
> How much "indication" a dialect provides will depend on the dialect. The
> PARSE dialect provides quite a bit of indication I think, which is
valuable
> in that context. Defining a grammar isn't the place to have lots of
> ambiguity. :)
I guess it depends on requirements. Its a hunch, but I think that if a
dialect is going to be stable and the outcomes change not much then perhaps
vocabularies / grammar can be minimal. But if the dialect has to grow over
time without breaking older messages then you might need to build in some
expansion flexibility or apparent redundancy. VID is amazingly extendable -
even to the point that a VID style can be designed to interpret the input
given to it as a special dialect in itself (within some limits of course). A
dialect within a dialect.
Regards,
Brett.
[4/7] from: greggirwin:mindspring at: 27-Sep-2002 9:46
I have a few I've done as well, and let's not forget about make-doc and it's
relatives! Here are some examples of a few of mine.
===REBOLogo, which is just a very basic version of Logo:
box-tri-procs [
to box
pen-down
set-pen-color any
repeat 4 [fd 100 rt 90]
end
to triangle
pen-down
set-pen-color any
repeat 3 [fd 100 rt 120]
end
box
triangle
to tri-box
box
triangle
end
repeat 3 [
left 90
tri-box
]
pen-up
fd 200
set-heading 180
tri-box
]
===FSM (and the FSM for a turnstile):
when locked
coin causes unlock then unlocked
pass causes alarm
when unlocked
coin causes thank-you
pass causes lock then locked
The FSM engine does all the action triggering and state changing for you
given a spec like this. All you have to do is feed it events.
===RMake. Similar to MAKE, with an engine that processes the rules and
performs the actions based on dependency evaluation:
spec-1: [
target %xxx.bld
depends on [%xxx-0.txt %xxx-1.txt]
made by [
print ["rebuilding" _target "from" _source]
write _target rejoin [now/time/precise newline read _source]
]
target %xxx-1.txt
depends on %xxx-2.txt
made by [
print ["rebuilding" _target "from" _source]
write _target rejoin [_target tab now/time/precise newline read
_source]
]
target %xxx-2.txt
depends on %xxx-3.txt
made by [
print ["rebuilding" _target "from" _source]
write _target rejoin [_target tab now/time/precise newline read
_source]
]
]
rmake/build spec-1
===RAWK (REBOL AWK):
test-prog: [
begin [print "begin"]
end [print "end"]
begin-file [print ["begin-file" _filename]]
end-file [print ["end-file" _filename]]
every-line [line-ct: line-ct + 1]
(find rawk/_ "[") [print ["found line with bracket:" rawk/_fnr rawk/_]]
[_/1 = "lng"] [print ["found line with _/1 = Lng:" _fnr _]]
[(field 1) = "lng"] [print ["found line with _/1 = Lng:" _fnr _]]
[(length? __) = 21][print "found line exactly 21 chars long"]
[_nr = 1] [print "record 1"]
[_fnr = 1] [print ["file record 1" _filename]]
[all [(_nr >= first-line)(_nr <= 12)]] [print ["record from 10 to 12"
tab _nr]]
[_nr // 1000 = 0] [prin "."]
]
===Send-keys (for sending keystrokes to other applications):
win-send-keys compose [
"Gregg" return tab F5
alt #"f" #"o" wait 0:0:0.1 alt "n" wait .5 escape
{^/This is some more text (with a "quote")...
no less. }
divide return
shift ["i" shift-up "rwin"] return
shift "i" "rwin" return
"Irwin" return
"0" 10 return
(s: copy "" repeat i 10 [append s form i]) return
(do func [/local s] [s: copy "" repeat i 10 [append s to char! add i 64]
s]) return
ctrl "s" wait .5 escape return
]
Something to note about these dialects is that some allow you to embed REBOL
code directly in them. REBOLogo is just Logo, and Send-keys is just what it
is, but you can still use COMPOSE to create dynamic content with REBOL of
course. FSM, RMAKE, and RAWK all perform actions, which is to say that they
execute REBOL statements - so there is a definite and direct link to REBOL.
I have some others that I've just sketched out a bit. Some of them use REBOL
directly but others are "pure" dialects.
--Gregg
[5/7] from: greggirwin:mindspring at: 27-Sep-2002 9:46
Hi Brett,
<<...I didn't quite understand what you meant by "In a good dialect, there
shouldn't be any *extra* vocabulary or syntax. Just the dialect." >>
What I meant was that a dialect like VID looks like it just adds extra
syntax rules to REBOL because of the way we can mix the two. With "hybrid"
or "mixed" dialects (where you can directly embed content for a different
dialect, or that are, themselves, modifications of an existing dialect)
there may be parts of speech that seem superfluous or don't quite match up
with other parts of the language. Dialects that try to be all things to all
people will likely turn out this way. Those that define a very specific
nomenclature, and any that are well designed, should just kind of "hang
together" in a very natural way.
--Gregg
[6/7] from: gerardcote:sympatico:ca at: 28-Sep-2002 10:51
Hi Gregg,
regarding some dialects of your own,
---------------------------- You wrote: ------------------------------------
> I have a few I've done as well, and let's not forget about make-doc and it's
> relatives! Here are some examples of a few of mine.
<<quoted lines omitted: 14>>
> ctrl "s" wait .5 escape return
> ]
-----------------------------------------------------------------------------------------
Sometime ago I asked myself how I could emulate the VB Send-Key function using REBOL
since I will need it soon.
I planned to use the Windows API but this requires the /View PRO that I can't afford
yet - other short term priorities appeared here
recently !!! Probably I'll get it in december instead of mid-september as originally
planned :-)
So my question is : Do you also use the Windows API under the hood of your Win-send-keys
DIALECT ?
When I will have done my own it is possible that I recontact you about your Dialect since
this looks an easier way to do things than
I originally planned to do them myself - do you agree ?
Thanks in advance,
Gerard
[7/7] from: greggirwin:mindspring at: 28-Sep-2002 13:53
Hi Gerard,
<< So my question is : Do you also use the Windows API under the hood of
your Win-send-keys DIALECT ? >>
Yes. No way around it that I could see.
<< When I will have done my own it is possible that I recontact you about
your Dialect since this looks an easier way to do things than I originally
planned to do them myself - do you agree ? >>
Yes, absolutely! If you want something like VBs SendKeys, this is it.
If there are any /Pro or Command users out there that would like to help
test it, just zap me an email.
--Gregg
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted