[REBOL] Rebol Tech, please answer. Two questions. Re:
From: rebol:techscribe at: 12-Sep-2000 1:12
Hi Keith,
you wrote:
>blk: [11 22 33 44 55]
>print skip blk 3
>44 55
>
>Why not (print skip 3 blk) instead of (print skip blk 3)?
My $0.02: Two related explanations. Because:
1. REBOL is a mind-mapping language.
2. Consistency makes REBOL easier to learn and to remember.
Somewhat longer explanations of what I mean follow:
1. skip 3 blk
skip 3 ...
Why 3? Because the element I'm interested in is in the third position.
It is? How do I know that? Because I know what block blk contains, and
therefore I know that the element is in some position in that block,
namely, in the third position.
You notice that I can only determine the appropriate skip distance, after
I've determined in which block I'm skipping around.
I already thought of block blk, when I set out to determine the correct
value for the skip distance. Therefore, let me do first things first, I
might as well type what's first on my minde, "blk", be done with it, and
then move on to think about the skip-distance, which is derived from
knowing that I'm skipping around in the block "blk".
In other words, REBOL enables me to program like I think. At the point in
time at which I choose 3 as the skip distance, I must already know that I
will be skipping in the block blk, otherwise I would have no way of of
determining how many elements to skip. So I first type what must be first
on my mind, blk, and then whatever is next, "3". It must be "next on my
mind" because to determine that 3 is the correct skip distance, I must
already know that I'm skipping in block blk. But I can know that I'm
skipping in block blk, because it contains the element I'm interested in,
before I determine where exactly the element is located in the block, i.e.
before I determine the correct skip distance.
skip blk 3
makes "thinking in REBOL" more natural, because it is more
similar to the way the mind works anyway. "skip 3 blk" separates thinking
about the problem from formulating it as REBOL code. In my mind blk must
have come first, because I figured out that the skip distance is 3 (skip
blk 3), but if REBOL's notation was "skip 3 blk", then in REBOL the
relative position of the skip distance and the block would be exactly
reversed, compared to how thinking works.
Take 2:
The short version: Two-argument functions are single-argument functions
with an additional argument.
Long version:
Observation:
You use the word print in your example (print skip ...). The print function
takes only one argument. This is also true for other functions, such as
ask, or form, for instance. One-argument functions are simpler than
two-argument functions.
Examples:
form blk
print blk
ask form blk
empty? blk
This is also true for all type-related functions:
type? blk
block? blk
I can prototype these examples by providing a pattern:
The pattern is:
1. First I answer the question "What am I doing?", and then
2. I answer the question "Who am I doing this to?"
Question: "What am I doing?"
Answer: "print"
Question: "Who am I doing this to?"
Answer: "blk"
Question: "What am I doing?"
Answer: "form"
Question: "Who am I doing this to?"
Answer: "blk"
We have a pattern.
Once the human mind has grown accustomed to a pattern, it's easier to
acquire new knowledge, by extending the known pattern. We want to add an
element (a second argument) to the existing single-argument-function
pattern. Where are we going to place this additional new element?
To answer this question we must ask, "Do there exist pattern derivation
rules that are more easily learned than other rules?" The answer in this
case is that "fewer rules" are more easily learned than "more rules".
Follow-up question: But what if I express several "more rules" in a single
fewer rules
rule, albeit a complex rule? The answer is that a complex
rule does not count as a "fewer" rule. A complex rule counts as much as the
number of its constituent elementary rules. A complex rule stands in a
similar structural relationship to elementary rules, like a molecule to the
atoms it is composed of. The molecule ways as much as the sum of the atoms
it is composed of. A complex rule counts as much as the number of
elementary rules it is composed of.
The pattern "skip 3 blk" compared to "print blk"
If we place the new, second argument between the function name and what
originally was the first argument ("Who are we doing it to?"), our
derivation consists of three rules:
1. Remove the first argument from its previous position;
2. Add a new element (the new argument) at the removed argument's position;
and
3. Add the previous first argument at its new second-argument position.
I can express rules 1 .. 3 in one complex rule: "Insert the new element
between the first and second elements of the old pattern". But this is not
an elementary rule. This is a complex rule. The complexity of this rule is
signalled by the words "Insert" and "between the first and second". To
determine the complexity of a derivation rule, we must formulate the rule
in terms of its rule "atoms", its constituting elementary rules. "Insert
... between the first and second" breaks down into the three elementary
rules listed above.
It's apparent that adding the new argument at the end of the
single-argument pattern is a much simpler derivation because it consists of
only one rule (and one none-rule:)
0. none-rule: Leave the single-argument pattern undisturbed.
1. new-rule: Add the new, third argument, behind the existing pattern.
To emphasize this pattern aspect, let's invent a new skip function, skip-one:
skip-one: func [series] [
skip series 1
]
Now we could continue to use the established pattern:
skip-one blk
Question: "What am I doing?"
Answer: "skip-one"
Question: "Who am I doing this to?"
Answer: "blk"
To skip 3 items:
skip-one skip-one skip-one blk
But we want to be more flexible. We want to skip any amount of elements in
a series, not just one. And we don't want to be forced to repeat the same
operation over and over again. That's simple, but exhausting. We must
provide a second argument, the skip-distance.
Yet we want to remain consistent, and keep things simple, by building on
the established pattern, namely, the pattern of single-argument functions.
To put it differently: Since everyone, who programs in REBOL will
occassionally use single-argument functions, we want to implement
two-argument functions to be as similar to single-argument functions as
possible. Like this you learn one thing, the pattern of single-argument
functions, and at the same time you have learned most of another thing:
two-argument functions.
Another aspect: Whenever we use single-argument or two-argument functions,
we are reinforcing a known pattern that is common to both functions. We
can, therefore, more easily remember the pattern of single-argument and
two-argument functions.
So we avoid rearranging the pattern, and instead we limit ourselves to
simply adding the new element to the end of the established pattern. We
retain the sequence of questions and answers, and add a third question
behind questions and answers we would be dealing with anyway, if we were
dealing with a single-argument function.
skip blk 3
The first two questions remain the same:
Question: "What am I doing?"
Answer: "skip"
Question: "Who am I doing this to?"
Answer: "blk"
New Question:
Question: "How much of it am I doing?"
Answer: "3"
Note that the first two questions and answers clarify the most important
aspects: What am I doing, and who am I doing it to. The third question adds
another important piece of information, but that information is derived
from the first two pieces of info.
Hope this helps,
;- Elan [ : - ) ]
author of REBOL: THE OFFICIAL GUIDE
REBOL Press: The Official Source for REBOL Books
http://www.REBOLpress.com
visit me at http://www.TechScribe.com