Hi Brett,

I don't know, why you didn't write it as follows:

    f3: func [
        [catch]
        block [block!]
    ] [
        if not parse block [any [number!] end] [
            throw make error! "F3 can only process numbers."
        ]
    ]

The parse rule contains END only for compatibility with my proposed PARSE
behaviour, otherwise it isn't necessary.

Cheers
-L

----- Original Message -----
From: "Brett Handley" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, September 12, 2002 2:05 PM
Subject: [REBOL] More dialects than you think, validating function input.


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

--
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the
subject, without the quotes.



-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to