I'm moving this to devel since it's probably a bit arcane for
And although I'll reply to the substance of Sven's post at
I'm basically going to take this from scratch.
So we're looking at the is*() functions for determining
whether a certain string is the name of a variable of a
certain type -- or with isnull(), whether the string is not
the name of any variable. And we're wondering if some of these
are redundant (such as the undocumented isscalar) -- and/or
whether we're in need of more such functions, or a single
function which does the same sort of thing with greater
Taking stock of the cases where functions of this sort may be
useful, I'd say there are basically two (with a marginal
1) Somebody has written a function with one or more parameters
that take a pointer-type argument, or a string argument, and
that have a default value of null. So the writer must test
whether the user has passed something or not. The isnull()
function will do the job fine. Functions like isstring and
isscalar can do the job too (inverted) but are redundant in
this context since the function-writer certainly knows the
type of the argument, if it's in fact supplied; he just has to
check for nullity.
2) As Sven pointed out, if a function accepts a bundle
argument -- in a context where the content of the bundle is
not guaranteed to conform to a known schema -- the writer may
need to determine (a) whether a given bundle contains an item
corresponding to a certain key, and also (b) the type of the
item, if present.
OK, so rather than proliferating is*() functions for all types
I suggested a more general typeof() function, which provoked
suggestions and counter-suggestions from Jack and Sven. I'm
now not so keen on that idea. If I'm right that the only
serious use case for such testing is in unpacking bundles [see
footnote], I think the job can be done quite efficiently via a
slightly modified inbundle() function -- and the
implementation is nice and easy.
That is, instead of inbundle just returning binary 1/0 for
presence or absence of the key, it returns an integer code for
the type of the item under the key (0 for none). Now Sven has
said he doesn't like magic numbers, and I sympathize; but a
little auxiliary function, typestr() -- which takes the code
from inbundle and returns a string -- can be provided for more
legible, perspicuous output.
I've put this in CVS but not documented it -- and I'm ready to
replace it if we come up with something that's clearly better
-- but here's how it looks right now:
b["str"] = "throgmorton"
eval inbundle(b, "str")
eval typestr(inbundle(b, "str"))
eval inbundle(b, "x")
eval typestr(inbundle(b, "x"))
? eval inbundle(b, "str")
? eval typestr(inbundle(b, "str"))
? eval inbundle(b, "x")
? eval typestr(inbundle(b, "x"))
That last is an empty string; it could be "none" or "null" if
we'd prefer. Right now the coding is 1 = scalar, 2 = series, 3
= matrix, 4 = string, 5 = bundle and 6 = matrixref (i.e.
[footnote: Jack identified a third case where testing of a
variable's type could be useful, namely in working around bugs
relating to the distinction between scalars and 1x1 matrices.
I see that point, but I don't see it as sufficient reason for
a fully general typeof() function if it's the only use case.
When I got to thinking about it, I realized that implementing
a general typeof() -- one that doesn't just accept a string
argument (a putative variable name) -- would actually be quite