Live data from Hacker News

I write type-safe generic data structures in C

danielchasehooper.com

151–160 of 196 posts

Re: I write type-safe generic data structures in C

#152
post #133

Earlier 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.

> 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 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

#153

I 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.

Re: I write type-safe generic data structures in C

#154
post #147

Earlier 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.

Exactly, thank you.

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

#155

Earlier 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.

In general, there is no “actual” head and tail - you could have multiple references to different parts of the list, and each of them would have a different head. If you’re recursing through a list, at some point every node will be used as the head. This is a common pattern in recursive data structures, particularly in functional languages.

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

#156

I 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.

Yah, I tend to think of type witnesses as actually existing at runtime and phantom types not, but in the union trick, they don't really exist either. So thinking on it some more, seems more of a way of expressing type parameters in the first place, and well, that's what the article was about.

Now I'm wondering what phantom types would look like in C...

8-/

Re: I write type-safe generic data structures in C

#157
post #24
post #20

Earlier 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.

I don't think compilers typically allow that: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14319

Re: I write type-safe generic data structures in C

#158

Earlier 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…

Well, I certainly would not interpret the terms that way, but you do you.

Re: I write type-safe generic data structures in C

#159
post #99

Dude the ship has sailed.

Not sure what you mean by that, but if you're trying to imply that C is not relevant: https://www.tiobe.com/tiobe-index/ Plus an article about C was at the top of hacker news all day today.

Not C per se, but trying to make C type safe.

Re: I write type-safe generic data structures in C

#160
post #110

Earlier 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.

You can definitely make an incomprehensible soup out of C++ templates. C++ expression templates are a classic example. But the threshold of this is much higher than with a macro language.

Using C++ templates for a linked list type doesn't make a mess.

Post reply on HN