"Remo D." <rdentatowrote in message
news:4722ec84$0$10625$4fafbaef@reader2.news.tin.it ...
Quote:
cr88192 ha scritto:
Quote:
>>
>if one thinks about it, they will realize that they have these void
>pointers, and these dynamic vectors.
>>
>"maybe it will be useful to nest these dynamic vectors?"
>"maybe it will be useful to have other useful container types?"
>"maybe it will be useful to conviniently represent values, such as floats
>or integers?"
>... then, one can end up with a typeless container system.
>
Funny you mentioned it! In fact I right after started thinking about a
"generic type" like:
>
typedef struct {
union {
struct vecVal *vector
void *pointer; /* a generic pointer */
int32_t num_i32; /* 32 bit integer */
float num_flt; /* a float */
... /* other values one may be interested */
} val;
uint16_t type;
} vecVal;
>
The "ugliness" of this would be the many conversion functions that will be
needed to properly handle those values in C ...
>
Anyone can think of a better method to express the concept of "generic
typed value" in C?
>
well, I had usually approached it though the use of "opaqueness".
basically, we have a value, in some opaque form, and use a system of wrap,
unwrap, and check functions.
in my most recent system, this looks like this:
dyt dyint(int v); //wrap integer
int dyintv(dyt p); //unwrap integer
int dyintp(dyt p); //type is an integer?...
where 'dyt' was basically a wrapper for an anonymous void pointer.
one ends up with a potentially large number of utility functions (a natural
cost of this approach), although, if one makes use of the dynamic-type
properties, one can cut down the costs substantially vs what they could
be...
of course, 'type' was built in as a part of the allocator, not as part of
the object as in the example above, so, one could do something like:
byte *a;
a=gctalloc("_bytearray_t", 1024);
where 'a' looks just like it came from something like malloc.
and, later be like:
if(gctypep(a, "_bytearray_t")) //check is a is a byte array
... //something specific to byte arrays
Quote:
Quote:
>one can arrive at a dynamic type system (and, of all things, see why this
>kind of thing is useful, even in the core of C-land...).
>
I guess one will have to find a point of balance between features and
usability.
>
yes.
and some options are better than others.
IMO, it is difficult to find the best possible balance (even as recently
demonstated), where I have ping-ponged to some extent between 'dynamically
typed void pointers' and 'tagged references' (where the value is essentially
an integer, using some of the bits for the type, and the rest for either
referring to objects, or for holding the value itself).
usually, the tradeoff is speed vs usability:
typed void pointers are easier to use, but not as fast nor as capable;
tagged references are more difficult, but are usually somewhat faster and
more capable.
a simple example:
pointers usually require some method of extracting and comparing the type;
with tagged references, it is often a mask and equality comparrison (and is
thus usually handled by a macro):
#define INTP(x) (((x)&3)==1)
likewise, if we are fairly sure of the type, we can usually extract it with
a shift:
#define INTVF(x) (((int)(x))>>2)
or, perform arithmetic directly on the tagged values...
but, this ability comes at high cost, as working with them, in some cases,
can become very painful...
one can end up forced inflexibly into a very rigid type system (both good
and bad in some ways), wheras typed pointers allow one to more informally
build a system that may involve structs or other ad-hoc constructions...
as a result, I have more often ended up using tagged references for
interpreters, and void pointers for general coding (and, in the cases I have
mixed them up, the results are not good, such as horribly painful and
non-reusable code in one case, and a horribly slow and garbage spewing
interpreter in the other...).
Quote:
Quote:
>of course, it is not a far reach to realize after having something like
>this, a garbage collector would also be very useful...
>
That's something I would like to have :). But then, I fear, it would not
be C any longer. It might be D or some other language...
I once had a look at the Boehm-Demers-Weiser GC but I felt rather
uncomforable with it. Not for the concept of GC, which I really like in
other languages, but for the ineherent machine/compiler/OS dependency it
has.
So, my preference would be for easing memory management but not up to the
point of a full GC.
>
well, one gets what they are willing to pay for...
portability is a cost, among others...
even within the realm of GC, there is a lot of room for costs and
tradeoffs...
Quote:
Quote:
>so, you may have stumbled on the first step, or maybe one can go a
>different direction?...
Surely I might! What I would value most is a discussion on alternative
directions!
>
yes.