Whattype

alec's picture

Recently, working on Nested Verification, I took a look at the whattype procedure.

First, I couldn't find any use of local variables t1, t2, L, k1, k2 declared in it. That seems odd.

Second, the order of types in it seems to be not exactly right. In particular, symbol is located earlier than `module`. Also, some types are missing, record for example. That leads to not recognizing modules and records,

r := Record( 'a', 'b' ):
m := module() end:
whattype(r);
                                symbol
whattype(m);
                                symbol

Similarly to the compact and efficient version of Nested Verification, I wrote a "compact and efficient" version of whattype,

wtype:=proc(a) 
local t;
if nargs <> 1 then return 'exprseq' fi;
for t in ['`+`','`*`','`||`','string','indexed','integer',
'fraction','`^`','function','series','SDMPolynom','float',
'extended_numeric','complex'('extended_numeric'),'hfarray',
'assignment','Vector[row]','Vector[column]','Matrix','Array',
'array','table','set','list','`=`','`..`','`<>`','`<`','`<=`',
'`and`','`or`','`xor`','`implies`','`not`','procedure','`::`',
'uneval','record','`module`','moduledefinition','zppoly',
'symbol','unknown']
do if a::t then break fi od;
t end:

I used the same order of types as in whattype except moving symbol to the end and adding record in front of module. That made records and modules recognizable,

wtype(r);
                                record
wtype(m);
                                module

A lot of types are still missing, but they can be easily added if necessary.

Comments

whattype Considered Harmful

I entirely understand the desire to improve whattype, and it can be useful tool for people beginning to learn about Maple's type system.

But is is dangerous. Few people coming to Maple have seen a programming language with subtyping before, and so they are used to thinking of objects as having a single type.

'whattype' is just useful enough to lull them into complacency here, and I've seen a lot of user code using it which is buggy or just inefficient (because it does a whole lot of useless type checks). Consider


p := proc(x) if whattype(x)='table' then true else false; end if; end proc:
q := proc(x) if type(x, 'table') then true else false; end if; end proc:

Now, p(table()) and q(table()) return true, as they ought to. But p(array([1,2])) is false, even though an array is also a table (as q(array([1,2])) reports).

On top of that, looking at the code for whattype, we had to do 20 type checks to get a result on the inputs above, whereas with 'type' we needed just one.

Type-checking should be done against a specific type with type(e, t), full stop.

alec's picture

Typechecking

Some people use hastype instead of type, too:)
See Testing objects for equivalence, for example.

By the way, I just recently did a time comparison (at the end of PointList constructor thread), and it has appeared that :: is faster than type. For example,

r := proc(x) if x::'table' then true else false fi end:

is faster than q - not that that matters :)

__________
Alec Mihailovs
http://mihailovs.com/Alec/

JacquesC's picture

Faster?

I really hate if-then-else that return booleans. So I really hope that
r := proc(x) evalb(x::table) end:
is faster!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}