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

[REBOL] More dialects than you think, validating function input.

From: brett:codeconscious at: 12-Sep-2002 22:05

I have a function that takes a block! as an argument. This block! should contain only numbers. The question is how do I check for valid input and throw an error on encountering a problem in an efficient manner? My first thought was something like this: f1: function [ [catch] block [block!] ] [kount] [ kount: 0 repeat value block [ if not number? value [ throw make error! "F1 can only process numbers." ] kount: kount + 1 ] ] After reflecting on this, I thought about how a block! passed to a function is one sense is being interpreted by the function according to an implied grammar. That is my requirement in the above function for only numbers, in a sense, implies that my function is processing a fairly simple REBOL based grammar (ie dialect). I don't think it is too outlandish to say every function that processes a block! is implementing grammar processing even if trivial. Hence, the subject title of this message. As a side note, I reckon every offline script can be considered as an out of memory block! ready for loading. Anyway, this thought leads me to PARSE, REBOL's grammar validator. So I recoded my function to look something like this: f2: function [ [catch] block [block!] ] [kount value] [ kount: 0 if not parse block [ any [set value number! (kount: kount + 1)] | set value any! to end ] [throw make error! "F2 can only process numbers."] ] Then I did some quick and dirty testing to see which was faster. On my machine, F2 takes half the time that F1 does. Just thought I'd share my little ramble. Test code below. Cheers, Brett. REBOL [] data: copy [] repeat i 2000 [insert tail data i] f1: function [ [catch] block [block!] ] [kount] [ kount: 0 repeat value block [ if not number? value [ throw make error! "F1 can only process numbers." ] kount: kount + 1 ] ] f2: function [ [catch] block [block!] ] [kount value] [ kount: 0 if not parse block [ any [set value number! (kount: kount + 1)] | set value any! to end ] [throw make error! "F2 can only process numbers."] ] timeit: func [f] [ t1: now/precise repeat i 300 [error? try [f data]] t2: now/precise t2/time - t1/time ] print ["f1" timeit :f1] print ["f2" timeit :f2] insert at data 1001 'a-word print ["f1 - error half way" timeit :f1] print ["f2 - error half way" timeit :f2] --- Website: http://www.codeconscious.com Rebsite: http://www.codeconscious.com/index.r