A question of function interface design
[1/8] from: pwawood:mango:my at: 19-Jan-2005 19:17
I have started to question whether it is best to use Rebol's automatic type checking of parameters or not when designing functions. If the type checking is used, calling a function with an incorrect type of value causes a script error, eg:
>> a: func [b [date!]] [print b] >> a 12345
** Script Error: a expected b argument of type: date ** Near: a 12345 However, if you don't use the built-in type checking, you can return a none! value and give the caller the option (and responsibility) to deal with the situation, eg:
>> a: func [b] [if type? b <> date! [return none]] >> a 12345
== none Given that Rebol is not strongly typed, is the second of these "idioms" the more appropriate? Regards Peter
[2/8] from: andreas:bolka:gmx at: 19-Jan-2005 12:26
Wednesday, January 19, 2005, 12:17:54 PM, PeterWAWood wrote:
> I have started to question whether it is best to use Rebol's > automatic type checking of parameters or not when designing
<<quoted lines omitted: 13>>> Given that Rebol is not strongly typed, is the second of these > "idioms" the more appropriate?
While the latter has obvious flaws when dealing with functions that may validly return 'none, I can see no advantages whatsoever. If the caller wants to deal with the situation, why not simply use 'try ? For example a: func [b [date!]] [print b] if error? try [ a 12345 ] [ print "uh oh!" ] -- Best regards, Andreas
[3/8] from: SunandaDH::aol::com at: 19-Jan-2005 6:44
> Given that Rebol is not strongly typed, is the second of these "idioms" the > more appropriate?
I find type checking is useful for typo checking -- like when I've missed an argument: afunc: func [a [string!] b [string!]] [return join a b] xx: afunc "abc" yy: 0 ** Script Error: afunc expected b argument of type: string Sunanda
[4/8] from: mokkel:gmx at: 19-Jan-2005 15:31
> Given that Rebol is not strongly typed, is the second of these "idioms"
I thought Rebol is strongly typed (but not statically) ... like a value has always an assigned type. About the rest: I prefer to have the interpreter checking the types of the arguments if that is wished. Actually I would like to have real support for Design by Contract (pre- and postconditions and maybe object-invariants), but I'm not sure whether that fits will with the Rebol philosophy - but however I find in principle nothing bad in having it. I know there is some old implementation of it at Rebol.org, but nobody seams to use it - maybe because of some other reasons ? I guess if you return 'none in case of error, that would somewhat destroy the purpose of a function (some precondition is always implied - if not explicitely stated), unless returning 'none would be raised to some standard, but then other problems occur (like Andreas Bolka stated in the other post). Maybe that's why I like the DBC approach, you just state what's else implicit in the function explicitely and the user/client of the function has to take care to fullfill the precondition and everything will work fine. Are there any comments regarding DBC being (un)useful for Rebol ? Michael
[5/8] from: premshree::pillai::gmail::com at: 19-Jan-2005 20:08
On Wed, 19 Jan 2005 15:31:25 +0100, Michael Berg <[mokkel--gmx--de]> wrote:
> > Given that Rebol is not strongly typed, is the second of these "idioms" > > I thought Rebol is strongly typed (but not statically) ... like a value > has always an assigned type.
Yes, REBOL _is_ strongly typed. Did anybody say otherwise? :-?
> About the rest: I prefer to have the interpreter checking the types of the > arguments if that is wished. Actually I would like to have real support
This is something debatable. Folks from the strong-dynamic typed kingdom would obviously not like the idea. However, there are clear benefits of having static type checking. The compromise to this solution would be to have _optional_ type checking. In fact, this is what's happening with Python. However, if there are type checkers (like pycheker for Python), it'd be nice. And I doubt there's one for REBOL as of now.
> for Design by Contract (pre- and postconditions and maybe > object-invariants), but I'm not sure whether that fits will with the Rebol
<<quoted lines omitted: 14>>> To unsubscribe from the list, just send an email to rebol-request > at rebol.com with unsubscribe as the subject.
-- Premshree Pillai http://www.livejournal.com/~premshree
[6/8] from: volker::nitsch::gmail::com at: 19-Jan-2005 16:33
On Wed, 19 Jan 2005 19:17:54 +0800, PeterWAWood <[pwawood--mango--net--my]> wrote:
> I have started to question whether it is best to use Rebol's automatic type > checking of parameters or not when designing functions.
<<quoted lines omitted: 12>>> Given that Rebol is not strongly typed, is the second of these "idioms" the > more appropriate?
No. 1) its longer. if it would be good, we would have a shortcut :) 2) this func [b [date!]] is the shortcut. 3) there are two types of fails: such which regulary happens(none!), and such which should never happen(error!). Thats why 'find returns none: often we want to know if something exists. 'read throws an error when file is missing: we rarely are prepared to deal with 'none instead of file-content. This keeps the code shorter, avoids continuing with broken data, and is simply smart: "hey coder, you forgot a file ;)". If the function-coder specifies a certain type, it means something. And passing something else is an coding-error. And the computer should be helpfull to do the right thing: decide if coder made error or did expect failing. In statically typing he does that conservative: if it could be wrong, it is wrong. in dynamically typing he flags only when he is really sure its wrong: at runtime with real data. but he checks. there is always 'attempt if you really may to call with wrong args: if attempt[to-integer ask "only numbers"][print "hohoho"] ;)
> Regards > Peter
<<quoted lines omitted: 5>>> To unsubscribe from the list, just send an email to rebol-request > at rebol.com with unsubscribe as the subject.
-- -Volker Any problem in computer science can be solved with another layer of indirection. But that usually will create another problem. David Wheeler
[7/8] from: greggirwin::mindspring::com at: 19-Jan-2005 11:21
Re: [functions] Re: A question of function interface design
Peter, Michael, et al PW> I have started to question whether it is best to use Rebol's PW> automatic type checking of parameters or not when designing PW> functions. I do different things in different contexts. With other languages, I never exercised the same variety of styles that I do with REBOL, maybe because they didn't allow it. With REBOL, I can tailor the style to the need very easily, even in the same script. This may lead to a view that the code is inconsistent, but it can also work to make it clear what kind of code you're writing. For example, a function with no help string, no type checking, and no comments is probably not meant for re-use. A function that has types defined for some parameters, but not all, jumps out at me as "mostly designed". If it were "fully designed", it would have any-type! listed for those params. With no type set for only certain params, it's like I'm saying "I'm not sure yet what I may want to allow here". Being able to specify types and have REBOL check them for us is a wonderful thing, but every script may not need that level of control for every function. Use it when appropriate. I often define local functions, and keeping them short and sweet really helps. I'm only going to be calling them from the next ten lines of code, so there is strong context to assist in using them correctly. MB> I thought Rebol is strongly typed (but not statically) ... like a value MB> has always an assigned type. Correct. Values have types, variables don't. MB> Are there any comments regarding DBC being (un)useful for Rebol ? I think it could be useful in certain applications. Again, REBOL is very flexible and there will be times when tools like DbC *will* be helpful; for most little REBOL scripts it would be overkill. I've tinkered a bit with Eiffel, and built my own DbC system for VB, which I used a lot and did help me to catch things sometimes. I think it can work well in an OO context, where you may be integrating a lot of little pieces you didn't write, and you're maybe not sure how they behave. In REBOL I find I write more general predicate functions, though I did play with Maarten's DbC stuff a bit. How would DbC work with something like PARSE though? It's really only applicable at the function level. Something else to consider is how it would work when you're dealing with code as data and such. One of the great things about REBOL is that we can try these things out (AOP is another hot topic) and see where they're applicable. e.g. you may have some critical parts of an app that would really benefit from DbC, so you could write a little dialect for just that purpose, or use Maarten's just for those pieces. With Eiffel, and I found with VB once I wrote my framework for it, you tend to use DbC very heavily, whether it's really necessary or not. -- Gregg
[8/8] from: carl::cybercraft::co::nz at: 23-Jan-2005 18:38
Re: A question of function interface design
On Wednesday, 19-January-2005 at 19:17:54 Peter wrote,
>I have started to question whether it is best to use Rebol's automatic type >checking of parameters or not when designing functions.
One reason not given so far for using it is that it makes it easy to see what types a function will accept. Compare READ and LOAD for instance...
>> ? read
USAGE: READ source /binary /string /direct /no-wait /lines /part size /with end-of-line /mode args /custom params /skip length DESCRIPTION: Reads from a file, url, or port-spec (block or object). READ is a native value. ARGUMENTS: source -- (Type: file url object block)
>> ? load
USAGE: LOAD source /header /next /library /markup /all DESCRIPTION: Loads a file, URL, or string. Binds words to global context. LOAD is a native value. ARGUMENTS: source -- (Type: file url string any-block binary) READ's description gets it right about what types are accepted, but LOAD's doesn't. Without them in the arguments, we'd have to view (and understand) the source to be sure what can and can't be accepted - and probably need to enclose the function in an error-trap anyway, just to be on the safe side. Long term, you'll probably find this will apply to your own functions as well. -- Carl Read.
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted