I write type-safe generic data structures in C
151–160 of 196 posts
Re: I write type-safe generic data structures in C
#152Earlier quoted context omitted.
Do you find the difference between abstract and concrete confusing? Or the difference between container and contents? Is that a pointless distinction with no upside?
I do agree these are useful concepts to distinguish, but I don't get the connection to the topic at-hand. To me, there is just the function signature. I don't see a benefit to referring to passed values as distinct from received values. To my ear "argument" and "parameter" are perfect synonyms.
That’s not the distinction being made by those terms.
“Parameter” refers to a named variable in a function definition.
“Argument” refers to an actual value that’s passed to a function when it’s called.
It’s exactly the same as the distinction between variables and values (which you probably see the use for), just applied to the special cases of function signatures and function calls.
(As an aside, in the lambda calculus this relationship becomes a perfect equivalence: all variables are parameters and all values are arguments.)
Re: I write type-safe generic data structures in C
#153I believe "type witness" is the generic (hah) term for "member that doesn't do anything but hold the type". Lot less literature out there about type witnesses than I had thought though...
I've mostly seen in done in Haskell, but have used it in it Scala as well to simulate type hierarchies not present in the actual type system.
In a way, this union trick is kind of like a phantom type, since the secondary type is never actually used.
Re: I write type-safe generic data structures in C
#154Earlier quoted context omitted.
> Beware that only tagged unions are considered the same type I don't get it. Tagged union is just a design pattern.
By tagged they mean have an identifier. Compare > struct { ... } foo; and > struct bar { ... } foo; The latter has an identifier, bar; the former doesn't. The standard uses tag to refer to the identifier name, if any, in an enum, struct, or union declaration.
I've always called "tag" the id that optionally follows struct/union/enum. Is it the wrong word? Some specs call it "name", but "unnamed union" sounds dangerously similar to "anonymous union", which is a different concept, namely (no pun!) an unnamed member of an outer struct or union whose submembers can be accessed as if they belong in the outer one. E.g.
struct {
struct {
int m;
}; // no name: anonymous
struct s;
s.m = 1;Re: I write type-safe generic data structures in C
#155Earlier quoted context omitted.
The naming of LIST_HEAD_INIT and INIT_LIST_HEAD is confusing to me.
Not to mention that they insist on calling every entry of the list a "list head", which makes no sense (hysterical raisins, maybe?). The structure is made of a uniform loop of entries, one of which is used as the actual head & tail, or entry point into the structure.
Disclaimer: I haven’t looked at this author’s code, just pointing out that list nodes that consist of (head, tail) are a common pattern with a clear rationale.
Re: I write type-safe generic data structures in C
#156I believe "type witness" is the generic (hah) term for "member that doesn't do anything but hold the type". Lot less literature out there about type witnesses than I had thought though...
There's a similar term "phantom type", for when you have some sort of type variable that is never used as the type of an actual variable. I've mostly seen in done in Haskell, but have used it in it Scala as well to simulate type hierarchies not present in the actual type system. In a way, this union trick is kind of like a phantom type, since the secondary type is never actually used.
Now I'm wondering what phantom types would look like in C...
8-/
Re: I write type-safe generic data structures in C
#157Earlier quoted context omitted.
I would love for `union`s to be federated, that is, a type could declare itself as thought it was part of a union with another type, without having to pre-declare all possible types in one place.
For layout-compatible types, you can often just include a `_base` member in each child. Maybe twice (once named and once unnamed) to avoid excess typing - I don't understand the common-initial-subsequence rule but people do this enough that compilers have to allow it.
Re: I write type-safe generic data structures in C
#158Earlier quoted context omitted.
I do agree these are useful concepts to distinguish, but I don't get the connection to the topic at-hand. To me, there is just the function signature. I don't see a benefit to referring to passed values as distinct from received values. To my ear "argument" and "parameter" are perfect synonyms.
> referring to passed values as distinct from received values. That’s not the distinction being made by those terms. “Parameter” refers to a named variable in a function definition. “Argument” refers to an actual value that’s passed to a function when it’s called. It’s exactly the same as the distinction between variables and values (which you probably see the use for), just applied to the special cases of function s…
Re: I write type-safe generic data structures in C
#159Re: I write type-safe generic data structures in C
#160Earlier quoted context omitted.
If I may may be provocative :-) this post isn't about C. It's about layering on a custom language using C preprocessor macros. My compilers were originally written in C. I started using the C preprocessor to do metaprogramming. After some years I got fed up with it and removed nearly all of the preprocessor use, and never looked back. My code was much easier to understand. An amusing story: long ago, a friend of mine…
I could tell a similar story (many, in fact) about C++'s templates. It is not entirely clear to me what exactly makes the preprocessor a bad choice. One could argue that it is too flexible, so it is possible to create a mess with it. But somehow this seems a rather weak argument for inventing another monomorphization layer, which often evolve into their own mess.
Using C++ templates for a linked list type doesn't make a mess.