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

2002-09-12 Thread Brett Handley

Tiny correction to my code so as not to confuse. It does not change the
result or conclusion.

set value any! to end

should read

set value any-type! to end

Brett.

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




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

2002-09-12 Thread Ladislav Mecir

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.




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

2002-09-12 Thread Brett Handley

Hi Ladislav,

I was less than clear. The kount stuff was to simulate other processing.
The value needs to be set for processing and to report the type in the error
message. My mistake for over simplifying the examples, and for stuffing them
up. Here is the actual function I was working on:

bayes: function [
{Calculate combined probability.}
[catch] probabilities [any-block!]
] [p0 p1 d] [
p0: p1: 1.0
if not parse probabilities [
any [
set value number! (p0: value * p0 p1: 1 - value * p1) |
set value any-type! to end skip
]
] [throw make error! reduce ['script 'cannot-use 'bayes mold type?
get/any 'value]]
if zero? d: add p0 p1 [throw make error! The probabilities cannot
be combined.]
divide p0 d
]

Sorry for the confusion.
Brett.


 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


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




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

2002-09-12 Thread Gabriele Santilli

Hi Brett,

On Thursday, September 12, 2002, 2:05:39 PM, you wrote:

BH if not parse block [
BH any [set value number! (kount: kount + 1)] |
BH set value any! to end
BH ] [throw make error! F2 can only process numbers.]

The  second  part  of the rule will never be reached. ANY does not
fail if it matches 0 elements.

In your trivial example, your code could look like:

   if not parse block [any number!] [ ...

provided you are accepting empty blocks as input too. Of course, I
imagine  your example was actually cut down form something bigger,
that needed the SET VALUE ... and the count (which you could maybe
do faster by just using LENGTH?...).

Regards,
   Gabriele.
-- 
Gabriele Santilli [EMAIL PROTECTED]  --  REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

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




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

2002-09-12 Thread Gregg Irwin

Brett, et al

A very good post, and related to the discussion on error handling to boot!
:)

I can see at least two major ways to apply this approach.

1) Parse drives the processing of the function, automatically validating the
correctness of the argument block as it goes.

2) Parse is used only to validate the block at the entry point, like a
precondition in a Design by Contract design, and the operation of the
function is separate. You could also use parse to validate return values
(i.e. as a post-condition processor).

In a large system, and as more things are driven by dialects, this could
prove very useful indeed. Now, does anyone have a model they use to return
helpful context information when a parse operation fails? Programmers are OK
with Syntax error: expected integer! but users are probably better served
by I understood the first part (sell 400 shares of MSFT at), but then I
was expecting to see a monetary value for the sell price (e.g. $50.00), and
I didn't, so I couldn't process your request. I'm sorry for any
inconvenience this might cause you. Have a nice day. Or maybe just No sell
price was specified in your request. or even a prompt for the missing info.

In any case, I agree that this is a good tool to keep in mind.

--Gregg


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




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

2002-09-12 Thread Ladislav Mecir

Thanks.

-L 

- Original Message - 
From: Brett Handley
...
Here is the actual function I was working on:

bayes: function [
{Calculate combined probability.}
[catch] probabilities [any-block!]
] [p0 p1 d] [
p0: p1: 1.0
if not parse probabilities [
any [
set value number! (p0: value * p0 p1: 1 - value * p1) |
set value any-type! to end skip
]
] [throw make error! reduce ['script 'cannot-use 'bayes mold type?
get/any 'value]]
if zero? d: add p0 p1 [throw make error! The probabilities cannot
be combined.]
divide p0 d
]

Sorry for the confusion.
Brett.


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