1. Re: [If/then and sequences...]
Hi Hawke',
I'm not very good at explaining myself am I? Sorry about that
Also, I am
NOT trying to argue a postion or win anybody over to my opinion. I am trying
to explain my thoughts on this topic and to gain understanding about the
reasons behind Robert's design decisions.
----- Original Message -----
From: "Hawke'" <mikedeland at NETZERO.NET>
To: <EUPHORIA at LISTSERV.MUOHIO.EDU>
Sent: Wednesday, August 30, 2000 10:29 PM
Subject: Re: [If/then and sequences...]
> in most languages, actually, you dont have sequences, and its not allowed
> to perform the actions that we do in euphoria, that are oft taken for
> granted,
> upon entire arrays...
> unless u go thru painstaking for loops examining every array element...
Yep, that's true. And a great thing it is too! I am also convinced that
sequences are great. No arguments there at all.
>
> eg:
> sequence ages, teens
> ages = {10,20,22,12,32,55,34,23,15}
> function IsTeenager(sequence data)
> return (data >=13) and (data <=19)
> end function
> teens = IsTeenager(ages)
>
> now u have a nice neat list of 0's and 1, in a sequence, showing u the
> indexes of all the teenagers, and the find() command will neatly locate
> those indices...what could be simpler?
>
Not much indeed. A very neat, simple and elegant construct. Truly a "good
idea". It just that the symbols "<=" and ">=" mean different things
depending on what they are applied to. I just thought it might have been a
better idea to have them mean one thing only in all situations. By all means
have a built-in function that performs the operation on sequences like they
currently do, but use the syntax of a function call rather than the syntax
of an operator. To the uninitiated, "{10,20,22,12,32,55,34,23,15} >= 13"
might reasonably be assumed that it returns a sequences of all elements that
are greater than or equal to 13, namely {20,22,32,55,34,23,15}. The fact
that it doesn't is a design decision by Robert. He chose to implement it as
a recursive ">=" comparison operator on each element. There's nothing wrong
with this sort of operation on sequences, I just wish he had chosen a
different way to implement it.
> try that in pascal or C, and you are looking at for loops, bunches of
> temporary storage array/variable declarations, and many lines of code...
>
Agreed, I'd hate to do it.
> >What you've demonstated is that in Euphoria, these operators return
> >a boolean when both operands are atoms, and return a sequence
> >when either operand is a sequence
> ERRRRRRRRRRRRR
> it returns a sequence OF booleans, that matches the original size and
depth
> of the original sequence
> atoms beget a single 'atomic' boolean result
> sequences beget a sequence of boolean results...
> seems logical to me :)
>
Ain't diversity wonderful. It would be a very dull world if we all thought
the same way. BTW, what does Euphoria return with this statement ... "atom1
& atom2" ? Is it an atom or a sequence?
> > (unless the operand is used in an IF statement, in which it is illegal).
> because there is no way to determine WHICH boolean within the sequence
> you want to look at...
> if u SPECIFY which boolean you want to look at within a sequence, by
> referencing it SPECIFICALLY, then it works just fine...
Yes, I know what Euphoria does here, but most what most coders mean when
they write "if A = B" is "does A have the same value as B?" and given that
the Euphoria can see the values at run-time, the answer is either Yes or No.
It doesn't matter if A or B are atom or sequences - the question being asked
is simply "are they the same?" not "if these are atoms, are they the same,
but if these either of these are sequences, build another sequence that
shows me where they might be different."
> eg: same as above
> if ages = 12 then puts(1,"almost a teenager") end if
> like...DOH, wont work...which person are you talking about???????
Of course in Euphoria this statement doesn't make sense because its
ambiguous at best. Does the coder what to know "is any age 12?", "does every
age in the set = 12?", "does the entire set consist of one age and is that
age = 12?". Mixing data types in a comparision (atoms v sequences), I
suspect, would not normally be a common requirement. In other languages,
these symbols (=><) are 'comparsion' operators - that is they are used to
ask questions about how one operand *compares* with another operand - Robert
has chosen to make the same symbols mean 'comparision' operators with atoms
and mean logical functions with sequences. In other words, in some
situations they return a boolean result (YES/NO) and in others they return a
sequence (of booleans - but still a sequence).
>
> if ages[3] = 12 then puts(1,"almost a teenager") end if
> well kick butt! now we know what person we are talking about, and
> everything is kosher and still maintains absolute logicality....
>
Assuming that the coder wanted to find out if person #3 is 12 or not.
> >And that compare() function always returns an atom
> of course, because we need a method which will allow sorting...
> all compare() does is recursively analyze the results of a boolean
> logic operation which was recursively applied to a sequence,
> just like the example above, and neatly sends back a singular
> boolean result instead of the list of results.
> saves us having to actually thread a for loop or a find() function...
> does it faster usually too cuz rob can take shortcuts...
> and in reality, its more like a tri-state boolean that gets returned, not
an
> atom...
>
Mmmmm "tri-state boolean", an interesting term - sort of like "dry water",
"solid vacuum", "military intelligence", "Micro$oft care", ... Sorry - no
offence - I just love oxymorons. I do understand what you're saying. And I
agree with you - 100 percent. I just think that the roles of '=><' and
'compare()' should have been reversed - that is compare() should return the
sequence of boolean values and =>< should return a single boolean in all
cases. Look its no big deal. I'm sure Robert has very good reasons for makin
g it like this - I just can't see them yet, that's all.
> >(and equal() function always returns a boolean)
> function equal(object a, object b)
> return compare(a,b) = 0
> end function
> that's all rob is doing...it was an include to the core language for
> conveince
> sake, nothing more, nothing less....it makes code a touch cleaner, and
> everyone
> was always putting that function i just wrote into their code toolbox
> anyway...
> saves a wee typing...shrug...no magic here
Of course to save even more typing and add even more convenience, why not
use '=' instead of 'equal()'? I'm sure every coder knows what I mean by ...
while UserAnswer != "quit" do
...
end while
because of the traditional meaning of '!=', but in Euphoria I must code ...
while not equal(UserAnswer, "quit") do
...
end while
which is 9 more characters and less "english-like" when you read it out
aloud.
> >In my mind that is inconsistent and also not simple.
> function IsTeenager(sequence data)
> return (data >=13) and (data<=19)
> end function
> what is not simple about that function ????
> where is the inconsistency???
> seems quite clear and consistent to me?!?!?!?!
>
Well, one interpretation is "This function returns the set of all numbers
that are common to the subsets 'the set of data that are >= 13' and 'the set
of data that are <= 19'", which of course is not true. But, if Robert had've
chosen to implement these symbols to perform set operations, this is a
possible interpretation. What is not obvious, unless one is aware of
Euphoria's non-traditional use of '<=' and '>=', is that this function
returns a sequence of booleans that map onto the original sequence to show
which elements meet the criteria. With your example data above, this would
return {0,0,0,0,0,0,0,0,1}. Now, if consistancy were an overriding design
criteria in Euphoria, the find() function could be used to return a sequence
of hits! Such that find(1, IsTeenager({9,14,44,15,21,90}) would return
{2,4} - the two(!) positions that are teenagers.
> > Its just that from my point of view, it would have been more intuitive,
> and
> > simpler, to reverse this arrangement of Robert's. That is, have the '<',
> > '>', and '=' operators always return a boolean (and allow their use in
> IFs),
> > and have the compare() function return a sequence.
> wanna try writing IsTeenager useing that proposed method???
> and have it return a list of boolean values that are exactly nested
> as the passed sequences??????
>
Sure...
function IsTeenager(sequence data)
return not (compare(compare(data,13) + compare(data,19), 0))
end function
compare({10,20,22,12,32,55,34,23,15},13) --> {-1,1,1,-1,1,1,1,1,1}
compare({10,20,22,12,32,55,34,23,15},19) --> {-1,1,1,-1,1,1,1,1,-1}
add them together --> {-2,2,2,-2,2,2,2,2,0}
compare(...,0) --> {-1,1,1,-1,1,1,1,1,0}
not (...) --> {0,0,0,0,0,0,0,0,1}
but I take you're point. A compare() function that returns a "tri-state"
boolean (gotta love that term) might not be the best one to use in this
situation. Okay, so maybe a ge(), gt(), le() and lt() set of sequence
functions would be handy.
function IsTeenager(sequence data)
return (ge(data,13) and le(data,19) )
end function
> something like this i suppose???
>
> function IsTeenager(object data)
> if atom(data) then return data end if
> for i = 1 to length(data) do
> if sequence(data[i]) then
> data[i] = IsTeenager(data[i])
> end if
> if (data[i] >= 13) and (data[i]<=19) then
> data[i] = 1
> else data[i] = 0
> end if
> end for
> return data
> end function
>
> hrmmmm, not so clear now????
Well done. Point admirably made. Euphoria *does* need sequence functions
that return a sequence of booleans. Thoughly agree.
> hell, i aint even sure that's a fully perfect function to do the task...
> i aint tested it, and i would have to test it to make sure it works...
>
> but i ***KNOW*** from just looking at it, without a doubt,
> what the following code does:
and that's because you know of Euphoria's non-traditional use of these
comparision operators.
> function IsTeenager(sequence data)
> return (data >=13) and (data<=19)
> end function
>
> shrug, i prefer knowing with a glance what code does...
> and the second function really looks a lot less complicated to me...
me too!
> >This probably would have
> >made the equal() function redunant. Of course its WAY too late to
introduce
> >this sort of change to the language, and I'm not advocating that. I'm
just
> >wondering why Robert decided to arrange the language the way he did.
> see above????
See what? All we have shown is that sometimes we need to know whether or not
two sequences are the same as each other, and sometimes we need to know
where, if any, differences between to sequences exist. What I haven't
established is why Robert chose the current way of doing this, as opposed to
any of the hundreds of other ways of achieving the same thing.
> > Current:
> > Operation Operands Allowed in IF Result
> > -------------------------------------------------------------------
> > =/>/< atoms yes boolean
> > =/>/< sequences no sequence
> errrr NO....
> that should read:
> =/>/< sequences no (without proper referenced indicies)
sequence
> of booleans
Is what I said wrong? Are these symbols allowed with sequences in IF
statements? Even with "proper referenced indicies", if this references a
subsequence I'm stuffed.
> > =/>/< mixed no sequence
> what is 'mixed'?????
I'm sorry - by "mixed" I meant one operand is a sequence and the other is an
atom.
> we have no 'mixed' data type in EU...
> it is an integer, an atom, a sequence, or an object...
>
> > compare() atoms yes atom
> > compare() sequences yes atom
> > compare() mixed yes atom
> errrrr more properly, that would be
> compare() atoms yes tristate boolean
(love the term) However isn't a "tri-state" boolean an atom? In fact, could
we have also a called it an integer.
> ditto for sequences....logical and consistant
>
> > equal() atoms yes boolean
> > equal() sequences yes boolean
> > equal() mixed yes boolean
> tis only a shortcut for typing, as per above, and does no magic...
>
> > if atom yes boolean
> > if sequence no n/a
> as per above, u cannot determine WHICH part of the sequence
> you are looking at without telling the interpreter which part of
> the sequence you are referring to...
Yeah, I know, I know...
> elegance comes from the
> manner rob has defined the language as it stands...
>
> lets suppose you want a function that examines any valid
> pair euphoria objects, atoms or sequences, no matter how big or
> nested they might be and determines which of them is the
> smallest, or the minimum, persay...
> to wit:
> constant
> first ={10,20,30,20,10},
> second={20,10,40,10,20}
> sequence result
> result = minimum(first,second)
> --result would now be = {10,10,30,10,10}
>
> a function like this is extremely handy for fuzzy logic and
> graphics applications
> the function to do this was written long ago with one line
> of euphoria code, and is as simple and elegant as they come
> (by lucius i believe)
> function minimum(object a, object b)
> return a*(a<=b) + b*(b<a)
> end function
Kinda looks a bit 'C'-like don't it. At-a-glance-obvious code.
>
> i dont believe it gets much simpler or clearer then this in a language...
>
Sure is. And I'm glad Robert had the foresight to include such a 'minimum'
function
A great design decision!
> if you really really MUST have your greater() and lesser() functions
> then try these:
>
> function greater(object a, object b)
> return compare(a,b) = 1
> end function
> function lesser(object a, object b)
> return compare(a,b) = -1
> end function
>
>
> problem solved?????
>
Hey, what a great idea for a built-in function!
> hope this helps clear things up as to why EU does things the way
> it does, and further elaborates on Irv's post as to why things
> function they way they do in EU...
Well.... not really. It does clear up WHAT Euphoria does, just not WHY.
Look in the end, it doesn't really matter because the language ain't gonna
change now. [Unless I get around to finishing my Eu-compiler with extensions
]
----
cheers,
Derek