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
Peter:
> 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.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted