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

I hate computers!

 [1/12] from: edanaii::cox::net at: 4-Jan-2003 9:34


No, really! I do. Well, OK, when they don't do what I want, I hate 'em. :) This is driving me nuts. I whipped up a small routine to validate parameters. It is relatively simple, You pass it the parameter, you pass it a series full of datatypes, it compares the two and tells you if your parameter's datatype is valid (IOW, in the series). But it's actin' strangely. Here it is: ====================================================================== REBOL [] Valid-Type?: Func [ Parameter [Any-Type!] DataTypes [Series!] ] [ ForEach DataType DataTypes [ If (Type? Parameter) = DataType [ Return True ] ] Return False ] ====================================================================== The problem is in the line "If (Type? Parameter) = DataType" it just doesn't work. When I call the routine, it does this:
>> Valid-Type? "x" [ String! Money! Integer! ]
== false Which is incorrect. It should be "true" since "x" is clearly a string. The only way it works, is when I change the line in question to "If (join (to-string Type? Parameter) "!") = (to-string DataType)", which is a little counter-intuitive. So, bug or oversight? And is there, as always, a more elegant way of doing this? -- Sincerely, | The problems of two little people don't amount to Ed Dana | a hill of beans in this crazy mixed-up world! But Software Developer | this is OUR hill, and these are OUR beans! 1Ghz Athlon Amiga | -- Leslie Neilson, Naked Gun (Casablanca).

 [2/12] from: joel:neely:fedex at: 4-Jan-2003 11:20


Hi, Ed, You're 95% there!!! (see below) Ed Dana wrote:
> ... I whipped up a small routine to validate parameters. It is > relatively simple, You pass it the parameter, you pass it a series > full of datatypes, it compares the two and tells you if your > parameter's datatype is valid (IOW, in the series). > > But it's actin' strangely. >
It's doing just what you designed it to do. (Maybe you want to design it to do something different... ;-)
> Here it is: > ...
<<quoted lines omitted: 3>>
> == false > Which is incorrect. It should be "true" since "x" is clearly a string.
The problem is that your usage above isn't passing a block of types, but a block of words! (Others have been bitten by this; wrapping a collection of words in a block keeps them from being evaluated at unless you expressly ask for DO or REDUCE at some point.)
>> foo: [string! money! integer!]
== [string! money! integer!]
>> foreach item foo [print type? :item]
word word word
>> foo: reduce foo
== [string! money! integer!]
>> foreach item foo [print type? :item]
datatype datatype datatype We can fix this either of two ways: 1) either make sure that the calling expression really passes a block of data types...
>> valid-type? "x" reduce [string! money! integer!]
== true 2) or rewrite your function to perform the reduction for you ( which is safe because reducing a block of data types gives back a block of data types)... ====================================================================== valid-type?: func [ parameter [any-type!] datatypes [series!] ][ foreach datatype reduce datatypes [ if datatype = type? parameter [ return true ] ] return false ] ====================================================================== And now, if you'll pardon the editorializing, a couple of suggestions: 1) Use the standard REBOL conventions for code layout (including capitalization) to make your code more readable to the widest audience on the list. 2) Use the fact that parameters values are local to avoid having to evaluate TYPE? PARAMETER over and over for all values in the block of types. 3) Use the fact that the value of a function evaluation is the last expression evaluated in the function (lose the RETURN in the last line reading RETURN FALSE). 4) Use the fact that the value of a FOREACH is the last expression evaluated inside the body. Use the fact that the value of an IF expression is either the value of the controlled expression if the guard is true or is NONE if the guard is false (and NONE acts as false for most purposes). In other words, of none of the tests succeed (causing the RETURN TRUE to evaluate) then the last IF evaluates to NONE, and so does the FOREACH, and therefore so does the entire function! A version utlizing all of these hints appears as: ====================================================================== valid-type?: func [ parameter [any-type!] datatypes [series!] ][ parameter: type? parameter foreach datatype reduce datatypes [ if datatype = parameter [ return true ] ] ] ====================================================================== Hope this helps! -jn-

 [3/12] from: joel:neely:fedex at: 4-Jan-2003 11:32


Hi, again, Ed, Man, is my face red!!!!! I was so focused on the incremental transformations that I overlooked the totally obvious solutions: valid-type?: func [param [any-type!] types [series!]] [ found? find reduce types type? param ] Sorry for the wasted bandwidth!!! ;-) -jn-

 [4/12] from: dockimbel:free at: 4-Jan-2003 18:54


Hi Joel, Here's an alternative approach, if you want to avoid the 'reduce call : valid-type?: func [param [any-type!] types [series!]][ to logic! find types type?/word param ] -DocKimbel En réponse à Joel Neely <[joel--neely--fedex--com]>:

 [5/12] from: g:santilli:tiscalinet:it at: 4-Jan-2003 19:58


Hi Joel, On Saturday, January 4, 2003, 6:20:39 PM, you wrote: JN> ====================================================================== JN> valid-type?: func [ JN> parameter [any-type!] JN> datatypes [series!] JN> ][ JN> parameter: type? parameter JN> foreach datatype reduce datatypes [ JN> if datatype = parameter [ JN> return true JN> ] JN> ] JN> ] JN> ====================================================================== And of course, one could also write: valid-type?: func [ parameter [any-type!] datatypes [block!] ; are you sure to want series! here? ] [ found? find reduce datatypes type? parameter ] Anyway, this function has the little problem of not working with pseudo-types. (Just warning you, maybe you don't need to use them.) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [6/12] from: joel:neely:fedex at: 4-Jan-2003 14:07


Hi, Doc, Tradeoffs about... ;-) [dockimbel--free--fr] wrote:
> Here's an alternative approach, if you want to avoid the > 'reduce call : > > valid-type?: func [param [any-type!] types [series!]][ > to logic! find types type?/word param > ] >
OTOH, staying with the REDUCE allows one to use VALID-TYPE? with exemplars as well, since the expressions would evaluate to types in something like valid-type? foo [type? something type? somethingelse] Good thing the cat has nine lives, as he can be skinned so many different ways! -jn-

 [7/12] from: joel:neely:fedex at: 4-Jan-2003 14:23


