Most active commenters
  • kbr-(4)
  • deagle50(3)

←back to thread

Four Years of Jai (2024)

(smarimccarthy.is)
166 points xixixao | 17 comments | | HN request time: 0.785s | source | bottom
1. TinkersW ◴[] No.43726834[source]
I have my doubts with Jai, the fact that Blow & co seems to have major misunderstandings with regards to RAII doesn't lend much confidence.

Also a 19,000 line C++ program(this is tiny) does not take 45 minutes unless something is seriously broken, it should be a few seconds at most for full rebuild even with a decent amount of template usage. This makes me suspect this author doesn't have much C++ experience, as this should have been obvious to them.

I do like the build script being in the same language, CMake can just die.

The metaprogramming looks more confusing than C++, why is "sin"/"cos" a string?

Based on this article I'm not sure what Jai's strength is, I would have assumed metaprogramming and SIMD prior, but these are hardly discussed, and the bit on metaprogramming didn't make much sense to me.

replies(4): >>43727697 #>>43731025 #>>43733282 #>>43736239 #
2. VyseofArcadia ◴[] No.43727697[source]
> Also a 19,000 line C++ program(this is tiny) does not take 45 minutes unless something is seriously broken

Agreed, 45 minutes is insane. In my experience, and this does depend on a lot of variables, 1 million lines of C++ ends up taking about 20 minutes. If we assume this scales linearly (I don't think it does, but let's imagine), 19k lines should take about 20 seconds. Maybe a little more with overhead, or a little less because of less burden on the linker.

There's a lot of assumptions in that back-of-the-envelope math, but if they're in the right ballpark it does mean that Jai has an order of magnitude faster builds.

I'm sure the big win is having a legit module system instead of plaintext header #include

replies(2): >>43729817 #>>43734788 #
3. MyOutfitIsVague ◴[] No.43729817[source]
It depends heavily on features used, too. C++ without templates compiles nearly as quickly as C.
4. unclad5968 ◴[] No.43731025[source]
I seriously doubt that any of them have trouble understanding a concept as simple as RAII.
replies(1): >>43732144 #
5. kbr- ◴[] No.43732144[source]
Yeah it's weird but the author of this post claiming that defer can replace RAII kinda suggests that. RAII isn't just about releasing the resource you acquired in the current scope in the same scope. You can pass the resource across multiple boundaries with move semantics and only at the end when it's no longer needed the resources will be released.
replies(1): >>43734447 #
6. lylejantzi3rd ◴[] No.43733282[source]
There is no RAII in his language. Why would you care if he understands it or not?
replies(1): >>43734898 #
7. deagle50 ◴[] No.43734447{3}[source]
I don't get the point, what does this have to do with defer?
replies(1): >>43739724 #
8. Jyaif ◴[] No.43734788[source]
For 1 million lines of C++ to take 20 minutes you must be building using a single core.
9. rrgok ◴[] No.43734898[source]
What an odd take. It is like saying: there is no addition semantic in his language, why would you care if he understands it or not?
replies(1): >>43736670 #
10. torginus ◴[] No.43736239[source]
Honestly I concur. Out of interest in what sort of methods they came up with to manage memory, I checked out the language's wiki, and not sure if going back to 1970s C (with the defer statement on top) is an improvement. You have to write defer everywhere, and if your object outlives the scope of the function, even that is useless.

I'm sure having to remember to free resources manually has caused so much grief, that they decided to come up with RAII, so an object going out of scope (either on the stack, or its owning object getting destroyed) would clean up its resources.

Compared to a lot of low-level people, I don't hate garbage collection either, with a lot of implementations reducing to pointer bumping for allocation, which is an equivalent behavior to these super-fast temporary arenas, with the caveat that once you run out of memory, the GC cleans up and defragments your heap.

If for some reason, you manage to throw away the memory you allocated before the GC comes along, all that memory becomes junk at zero cost, with the mark-and-sweep algorithm not even having to look at it.

I'm not claiming either GC or RAII are faultless, but throwing up your hands in the air and going back to 1970s methods is not a good solution imo.

That being said, I happen to find a lot that's good about Jai as well, which I'm not going to go into detail about.

11. lylejantzi3rd ◴[] No.43736670{3}[source]
This take is equally bizarre. Most languages have an addition semantic. Most languages do not have RAII. That's, by and large, a C++ thing. Jai does NOT have RAII. So, again, why would anybody care what his opinion on RAII is?
12. kbr- ◴[] No.43739724{4}[source]
The author of the post claims that defer eliminates the need for RAII.

Well, goto also eliminates the "need" but language features are about making life easier, and life is much easier with RAII compared to having only defer.

replies(1): >>43740123 #
13. deagle50 ◴[] No.43740123{5}[source]
I got that, but the I don't see what the example of move semantics has to do with RAII or defer.
replies(1): >>43742813 #
14. kbr- ◴[] No.43742813{6}[source]
It makes things easier. Usually the move constructor (or move assignment operator) will cause the moved-from object to stop being responsible for releasing a resource, moving the responsibility to the moved-to object. Simplest example: move- construct unique-ptr X from unique-ptr Y. When X is destroyed it will free the memory, when Y is destroyed it will do nothing.

So you can allocate resource in one function, then move the object across function boundaries, module boundaries, into another object etc. and in the end the resource will be released exactly once when the final object is destroyed. No need to remember in each of these places along the path to release the resource explicitly if there's an error (through defer or otherwise).

replies(1): >>43746178 #
15. deagle50 ◴[] No.43746178{7}[source]
I agree that it makes some things easier (at the expense of managing constructors/destructors), I'm disputing the blanket assertion that it's superior to manual management, in the context of Jai (and Odin). You're also introducing a reference count, but that's besides the point.

In Jai/Odin, every scope has default global and temp allocators, there's nothing stopping you from transferring ownership and/or passing pointers down the callstack. Then you either free in the last scope where the pointer lives or you pick a natural lifetime near the top of the callstack, defer clear temp there, and forget about it.

replies(2): >>43748893 #>>43749888 #
16. jguegant ◴[] No.43748893{8}[source]
> You're also introducing a reference count, but that's besides the point.

How so? RAII absolutely doesn't imply reference counting.

17. kbr- ◴[] No.43749888{8}[source]
You may also want to pass a resource through something like a channel, promise/future pair or similar. So it's not just down/up the callstack, sometimes it's "sideways". In those cases RAII is a life savior. Otherwise you have to explicitly remember about covering all possibilities: - what if resource never enters the channel - what if it enters the channel but never gets retrieved on the other side - what if the channel gets closed - what if other side tries to retrieve but cancels

Or you leak the resource.