Hi, jamaicamon!
Let me suggest a few places where your tutorial explanations could be
improved. (Just because all of my comments are suggestions for
improvement, please don't infer that I'm negative about your efforts
to create another tutorial!)
[EMAIL PROTECTED] wrote:
>
> 2. the colon
> 2.2 before = get value, but don't apply it. Kind of pointless for short examples.
>
Not pointless (unless by "short examples" you're excluding functions).
Key idea is
Same as evaluating plain word for data values, but NOT same for
words whose value is a function. "Get"ting a function, doesn't
evaluate it. For example:
>> greet: func [name] [print ["Hello," name]]
>> greet "jamaicamon"
Hello, jamaicamon
>> aloha: greet
** Script Error: greet is missing its name argument.
** Where: aloha: greet
REBOL is unhappy because evaluating 'greet requires giving it
an argument. However...
>> aloha: :greet
This sets 'aloha to the current value of 'greet, without trying
to evaluate the function. Following this, you can...
>> aloha "jamaicamon"
Hello, jamaicamon
>
> 3. ' = literal, much like quote marks in english, perhaps you want
> to print the word 'delete instead of do the word delete.
> >> 'delete
> == delete
> >> delete
> ** Script Error: delete expected target argument of type: file url.
> ** Where: delete
Well... The "quote marks" reference is good, but printing is not the
issue. The issue is more of a name-versus-value idea.
'word refers to the word itself, instead of its current value.
Sorta like the difference between saying
"Bob Marley" has nine letters.
and saying
Bob Marley had a band named The Wailers.
> >>
> 4. ! = datatype model "DO this TO that"
> used with MAKE and one of the datatype keywords. See below. Important.
>
No. The ! character can be used in the name of a word.
>> greet!: func [name] [print ["Hello," name]]
>> greet! "jamaicamon"
Hello, jamaicamon
By convention (but not rules of the language!) used to distinguish
between names of datatypes and queries to see if something is of
that datatype.
>> type? 123
== integer!
>> integer? 123
== true
>
> 7. "" double quotes = generally text
>
Well... both quotes and braces may be used to delimit strings. By
convention (but not rules of the language!) quotes are normally used
for shorter strings and braces used for longer ones. Given
tellme: func [s] [
either string? s [
print [mold s "has" length? s "characters"]
][
print [mold s "is not a string!"]
]
]
we get
>> tellme "the quick brown fox jumps over the lazy dog"
"the quick brown fox jumps over the lazy dog" has 43 characters
>> tellme 256
256 is not a string!
>> tellme [how now brown cow]
[how now brown cow] is not a string!
>> tellme "the more i keep typing the more likely i'll get back some
braces"
{the more i keep typing the more likely i'll get back some braces}
has 64 characters
>> tellme {boo!}
"boo!" has 4 characters
>
> 10. ^ = carat = used to insert ascii values
>
Close. Used to "escape" values in strings for special treatment.
>> print "these^-words^-have^-tabs^-between"
these words have tabs between
>> print "these^/words^/have^/newlines^/between"
these
words
have
newlines
between
>> print "these^(line)words^(line)have^(line)newlines^(line)between"
these
words
have
newlines
between
>> print "these^Iwords^Ihave^Itabs^Ibetween"
these words have tabs between
>
> 10. , = comma = unknown use used other than to seperate data entries
>
NO! Used as alternate "decimal point" (per European usage), the comma
IS NOT used to separate data values.
>> block: ["my" "dog" "has" "fleas"]
== ["my" "dog" "has" "fleas"]
>> bogusblock: ["my", "dog", "has", "fleas"]
** Syntax Error: Invalid word -- ,.
** Where: (line 1) bogusblock: ["my", "dog", "has", "fleas"]
>> 1,25 + 2,50
== 3.75
>
> F: DATATYPE
> The REBOL they start out with everything is a value, what they
> really mean is a datatype:
>
No. A datatype is a class of values that exhibit the same behavior.
Therefore, every value is/has a datatype. (Even datatypes -- which
are values -- have a datatype!)
>> type? 3.75
== decimal!
>> type? 375
== integer!
>> type? "something"
== string!
>> type? decimal!
== datatype!
>> type? integer!
== datatype!
>> type? string!
== datatype!
>> type? type? 123
== datatype!
>
> G: KEYWORDS
> Which I define is a word you type at the prompt that does something.
> They seem kind of confused by this concept at REBOL.
>
No. REBOL is just different from most other programming languages.
Unless you've used FORTH, you've probably never seen a language that
uses "words" like REBOL. (Possible exception is LISP/SCHEME use of
"atoms", but that's now quite the same.)
>
> Depending on what docs you are reading, it means any or all of these
> things: ...
>
No. A word is more like a name in ordinary speech. It simply refers
to whatever value it was defined to (assuming it has been defined).
Therefore,
Depending on the current context, a word may have any of these
as its value: a simple data value, a data structure, a function
(defined in REBOL itself), a native (a function predefined
within the REBOL interpreter, ...
>
> But the real thing is I want them sorted into functional groups,
> like every other tutorial in the universe.
>
Take a look at
http://www.rebol.com/users.html
for the newest version. I think you'll find the organization much
more to your liking.
>
> contexting: haven't messed with this
>
Think of a context as being like a private dictionary. Contexts
allow words (well, at least, words spelled identically) to have
different meanings in different settings. For example:
>> print 1 + 2
3
>> print "Hi!"
Hi!
>> prin "x" prin "y" prin "z" print "- that's all!"
xyz- that's all!
That uses 'prin and 'print with their global meaning. But in
>> bufferingfunction: func [/local buffer prin print] [
[ buffer: copy ""
[ prin: func [value] [append buffer form value]
[ print: func [value] [append append buffer form value "^/"]
[ print 1 + 2
[ print "Hi!"
[ prin "x" prin "y" prin "z" print "- that's all!"
[ buffer
[ ]
>> print bufferingfunction
3
Hi!
xyz- that's all!
the function creates a context in which 'prin and 'print have a
different meaning.
>
> FUNCTIONS (KEYWORDS, whatever). The CONTEXT is the set of all defined words.
>
Well... A context is *a* set of definitions.
>
> reduce = [] evaluate all expressions in block as single expression
> do [] = block evaluate
>
'do (when applied to a block -- it can also be applied to strings and
files) evaluates all expressions in the block and returns the last
value as its result.
'reduce (when applied to a block) evaluates all expressions in the
block and returns a block containing all the values.
>
> for = accidentally is same command as in BASIC
>
No accident. Common to LOTS of programming languages. Why fight
habit (without compelling reason, at least)?
>
> try [] = attempt to do a function
>
... and allow the script to handle any errors that may occur, instead
of having an error abort the entire script back to the interpreter.
>> div: func [a b] [a / b]
>> div 4 2
== 2
>> div 123456 3
== 41152
>> div 23 0
** Math Error: Attempt to divide by zero.
** Where: a / b
>> either 100 < div 2300 10 [print "big!"][print "little!"]
big!
>> either 100 < div 2300 100 [print "big!"][print "little!"]
little!
>> either 100 < div 23 0 [print "big!"][print "little!"]
** Math Error: Attempt to divide by zero.
** Where: a / b
We can handle the errors ourselves by defining
>> div: func [a b] [if error? try [return a / b] [0]]
>> div 23 0
== 0
>> either 100 < div 23 0 [print "That's a big quotient!"][print
"little!"]
little!
>
> >> print 'one 'two 'three
> one
> == three
> (maybe better not try that one)
>
The entire line is treated as if it were a block. After the input
line is translated to a block, the interpreter will 'do that block.
So...
>> do [print 'one 'two 'three]
one
== three
because (remember the suggestion for 'do covered above?) the first
expression in the block is
print 'one
whose evaluation has the side effect of putting
one
in the interactive window. The second expression is
'two
whose evaluation is just the word two with no side effect.
The last expression is 'three which evaluates to the word three
and is returned as the result of the entire line -- because 'do
returns the last expression evaluated.
>> print 'one "none of this shows up" 23 (15 / 3) 'finally!
one
== finally!
If you wanted all of those things printed, you needed to put them
into a block, because if you give 'print a block, it'll print
everything in the block.
>> print ['one "none of this shows up" 23 (15 / 3) 'finally!]
one none of this shows up 23 5 finally!
Note that there's no result value, only the side effect of output.
(The result value appears after the double equal sign == .)
Finally, you could ask for all values to be evaluated and returned
at once (with NO side effect) by saying 'reduce instead of 'print.
>> reduce ['one "none of this shows up" 23 (15 / 3) 'finally!]
== [one "none of this shows up" 23 5 finally!]
>
> 2. Or else it comes between two arguments ;infix function
>
Hmm... infix operator, actually.
>> type? get to-word "+"
== op!
Hope some of this is helpful!
-jn-