Hi, Gabriele, Gabriele Santilli wrote:
> And of course, one could also write: > valid-type?: func [
<<quoted lines omitted: 3>>
> found? find reduce datatypes type? parameter > ]
(see my red face... At least I ended up with the same solution as yours, which makes me cheerful! ;-)
> Anyway, this function has the little problem of not working with > pseudo-types. (Just warning you, maybe you don't need to use > them.) >
That reminds me of a couple of other interesting question whichs I never put the thought into solving, but which someone on the list may have already pondered: 1) Since pseudo-types (e.g., SERIES!) are simply identified by REBOL as data types (not a distinct "pseudo-type" type), what is the best way to determine whether a value of type DATATYPE! is a "physical" type or a "pseudo" type? 2) Given two datatypes, is there a simple way to determine whether one is a super-type of the other? super-type? number! integer! ==> true super-type? series! string! ==> true super-type? number! logic! ==> false super-type? any-string! file! ==> true Any suggestions (other than brute-force enumeration, of course) would be welcomed! -jn-

 [8/12] from: al:bri:xtra at: 5-Jan-2003 10:20


jn wrote:
> 1) Since pseudo-types (e.g., SERIES!) are simply identified by REBOL as
data types (not a distinct "pseudo-type" type), what is the best way to determine whether a value of type DATATYPE! is a "physical" type or a pseudo type?
>> Physical?: func [Datatype [datatype!]] [
[ attempt [make Datatype 0 true] [ ]
>> Physical? string!
== true
>> Physical? foo!
** Script Error: foo! has no value ** Near: Physical? foo!
>> Physical? series!
== none
>> Physical? number!
== none
>> Physical? function!
== none Basically trying to 'make the real value. Unfortunately, it doesn't work for 'function!, which requires two block! values and crashes Rebol when using a 0 value instead. Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [9/12] from: rotenca:telvia:it at: 5-Jan-2003 2:41


Hi Andrew,
> determine whether a value of type DATATYPE! is a "physical" type or a > "pseudo" type?
<<quoted lines omitted: 4>>
> 'function!, which requires two block! values and crashes Rebol when using a > 0 value instead.
It does not work also for action!, datatype!, date!, error!, function!, get-word!, library!, lit-word!, native!, object!, op!, port!, refinement!, routine!, set-word!, struct!, symbol!, tuple!, unset!, word! This function t-d?: func [x][if error? set/any 'x try [make x] [x: disarm x return x/id <> 'cannot-use] true] fails on: action! datatype! native! op! unset! This is a very empirical example which happens that fails only on unset! (but is unset! a real datatype?): t-d?: func [x /local y][ if parse/all second system/words [ to x skip to x y: skip to end ][return x = type? first y] true ] I think that we need some natives to works on datatype!, for example: 1) pseudo-datatype? pseudo-datatype? any-string! ;== true 2) in-datatype? in-datatype? any-string! string! ;== true 3) parent-datatype? parent-datatype? string! ;== any-string! parent-datatype? any-string! ;== series! --- Ciao Romano

 [10/12] from: edanaii:cox at: 5-Jan-2003 9:26


Joel Neely wrote:
>OTOH, staying with the REDUCE allows one to use VALID-TYPE? with >exemplars as well, since the expressions would evaluate to types >in something like > > valid-type? foo [type? something type? somethingelse] > >Good thing the cat has nine lives, as he can be skinned so many >different ways! >
But would you want to do this? The purpose of the function was to allow the use of multiple datatypes for a parameter and still keep it optional. As was pointed out to me earlier, the use of Any-Type! seems to make a parameter optional. Were I to define a parameter as such: Parameter [ String! Money! ], if I omit the parameter when called, it blows up. But with any-type!, it doesn't. So this was a means to have multiple parameters and have it optional. This would allow me to do some overloading, i.e. fall Foo with a String performs a different action than Foo with Money or Foo without a parameter. -- Sincerely, | Don't part with your illusions. When they are gone Ed Dana | you may still exist, but you have ceased to live. Software Developer | -- Mark Twain 1Ghz Athlon Amiga |

 [11/12] from: lmecir:mbox:vol:cz at: 6-Jan-2003 12:21


Hi Ed, you wrote:
> As was pointed out to me earlier, the use of Any-Type! seems to make a > parameter optional. Were I to define a parameter as such: Parameter [
<<quoted lines omitted: 3>>
> overloading, i.e. fall Foo with a String performs a different action > than Foo with Money or Foo without a parameter.
you can use this: f: func [parameter [string! money! unset!] [ ... ] to have an optional parameter. Regards -L

 [12/12] from: edanaii:cox at: 6-Jan-2003 8:00


Ladislav Mecir wrote:
>Hi Ed, >you wrote:
<<quoted lines omitted: 12>>
> ] >to have an optional parameter.
Ah hah! That's another thing I didn't know I could do. Never thought of Unset as a datatype. At this rate, I should get this language figured out in about 50 years. :) -- Sincerely, | Control is an illusion, you infantile egomaniac! Ed Dana | Nobody knows what's gonna happen next: not on a Software Developer | freeway, not in an airplane, not inside our own 1Ghz Athlon Amiga | bodies and certainly not on a racetrack with 40 | other infantile egomaniacs! | -- Nicole Kidman, Days of Thunder

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted