Live data from Hacker News

Algebraic Data Types for C99

github.com

111–120 of 233 posts

Re: Algebraic Data Types for C99

#111
post #68

Let's say you have a C program to write, and you really want exhaustive pattern matching on the tags of unions (which is what Datatype99 provides: "Put simply, Datatype99 is just a syntax sugar over tagged unions"). Let's say further that you already know Rust exists, and aren't going to use it for reasons that anyone writing a C program already knows. At least consider Zig. Here's a little something I wrote in Zig t…

Seems like Nim can be useful too, plus it compiles to C. https://gist.github.com/unclechu/eb37cc81e80afbbb5e74990b62e...

In Nim, ADTs are painful still (as your example clearly shows), but they are working on adding proper ADTs to the language (I can't find where I read that, but I am sure I did!).

Re: Algebraic Data Types for C99

#112

Earlier quoted context omitted.

C has always had them, it's called union. In practice you need to couple it with an enum, and your visitation mechanism is a switch statement. But C doesn't impose that on you and lets you do it as you see fit.

lol this is like saying C doesn't need structs, you can just declare the variables with a common prefix separately! See ma, product types!

Yep, or C doesn't need arrays just use pointers! And C doesn't need strings, just use a pointer to the first byte and assume it's ASCII!

Re: Algebraic Data Types for C99

#113
post #39

Earlier quoted context omitted.

Everyone who hasn't used ADTs and pattern matching doesn't get what the big deal is all about. Everyone who is used to ADTs and pattern matching doesn't get what the big deal is all about, until they have to work in a language that doesn't have them. And everyone who just found out about them can't shut up about them being the best thing since sliced bread. :)

I have mainly used them in Rust. They are nice I suppose, but nothing mindblowing. To me it feels very similar to an interface (trait) implemented by a bunch of classes (structs). I have multiple times wondered which of those two approaches would be better in a given situation, often wanting some aspects of both. Being able to exhaustively pattern match is nice. But being able to define my classes in different places…

> To me it feels very similar to an interface (trait) implemented by a bunch of classes (structs)

Then you might not fully grok sum types yet.

> From my perspective a discriminant vs a vtable pointer is a boring implementation detail the compiler should just figure out for me based on what would be more optimal in a given situation.

Disagree. It's a design choice that should be decided by the programmers. There's a tradeoff—choosing which should be easier: adding a new variant or adding a new function/method. It's called the Expression Problem: https://wiki.c2.com/?ExpressionProblem

Re: Algebraic Data Types for C99

#114

Earlier quoted context omitted.

Typing features affect the way we design APIs. Libraries written in languages with type classes and without them can have completely different designs. If nested pattern matching is not available, this will not affect the APIs, only the function bodies -- because desugaring is local by definition.

That doesn't matter in practice. If two programming languages have the same underlying feature but one has syntactic sugar to make it very easy to use and the other does not (so is quite cumbersome to use) then you'll find that the library ecosystem for the former language will see the feature in widespread use whereas the ecosystem of the latter will tend to shun the feature. This is one of the social factors of pro…

Yes, features that are easy to use will be more often used, while inconvenient features will be less used. I don't quite see any controversy with my comment.

Re: Algebraic Data Types for C99

#115
Anyone considering using this should be strongly looking at using Swift or Rust instead. You can build almost any given language idea using the C macro preprocessor, but that doesn't mean it's a good idea to ship production code using it.

The worst codebases to inherit as a maintenance programmer are the ones where people got clever with the C preprocessor. Impossible to debug and impossible to maintain.

Re: Algebraic Data Types for C99

#116

One of the crimes of modern imperative programming languages is not having ADTs (except maybe Rust) built-in. It is such a basic mental model of how humans think and solve problems. But instead we got inheritance and enums which are practically very primitive.

> except maybe Rust

Swift, Kotlin and Scala all have had ADTs for a while, even Java has it now.

Re: Algebraic Data Types for C99

#117
post #99

Earlier quoted context omitted.

Of course the syntax sugar is a good thing if it makes it easier to write the code, but if the question is about "expressive power of the type system", it's not really relevant: Zig's type system can properly express a sum type. In addition: pattern matching is orthogonal to ADT, you can have pattern matching in both languages with and without algebraic types. Neither one implies the other.

> Zig's type system can properly express a sum type. Surely any Turing complete PL can express a sum type? I can't imagine a language that can support products but not sums.

Turing completeness has nothing to do with static type checking. Dynamically typed PLs can't express any type (except Any) yet are still Turing complete.

Re: Algebraic Data Types for C99

#119
post #71
post #54

Earlier quoted context omitted.

Some have even older Java versions in 'prod'. 6 is still alive in some places out there, because management refuses to pay for either upgrade, replacement or dismantling. I have a mid-sized application I built on 17 that's used to deliver a particular project, really looking forward to finish the project so I get to move to 21 and refactor it with these new features and make it more general.

Oof, I didn't know that anyone still used Java 6 anywhere. I have to think that it's a potential security nightmare at this point isn't it?

It is. We run an old version of our application on Java 6. Apparently multiple people have tried to upgrade it in the past but it proved too difficult because it's using a bunch of completely obsolete technology with little available documentation that seems to randomly break when you upgrade even minor things.

The plan has been to gradually replace it with the new version of the software (which runs on Java 17), unfortunately this plan has been ongoing for 10 years and it's not gonna be done anytime soon.

Such are the sad realities of working on legacy code sometimes.

Re: Algebraic Data Types for C99

#120

Earlier quoted context omitted.

Java's sealed classes are still somewhat more limited than Rust's or Haskell's sum types, in that each instance of the superclass holds a fixed variant (i.e., subclass), so you can't change the variant without creating a new instance. Clearly, this limitation is necessary for references to stay intact, but I've personally ran into this issue when trying to represent a sum type in an ORM.

> so you can't change the variant without creating a new instance. Isn't that true of ADTs in all languages? I can't think of a single language with ADTs that lets you change the tag/variant of an existing value.

In Rust [0]:

  #[derive(Debug)]
  pub enum Example {
      Foo(i32),
      Bar(&'static str),
  }

  let mut ex: Example = Example::Foo(42);
  println!("{ex:?}"); // Foo(42)

  let ex_ref: &mut Example = &mut ex;
  *ex_ref = Example::Bar("hello");

  println!("{ex:?}"); // Bar("hello")
Given a mutable reference to a value of enum type, you can replace it with another variant. Or you can swap it out with any other value of the same type, even if the variants are different. This is most commonly used for Option, where you can insert or remove the contained value as long as you have a reference.

The limitation here is that for as long as the mutable reference is live, no other code can access the value. So when you do change the variant, you can't have any other references sitting around that point to the removed subfields.

[0] https://play.rust-lang.org/?version=stable&mode=debug&editio...

Post reply on HN