I’ve seen in the stdlib that algebraic types are sometimes emulated using a case union (e.g. Json::Any):
struct Any alias Type = Nil | Bool | Int64 | Float64 | String | Array(Any) | Hash(String, Any)
which is very similar to a sum type, with value semantics. This is fine, but there’s a twist: recursion is achieved through reference values (
Array), which makes the recursion valid since the union has a fixed size. However if there was to be a recursion with a single child, there is no obvious way to represent it (except for
Pointer(T) maybe, which is unsafe). So I wonder why there isn’t a kind of smart pointer like what follows:
struct Ref(T) @ptr : Pointer(T) def initialize(x : T) @ptr = Pointer.malloc(1, x) @ptr.value = x end forward_missing_to @ptr.value # behave like the object, hence "smart" end record Foo, id : Int32, parent : Ref(FooBar) # single child recursion record Bar, s : String alias FooBar = Foo | Bar p! Foo.new(id: 0, parent: Ref.new(Bar.new(s: "hello").as(FooBar)))
Am I missing something?