[EMAIL PROTECTED] wrote:
> 
> I'm probably going to get beaten up for this :), but if my question is
> totally absurd, please excuse my ignorance...
>

The only absurd questions are those that are asked out of malice or not
asked out of timidity.  ;-)  I may have strong opinions on what I'd like
to be able to do in my own programs, but certainly don't want that to
come across as negative value judgements on anyone who wishes to write
in a different style.

> 
> You seem to put a lot of emphasis on being able to use block!s as keys. Is
> this really necessary or desired?
> 

Well, in terms of strictly "necessary", we could just write everything
in
tcl, where all data are strings (even data structures).  However, REBOL
gives us this really nice collection of various data types.  Why NOT be
able to use them?  As the only thing really necessary for looking up a
key is to do an equality test, why shouldn't keys be able to come from
any data type for which the concept of "equal" makes sense?

Also, as one of my co-workers pointed out to me, a  block!  is a generic
container into which I'm allowed to put any kind of REBOL data I wish.
If  find  (for example) is defined to work on blocks, then why shouldn't
it work on blocks that contain anything blocks are allowed to contain
(such as other blocks)?

In terms of "desired", I certainly desire that capability!
Let me give an example:

Suppose I have a file of data on school children, which includes age and
grade level for each student.  Now suppose I'm asked to cross-tabulate
age and grade level for some report.  This means I need a set of
counters,
where each one corresponds to a specific combination of age and grade. 
It
would be very pleasant, IMHO, to be able to write something like the
following sketch:

    age-grade-tab: assoc/new
    foreach studentrecord read/lines %studentdemographics.data [
        age:   get-age studentrecord
        grade: get-grade studentrecord
        a-g:   reduce [age grade]     ; the key IS the combination!
        age-grade-tab/put  a-g  1 + any [age-grade-tab/get a-g 0]
    ]

Now someone may ask why I didn't just use a two-dimensional array, with
age and grade as subscripts.  A couple of reasons immediately come to
mind:

0) A counter is identified by a combination of two facts: age and
   grade.  REBOL provides me with a handy datatype for representing
   compound values: the block!  Why shouldn't I use it?

1) Such an array would be very sparse!  As most of the values are
   clustered along a narrow diagonal band, it would be nice to limit
   my storage requirements to age/grade combinations that actually
   exist.  (Please remember that this is a small example of a more
   general concern.  I'm only illustrating the fact that arrays are
   often wildly space-inefficient; I'm sure you can all come up with
   many examples that are even more extreme, such as weight in grams
   versus height in centimeters, etc.)

2) Who says that grade is an integer?  Perhaps the coding scheme is
   that "K" is kindergarten, 1-8 are grade numbers, "Fr" "So" "Jr"
   "Sr" are the last four levels of high school, "GED" high-school
   equivalent coursework for adults, and "AE" is adult education
   courses for high school diploma holders.  In this case we not only
   can't use the grade as a numerical index, but now our ranges of
   values for both age and grade have become much larger, greatly
   aggravating the sparse-array problem above.

3) Notice that the code sketch above is unaffected by changes in
   these issues.  If I originally wrote the code above only for
   an elementary school (ages 6-11, grades 1-6) and was suddenly
   asked to produce the same report for an entire traditional system
   (ages 4-18, grades 1-12) or a non-traditional school (with the
   non-numeric grade codings and ages 4-90), the above code wouldn't
   break.  Isn't writing generalized code that doesn't break a good
   thing to do?

Turning the output side of the report, I can start with something as
simple as

    foreach k age-grade-tab/keys [
        print [k ":" age-grade-tab/get k]
    ]

which works for all of the above cases.  However, if I need to provide
a more orderly report, I'll probably write something like

    foreach k sort/compare age-grade-tab/keys age-grade-sorter [
        ; with some nice layout tricks not relevant to this point
    ]

If there is simply a range expansion (grades 1-12 instead of 1-6,
with ages 4-18 instead of 6-11) the above code still works (ignoring
layout issues).  If we go to the mixed coding of (2) above, all I
have to do is go to one function  age-grade-sorter  and adjust it
appropriately.  All of the rest of the code still works.

I VERY much like the idea of encapsulating each policy decision in
exactly one place in the code.  The idea of having to transform data
back and forth between a natural representation and an agglomerated
string throughout my program (just because some language feature has
a bias in favor of strings) strikes me as very ugly, as well as a
fruitful source of coding and maintenance errors.

I could make up more examples, but I hope the single one above is
adequate to explain the "flavor" of the concept without more belaboring.

>
> It seems like an implementation would be easier and/or more efficient if we
> didn't have to worry about that case. Same for logic! values :)
> 

What worry?  REBOL already knows how to take two values and compare
them for equality.  The  block!  and  logic!  types just happen to
be two examples of that more general principle.

What if I wanted to tally up the birthdates of the students?  Isn't
it meaningful to use a  date!  key for a count of how many students
had a birthday on that date?  REBOL already can do that, and equality
comparison on  date!  values is much more complex that testing
 logic!  values for equality.

>
> Many other languages get by with just strings for keys, ...
> 

Many other languages "get by" without MOST of the nicer features of
REBOL.  If all I wanted was a language which could "get by", I'd
keep writing in C.  REBOL has been presented as a high-level language
which can do make use of a wide range of user-friendly data types.

I think it is unfriendly to have arbitrary restrictions on which of
them can be used in some situations.

>
> ...why do we have to be able to use every Rebol data type as a key?
>

Anyone who wants to use only strings as keys, and can get his/her
work done effectively under that restriction has my blessing.  I'm
not trying to force anyone to use any feature they don't see a need
for.

On the other hand, I'll be sad if the hypothetical person in the
previous paragraph tells me that I CAN'T use any other type of key,
even when I can see good reason to do so in my own code.

-jn-

Reply via email to