Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Comparing logic! [was Re: WYSIWYG programming]

From: joel:neely:fedex at: 28-Oct-2000 17:42

Hi, Brett, [rebol-bounce--rebol--com] wrote:
> Hi Joel, > > > That sounds good. However, natural language and the common-sense > > expectations of 'normal' people (or even programmers when they're > > not programming) are notorious for their ambiguity and fuzziness. > > Important qualities that traditional computing cannot deal with. >
This is not really an issue of "legacy" computing versus new-age computing (or whatever one would call it ;-). Rather it is an issue of whether it is important to be able to reliably state what will happen. Consider all the various sciences, engineering, software requirements, contracts, treaties, and all the branches of law. It's A Good Thing if a line of poetry has multiple interpretations. It's funny when an actor utters a line that has multiple meanings, and then the plot takes various twists when different characters act on those differences. But when I'm buying a house, applying for health insurance, signing an employment contract, driving over a newly opened bridge, reading the warranty on a product I just bought, or using a programming language, I most definitely do not want any surprises due to hidden meanings, fine print, ambiguity, or obscurity. I recall a conversation involving a lawyer and some non-lawyers who were razzing him about how unreadable most contracts are. His reply was, "You're absolutely right. But the purpose of contract language is not to be readable; it is to be unambiguous."
> > > > I humbly propose that the need for precision in programming means > > that rigorous, elegant, and minimalist definition should take > > priority over everyday conversational comfort, should they ever > > come into conflict. > > Respectfully, I think you are putting up a language design goal > that many (most?) computer languages have been aiming for for > years. The same thing that many (most?) serious (experienced?) > programmers would aim for in their programs. A mindset legacy of > structured programming, provable programs, etc. There is nothing > wrong with this - indeed it is necessary line of thinking, and up > until recently I would have seconded your proposal for Rebol to > follow this goal. >
Let me state clearly, in case I have miscommunicated my view, that I am NOT proposing nor advocating any radical changes to REBOL. I am assembling a list of areas in which I feel the details could use some polishing, and have attempted to explain my motivations for that effort. I have also discussed some areas in which REBOL is sufficiently unique (compared to the general field of prog. lang.) or subtle (in and of itself) that special care may be needed in documenting and explaining it. However, I do not suggest that there's anything fundamentally "wrong" with REBOL -- if I held that view, I simply wouldn't bother. There are, after all, plenty of other programming languages.
> Now I think otherwise. > > 1) If feel that "rigorous", "elegant" and "minimalist" are from > the Mathematical space of thinking. >
Speaking as someone with a bit of familiarity with Mathematics (2+ degrees and 12 years teaching Math and Comp Sci), I agree. I must add in passing that most folks find my definition of Mathematics very different from what their academic experience has led them to believe.
> Paradoxically, I think these concepts are very subjective. >
If by "subjective" you mean "simply a matter of opinion" then I disagree emphatically. If you mean "sufficiently subtle that they cannot be defined in a 15-second sound bite" or "unlikely to be assessed reliably by someone without significant experience", then I wholeheartedly agree. I don't want to sound elitist here, but let me give a couple of analogies that I believe are valid. A master carpenter can walk into a house that is at the stud-wall level of construction and almost instantly spot a flaw in the framing. However, it might take him several minutes to explain exactly what's wrong -- and the negative consequences that could occur -- to a someone who is a ignorant of house framing as I am. It is quite possible, in fact, that my background is so limited that I simply won't understand his concern no matter how carefully he explains it (although that is probably very unlikely, not because I know much about carpentry, but because most of the good carpenters I've been around can explain what they do fairly well). I've also had the experience of taking a car with one or two fairly subtle symptoms to an expert mechanic who could almost interrupt me before I finished my description and tell me what was wrong. So it is with elegance in Mathematics (of which Computing Science is a close relative).
> 2) I believe one of the main aims of Rebol is to be a useful > language. Its practical and pragmatic approach has been the > selling factor for me to invest my time in it. That said, I do > agree with you (and others) that it needs a more detailed > supporting documentation set on the language, but I can accept > that the language itself is still stabilising. >
Agreed on all points. Actually, some folks are surprised that I consider one of the most endearing properties of Perl that it is conceptually much closer to natural (human) languages than it is to most programming languages.
> 3) "precision in programming" reminded me of the often heard > "Arrgghh! It did what I said, not what I meant!". I'm hoping > that Rebol will succeed in reducing the occurrence of this > phrase via dialecting. >
Dialecting is a nice device -- and REBOL is not the only language that uses such a device. However, it's just a device, and poor design can afflict dialects as well as entire languages.
> I hope you don't find my comments frustrating - I am deliberately > "coming in from a different angle". They are meant to invite the > questioning of perhaps long held "truths". In the Rebel fashion ;) >
Quite the contrary! Probing such a topic from as many angles as possible is one of the most effective ways to understand it, IMHO. I certainly spend enough time inviting questioning of perhaps more recently held positions! (One of my favorite quotations says, There are two kinds of fool in the world. One kind says, "This is good because it's old." The other kind says, "This is better because it's new."
> One last thing which has perplexed me with this whole thread. > Your example of the ordering of logical values. Why? >
The issue was not about an burning need for logic! values to be considered as an ordered set. I was simply demonstrating an inconsistency in how data values are handled. However, I admint that this inconsistency is annoying to me, for reasons which I illustrate below, following your next question. REBOL lets me convert back and forth between logic! and integer! data, with the correspondence that FALSE <-> 0 and TRUE <-> 1. It also lets me compare/sort integer! values, but refuses to let me compare logic! values, even though the correspondence above clearly (to me, at least) is consistent with the interpretation that FALSE < TRUE. If I have two number! values, they compare in the same way as their integer! equivalents. Two character! values also compare in the same way as their integer! equivalents. Converting to and from integer! preserves the ordering of these values. It seems odd to allow ordering to be preserved over all the other types that can interconvert with integer! and yet refuse to allow that for logic! values.
> What do you use such a thing for? >
Let me give a tiny example of how one could use that capability, and why I view the inconsistency as too costly. Consider the function defined as tally: func [b [block!] /local c t v n] [ c: sort copy b t: copy [] while [not tail? c] [ v: first c n: 0 while [all [not tail? c v = first c]] [ n: n + 1 c: next c ] append/only t reduce [v n] ] t ] This function just tallies up the number of occurrences of each value in a block. If I have a block containing the ages of a second-grade class, ages: [7 6 7 7 8 6 8 7 7 6 6 7 7 8] I can say
>> tally ages
== [[6 4] [7 7] [8 3]] and learn that there are 4 six-year-olds, 7 seven-year-olds, and 3 eight-year-olds. Bear in mind that the block could have been the result of user input, or could have been extracted from data in a disk file, or calculated from birthdates... it doesn't matter where the data came from. Sorting is a convenient way to group data for a variety of reasons, and (depending on your application domain) Tally might be a handy addition to your toolkit. ALSO... We could write another function (using "ASCII art" in /Core or /Command, or the graphical features of /View) which would take an argument block, call Tally to get a summary, and then draw a bar graph of the results, something like 6: #### 7: ####### 8: ### I won't bore everyone with the bar-graphing code, but my point is that once we have Tally, we may use it either stand-alone, or build on it to define other additions to our re-usable library. Our little Tally function can also handle other data. Suppose I have the home states of a group of people. homestates: ["TN" "CA" "NY" "CA" "TN" "WA" "CA" "WA" "AR" "TN"]
>> tally homestates
== [["AR" 1] ["CA" 3] ["NY" 1] ["TN" 3] ["WA" 2]] Now, suppose I have a block that tells me whether each of a group of people are going on the company picnic.
>> picnic: reduce [yes no no yes yes no yes yes yes no yes yes]
== [true false false true true false true true true false true true] (Remember, that 'yes 'no 'on 'off 'true 'false are just words that are predefined to REBOL logic values TRUE and FALSE. I reduced the literal block in this example to get "real" logic! data, which we would have gotten if we were producing the true/false values from other code.)
>> tally picnic
== [[false 4] [true 8]] Notice: REBOL SORTS LOGIC! VALUES, using the same implied order that we would infer from the corresponding integer values -- FALSE < TRUE. Now, back to our Tally function... Suppose I have some student test scores... scores: [90 95 90 100 85 90 90 80 95 90 100 95 100] ...and I am mostly interested in the top performers. I can certainly use Tally for that purpose...
>> tally scores
== [[80 1] [85 1] [90 5] [95 3] [100 3]] ...but wouldn't it be nice if I could see them in highest-to-lowest order as well? Guess what? Sort lets me supply a comparison function to cause the ordering to be whatever I want. Let's take advantage of that to make a nicer Tally. tally: func [b [block!] /compare f [function!] /local c t v n] [ c: copy b either compare [ sort/compare c :f ][ sort c ] t: copy [] while [not tail? c] [ v: first c n: 0 while [all [not tail? c v = first c]] [ n: n + 1 c: next c ] append/only t reduce [v n] ] t ] Now I can say
>> tally/compare scores func [a b] [a > b]
== [[100 3] [95 3] [90 5] [85 1] [80 1]] as well as
>> tally/compare homestates func [a b] [a > b]
== [["WA" 2] ["TN" 3] ["NY" 1] ["CA" 3] ["AR" 1]] but if I try to say
>> tally/compare picnic func [a b] [a > b]
** Script Error: Cannot use greater? on logic! value. ** Where: a > b So, I ask you, what sense does it make for REBOL to allow sorting of values that it refuses to compare???? Doesn't common sense (using either your sense or mine... ;-) lead us to believe that sorting is just repeated comparison and shuffling among a bunch of data values? Grumble, grumble, grumble... SO NOW... In order for Tally to be as re-usable as possible, we either need to complicate Tally with a check on the data in the argument block (and have it ignore any custom comparison in the case of logic! values), or we have to remember never to use custom comparison functions with logic! values ... WAIT A MINUTE! Remember our imaginary bar-graphing function that could be based on Tally? Now we have to worry about whether it may call Tally with custom comparisons as well... Oh, what a tangled web we weave When first we practice inconsistency! Inconsistency puts all kinds of sand in our shoes when we start trying to write general, reusable code. Hence my strong personal preference for rooting it out as early as possible! Hope this helps put my grumpiness into perspective! ;-) -jn-