Re: Strings and the like.
- Posted by "Boehme, Gabriel" <gboehme at POSTOFFICE.MUSICLAND.COM> Dec 08, 1999
- 510 views
Everett Williams wrote (in response to Lucius Hilley): >> What if something like these were built-in? >> >>----------------------------------- >>type whole_number_set(sequence s) >> for A = 1 to length(s) do >> if (s[A] = floor(s[A])) then >> return 0 >> end if >> end for >> >> return 1 >>end type >>----------------------------------- > >I think that you have a small error in these routines, and I would not >see the difference between your's and this: > >type whole_number_set(sequence s) > sequence temp1 > temp1 = (s = floor(s)) > return (find(0, temp) = 0) >end type The difference between your logic and Lucius' is that Lucius' will detect illegal values much faster than yours will. Lucius' routine evaluates one element at a time, returning "false" *immediately* upon the discovery of an illegal value. Your routine is forced to evaluate the whole sequence first, *then* look for a false value. Now, you may not think this makes any difference for type-checking -- after all, an illegal value will cause the program to abort anyway, so what difference does it make how fast it returns a false value? Well, it can make a *big* difference when you employ MANUAL type-checking, i.e., calling the type like a function: sequence s s = get_value_from_somewhere() if whole_number_set(s) then puts(1, "Yippee!\n") -- process the sequence else puts(1, "Dang!\n") -- do some error handling end if You will notice that using *this* kind of type-checking avoids the problems of automatic type-checking happening when you don't want it to. Plus, it gives your program the opportunity to abort gracefully, saving data, displaying a user-friendly error message, etc., etc. Your program may even *expect* to have hundreds of type-check fails in this manner, and need to react accordingly (as is the case with my BGET routine). In this situation, the speed at which the type returns a "false" value can be vitally important. >type byte_set(sequence s) -- I.E.: standard ASCII byte STRING !!! > sequence temp > if whole_number_set(s) then > temp = ((s >= 0) and (255 > s)) > return (find(0, temp) = 0) > end if >end type <PICKYMODE=ON> Sorry, but this routine looks woefully inefficient, no matter what kind of type-checking you do. The following is the speediest string type I was able to create for my BGET routine. It's optimized to return a "false" value ASAP, so it might not be the speediest for automatic type-checking. (It's still mighty fast, though...)type string(sequence s) -- string8 object x for i = 1 to length(s) do x = s[i] if integer(x) then if x < 0 then return 0 elsif x > #FF then return 0 end if else return 0 end if end for return 1 end type </PICKYMODE> >Anyway, I think I recognize a palliative gesture here. You have described a >very specific, very non-embedded Euphoria typing routine here. It appears >that the only way to type check by these techniques is to check the >entire sequence each time that any operation is made on the sequence... >OUCH!!...can anybody spell overhead. Can anybody spell, "use this wisely?" Again, if you don't like the automatic type-checking, do it manually. >The only way to prevent this would >be to assign the substring to be affected to another type-checked variable >before the operation and then assign it back. Not only would this be >clumsy, in some cases it might be tricky and from what I can tell, it would >trigger the type check anyway on the whole string. Depending on how often >the test is triggered for operations that affect the whole or some slice of the >string, this could get ugly. I don't see why this is "clumsy". Again, just type-check MANUALLY in these unusual situations. IMO you are making this sound like far more of a problem than it really is. >OUCH!!...I, as an Euphoria newby, just stomped on a really ugly artifact of >Euphoria and sequences. I see how relational and logical operators produce >multiple results, true values rather than logical values. A logical value is a >temporary item that only exists at the point of comparison unless >deliberately and separately preserved. Unless the comparands are also >preserved, any such logical "value" loses its relevance as soon as those >comparands lose their validity. For validity, where a single logical result is >expected, Euphoria should sequentially "and" together the truth values >for this purpose. This should be valid, for example: > >type whole_number_set(sequence s) > return (s = floor(s)) >end type Sorry, but you completely lost me with the "comparands" and "validity" stuff. Perhaps this is why I don't understand what the problem is here. Euphoria handles its logical operations consistently across all data types. This consistency makes the language easier to understand than other languages with too many exceptional conditions. As for your whole_number_set type, you could just write it like this: type whole_number_set(sequence s) return not find(0, (s = floor(s))) end type Or, if you're going to do a lot of this kind of logic and want it to be more readable, you can use my generic all_true() function: function all_true(sequence s) return not find(0, s) end function Using this, you can then write your whole_number_set type like this... type whole_number_set(sequence s) return all_true(s = floor(s)) end type ...which not only works, but also results in very readable code.
>And in any other case where a single value would be necessary for >consistency. Another example would be: > >sequence s >s = "ABCD" >if s = floor(s) then .... > >end if Again, your proposal does not strike me as being "consistent." This could just as easily be accomplished by coding: if all_true(s = floor(s)) then... >This is a major logical hole in the language. No, it isn't. If you want it to work differently, it's quite easy to make it do so, as I have shown. Hep yadda, Gabriel Boehme ---------- If we can define our aim, we are halfway to achieving it. Robert Fripp ----------