Hacker News new | ask | show | jobs
by miki123211 2050 days ago
Zig's compile time execution lets you do similar things I believe.

In Zig, structs and modules are equivalent, and type declarations can be manipulated at compile time just like any other value. That, among other things[1], lets you write:

  fn LinkedList(comptime T: type) type {
      return struct {
          pub const Node = struct {
              prev: ?*Node,
              next: ?*Node,
              data: T,
          };
  
          first: ?*Node,
          last:  ?*Node,
          len:   usize,
      };
  }

I wonder if there's anything that OCaml functors can do but this can't.

[1] for example, you can implement a very efficient printf that gives an error at compile time when the format string is invalid. See https://ziglang.org/documentation/master/#comptime for more details.

3 comments

One thing is that OCaml modules are first class objects, so can be constructed at runtime and passed around as variables. But this Zig example, I think, will cover the most common case of functors for creating generics.

(I'm also not sure if Zig does compile-time check if the type T is compatible with LinkedList. OCaml does this type of check, making sure the signature of T fits the requirement of the functor LinkedList. The module T may have certain functions, for example a compare function associated with T to ensure sorting of the elements in your data structure.)

(Not even close to a zig expert, but I've been playing with it a little bit, find it very interesting, and think what I'm about to say is correct:)

The zig equivalent of a module, a struct, is also a first-class object in zig, so should be the same as OCaml there.

However, Zig does not have anything like a signature -- in that sense, it's "dynamically typed" at compile time (i.e., like type args to C++'s templates, however not nearly as bad because the errors you get are immediate and understandable -- think of it as more like "I fucked up the types and got a python-style error" than I "I fucked up the types and got a C++ templates error").

One limitation is privacy and abstraction. You can hide implementation details with most ML module systems - eg. hiding the underlying type of `Node`. You can also make local definitions in the module private. It's pretty challenging to get this stuff right - there's lots of research about it.

Also, as noted in other comments, Zig's type parameters are also dynamically typed. This leads to implementation details leaking out. This is not an issue in OCaml and other ML-style languages.