ID:1188741
 
Often, I see a common convention of checking a variable's derived type, whether it be in libraries or in code snippets. The convention is fine, but there's also an alternative way a lot of developers don't know about, surprisingly. For example, it's commonly used in checking whether a variable is a list or not.

proc
is_list(l)
return istype(l, /list)

Now, there's nothing wrong with that. Nothing at all. However, that could be shortened(not much) to this version:

proc
is_list(l[0])
return istype(l)

I'm kind of surprised that a lot of developers don't know about this, as it is blatantly stated in the reference, with an accompanying example provided.


P.S. I'm just being picky :p
Have you actually tested that for speed to see if it's faster? Something tells me yours will wind up being slower because of the function's overhead.
In response to Ter13
Ter13 wrote:
Have you actually tested that for speed to see if it's faster? Something tells me yours will wind up being slower because of the function's overhead.

I haven't, no. I guess it's worth a check.

EDIT: I'd also imagine there wouldn't be any overhead. Boiled down, it's just a simple comparison check--checking whether the variable's type matches its derived type.
For the curious cats, there doesn't seem to be any significant performance gain between the two methods. This is the result of a test, with the following code and run-times:
proc
is_list_1(l)
return istype(l, /list)

is_list_2(l[0])
return istype(l)

mob
verb
case_1()
for(var/i = 1 to 1000)
is_list_1(list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
case_2()
for(var/i = 1 to 1000)
is_list_2(list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

The self CPU of case_2 is fairly high compared to case_1, be interesting to see it running 1000 calls.
For is_list_2, try this instead:
proc
is_list_2(l[])

I doubt it makes a difference if you provide one. What it probably does is create a list if one isn't provided, which probably isn't preferred anyway.
In response to Kaiochao
Kaiochao wrote:
For is_list_2, try this instead:
> proc
> is_list_2(l[])
>

I doubt it makes a difference if you provide one. What it probably does is create a list if one isn't provided, which probably isn't preferred anyway.

It wouldn't. All list initialization methods(i.e., list/l = new, l[0], l[], list/l) would probably be the same.
Also, try running them in reverse order. I remember seeing several benchmarks get messed up because of the garbage collecter.
In response to A.T.H.K
Well, Ter13 was interested(assumingly) in the two procs' performance, not the verbs. The verb is merely an encapsulation for the procedure.
In response to Ter13
I'll get into an in-depth benchmark testing some other time using atoms, string literals, and numbers(a lot more). I'm too busy to do it at the moment.
In response to A.T.H.K
A.T.H.K wrote:
The self CPU of case_2 is fairly high compared to case_1, be interesting to see it running 1000 calls.

It's probably because case2 was called after case1, so the lists being created took longer. I've seen it before with mass list creation without leaving references. Running them in reverse order would show case1 probably being the high one.
In response to Ter13
Strange

@Magnum2k obviously :)
To be honest, the main 'issue' (if you might call it such, more preference) with this is merely a case of readability. istype(var, type) simply happens to be more declarative, and so may be very easily and unambiguously sight-read than the implicit type form.

For trivial cases, makes no odds. When you're 2 loops deep in a 50 line procedure, it saves you the mental break of "what's the type *finds variable definition*". The positive counter-case being refactoring oriented, the implicit check requires no changes if you've refactored a type. May be good, if the check is general, may hide a needed point of change, if the check was more specific to the old type.

It's kind of very situation dependent, as to which you'd favour. Out of clarity and sight-reading though, I would go with the explicit form.