[DGD] typeof bug?

elemel at bredband.net elemel at bredband.net
Thu Mar 31 09:05:01 CEST 2005


Robert Forshaw wrote:

> If past experience has told me anything, it's that requesting a small 
> feature in a future version of DGD doesn't work; rather I get told that the 
> feature is useless and I don't really want it. I'd like to be proven wrong 
> for once.

In DGD, typeof is a plain function (although a kfun) that gives you the
dynamic type of a value, and not, as Pär Winzell pointed out, a language
device that gives you the static type of a variable. Note the
distinction between variable and value.

When you invoke typeof with a typed variable containing the nil value,
nil is copied from your typed variable into the untyped (mixed)
parameter of typeof. This effectively discards the type information of
the variable. So all typeof can do is inspect the value you pass it. And
the nil value has no type.

> Here's the macro in question that gave rise to my discovery that typeof 
> doesn't do what I thought it did:
> 
> #define EMPTY(X) { if(typeof(X) == T_STRING) X = ""; else if(typeof(X) == 
> T_ARRAY) X = ({ }); else X = nil; }
> 
> 
> In literature, one tries to express as much as possible with as few words as 
> possible. By the same reasoning, I want to achieve as much function as 
> possible with as little code as possible (with as much lucidity as 
> possible), and this is my means of doing that. That is why I would find such 
> a feature useful. Here's just a few of the other definitions and macros I 
> like to use:

Concerning literature, I strongly disagree with your view. Being brief
and to the point is a merit. But this should not be taken too far,
because then the text will be terse and difficult to absorb. The same
holds true for programming languages. But perhaps you and I mean the
same thing?
 
> #define EMPTY_ARRAY ({ })
> 
> #define EMPTY_STRING ""
> 
> #define SWAP(X, Y) { mixed val; val = (X); X = (Y); Y = val; }
> 
> #define ARR_INCREASE_SIZE(X, INC) { X += allocate(INC); }
> 
> #define GET_BIT(C, B) (((C) << (31 - (B))) >> 31)
> 
> #define ARR_REDUCE_BY(X, A) if(A < sizeof((X))) X = X[..sizeof(X) -\
> (A + 1)]; else X = EMPTY_ARRAY;
> 
> #define UNTIL(X) while(!(X))
> 
> #define ARR_SET_MAX(X, MAX) { if(MAX < sizeof(X)) {\
> if(MAX > 0) { X = X[..MAX - 1]; } else { X = EMPTY_ARRAY; } }\
> else { X += allocate(MAX - sizeof(X)); } }
> 
> #define REMOVE_ELEMENT(A, E) A = A[..E - 1] + A[E + 1..];
> 
> #define MAX(V, M) ((V) > (M) ? (M) : (V))
> #define MIN(V, M) ((V) < (M) ? (M) : (V))
> 
> #define APPEND(A, X) A += ({ X });
> 
> #define LOOPVARS() int i, sz;
> 
> #define ITOC(I) (((string)(I))[0])
> 
> #define IS_EMPTY(V) (!(V) || (V) == EMPTY_STRING)
> 
> ...and so on.
> 
> As an aside, I'm coding a pseudo-language which is parsed into LPC. 
> Preprocessor definitions come in very handy when trying to keep my code 
> short and to the point.

Macros are kludgy and should generally be avoided. I won't argue why, as
there are many good explanations on the Web and elsewhere. Most of the
macros above are better implemented as functions.

As an aside, the built-in DGD types are pretty low level. You can use
LWO's for a higher level of abstraction.

As another aside, if your language is parsed into LPC, compiled, and
executed, it is by definition not a pseudo-language but a real one.

Regards,
Mikael




More information about the DGD mailing list