Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

my best guess is that you can't do recursive enums without explicit boxing [edit: or other forms of indirection, like &T]¹. so you can't do this:

  enum List<T> {
    Nil,
    Cons(T, List<T>)
  }
instead, you have to box/reference-ify the recursive occurrence:

  enum List<T> {
    Nil,
    Cons(T, Box<List<T>>)
  }
so in certain circumstances it doesn't let you "coproduct" two types together, you might need to modify one a bit, which makes it a technically-not-exactly-a-coproduct (i think). a bit of a stretch but it sort of makes sense next to a by-reference-only ML langs where you can (co)product anything as you please

(btw, it's the same for recursive products)

---

1 - https://users.rust-lang.org/t/recursive-enum-types/2938/2



You don't have to box, but you do need some sort of type to make things sized. This is usually a pointer of some kind, but any kind of pointer works. Take references, for example:

  enum List<'a, T> {
    Nil,
    Cons(T, &'a List<'a, T>)
  }
  
  fn main() {
      let list = List::Cons("hello", &List::Nil);
  }
Box is usually chosen because it's a good default choice.


you're right of course! i should've used a more generic term like "indirection" or "reference", didn't mean to put emphasis on Box


It’s all good, most people say just Box, because it is the majority case.


I think that's because Rust types are Sized, but I could be wrong. The first example has size = Infinity, while the second has a constant size.


Thanks for commenting, that's probably it. I was aware of the requirement for explicit box-ing but it didn't immediately come to mind.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: