From Joe Finney to ~sircmpwn/hare-dev
> The option that I've taken in my hare::unit:: prototype is analogous to > allocating each json::value individually and only storing pointers in > the buckets. Then each bucket can be safely realloced as needed. There > are a number of downsides to this of course, but it seems the simplest > to me. Personally, I think this is the best way for most cases, and it's what I use for my own projects. The downsides are relatively minor: * You have to alloc and free once per item. * You use an extra pointer's worth of memory per item. * You have to do an extra pointer deref. * You lose a bit of cache locality.
From Joe Finney to ~sircmpwn/hare-rfc
You can always copy/paste the type and do a pointer cast, I guess. Do you have a particular syntax/semantics in mind, and are you okay with export opaque going in before this is implemented?
From Joe Finney to ~sircmpwn/hare-dev
IMO that's a broader problem with defer, not assert. You can replace the assert with fmt::fatal and it will have the same issue. Your point still stands though, the problem wouldn't happen with assert after your patch. I don't feel very strongly either way wrt this patch, so I'll check out and let others chime in. It's probably good to note that this is a breaking change in one of the commit messages.
From Joe Finney to ~sircmpwn/hare-dev
> I think that it has too many footguns and it isn't that useful. > rather make the change to simplify it. The footgun here was that stack-allocated strings don't work with assert/abort in tests. Are there any others, and would it be too expensive to fix the test runner to save the message before the stack is lost? > Out of nearly 4,000 asserts and aborts in the stdlib there were, what, > six of them which needed to be fixed following this change? To be fair, this feature was only recently-ish added. > The most important issue is that this is replacing a language feature
From Joe Finney to ~sircmpwn/hare-dev
> I agree that this is the main use-case, but I think you can easily just > add fmt::println/fmt::errorln liberally to your tests and it works even > better, now that the test harness captures the stdout/stderr of each > test case to display on failure in the test summary. That's fine, I suppose. At some point I would like a more powerful test harness (possibly a library, possibly improve the built-in one), but that's a discussion for later. > I didn't add this to the bytes/strings tests I updated in my > corresponding stdlib patch because it would have introduced a dependency > loop. This bothered me to no end while I wrote the strconv/ftos test. No good
From Joe Finney to ~sircmpwn/hare-dev
> - assert(equal(p, n), testcase); > - assert(equal(n, want), testcase); > + assert(equal(p, n)); > + assert(equal(n, want)); This is the only use of the testcase str. I think you can remove it from the fn args and make it a comment, so tokenize_test(&tokenize, "simple case", [1, 2, 0, 3, 4], [0], [ becomes // simple case tokenize_test(&tokenize, [1, 2, 0, 3, 4], [0], [
From Joe Finney to ~sircmpwn/hare-dev
This is a somewhat useful feature for table-based tests, where one assert statement accounts for many test cases. Without this, you don't know which test case triggered the assert. I think it's all good if we add assert fns to fmt:: fn assert(cond: bool, args: formattable...) void = { if (cond) { error(args); os::exit(255); }; }; and similar for an assertf. Only problem is the keyword name "assert".
From Joe Finney to ~sircmpwn/hare-rfc
I think it makes the most sense to allow for non-exported decls in the .td file. Such decls will not be directly usable by the module that imports them, but they can be used by opaque types within their own module. So, // foo/foo.ha type foo = int; export type bar = struct { x: foo }; // foo.td type foo::foo = int; export type foo::bar = struct { x: foo::foo }; While importing the .td file, foo::foo is usable by foo::bar, but
From Joe Finney to ~sircmpwn/hare-rfc
My initial proposal was to make the types properly opaque, meaning they could not be stack allocated, passed by value, etc. This would suffice for my use case, and is also super easy to implement: just literally put "type t = opaque" in the .td file and you're most of the way there. It seems the rough consensus is that we want to be able to stack allocate, which is fair, although the code will be more complicated. What do you expect would go into the .td file for type foo = int; export opaque type bar = struct { x: int, y: foo }; ? Would it be acceptable to "export opaque" all types within a module,
From Joe Finney to ~sircmpwn/hare-rfc
RFC SUMMARY Some libraries export functions that operate on opaque pointers. In C, this is convenient: in the header you declare the type without defining it, then you define and use it as normal in the source file. In Hare, this is not always convenient. You typically have two options: export the type (and all types it uses, which may be Lots), or export an opaque type and cast it to and from an internal type at your library boundaries. These options work, but neither is ideal for large libraries with many internal types. I propose allowing type declarations to specify that the type is opaque externally to the module, while remaining visible internally.