Most active commenters
  • eddythompson80(3)
  • juliangmp(3)
  • TuxSH(3)

←back to thread

228 points Retro_Dev | 39 comments | | HN request time: 1.65s | source | bottom
1. blippage ◴[] No.44462083[source]
I tried Zig some time ago to use with microcontrollers. It has a generator for the pins, which was nice. But subsequent versions broke as Zig changed syntax. So I started going down the rabbit-hole (it needed a newer version of llvm, for example) until I eventually decided that the game wasn't worth the candle.

The fact that another breaking change has been introduced confirms my suspicion that Zig is not ready for primetime.

My conclusion is to just use C. For low-level programming it's very hard to improve on C. There is not likely to be any killer feature that some other contender will allow you to write the same code in a fifth of the lines nor make the code any more understandable.

Yes, C may have its quirky behaviour that people gnash their teeth over. But ultimately, it's not that bad.

If you want to use a better C, use C++. C++ is perfectly fine for using with microcontrollers, for example. Now get back to work!

replies(10): >>44462098 #>>44462163 #>>44462194 #>>44462322 #>>44462409 #>>44462430 #>>44462780 #>>44463127 #>>44463517 #>>44464834 #
2. sgt ◴[] No.44462098[source]
But at some point it'll be ready. Might it be worth it then?
3. overflyer ◴[] No.44462163[source]
Dude Zig is clearly pre 1.0. It can introduce breaking changes with every commit and rightfully so. I mean d'oh it's Not ready for Prime Time.
replies(1): >>44462293 #
4. self_awareness ◴[] No.44462194[source]
The point of the language stability is spon on, but it's actually very easy to improve on C, not in terms of performance or readability, but rather safety and the ability to encode more constraints in a compact form than C would ever allow. Sometimes it's not about less lines, but the same amount of lines that encode a lot more stuff than these lines in C.
5. hencoappel ◴[] No.44462293[source]
Zig uses ZeroVer so don't expect it to ever hit 1.0.

https://0ver.org/

replies(2): >>44462331 #>>44462364 #
6. eddythompson80 ◴[] No.44462322[source]
> The fact that another breaking change has been introduced confirms my suspicion that Zig is not ready for primetime.

Huh, it was the 0.14 version number for me.

replies(2): >>44462350 #>>44463868 #
7. bigstrat2003 ◴[] No.44462331{3}[source]
Is that versioning site supposed to be some kind of joke? I can't really figure out if they are joking or serious - the tone comes off as joking, but it could be read as serious too.
replies(1): >>44462365 #
8. dtech ◴[] No.44462350[source]
0.x doesn't say as much as it used to 20 years ago, many fine projects keep it for way too long.
replies(1): >>44462473 #
9. ◴[] No.44462364{3}[source]
10. dtech ◴[] No.44462365{4}[source]
I guess you're being Poe's lawwed but it's definitely a joke
11. juliangmp ◴[] No.44462409[source]
Obligatory C is not a low level language: https://queue.acm.org/detail.cfm?id=3212479

I also have to disagree with C++ for micro controllers / bare metal programming. You don't get the standard library so you're missing out on most features that make C++ worthwhile over C. Sure you get namespaces, constexpr and templates but without any standard types you'll have to build a lot on your own just to start out with.

I recently switched to Rust for a bare metal project and while its not perfect I get a lot more "high level" features than with C or C++.

replies(4): >>44462438 #>>44462543 #>>44462692 #>>44464014 #
12. vlovich123 ◴[] No.44462430[source]
I haven’t done embedded stuff in Rust, but the nostd crates and automatically generated libraries from manufacturer SVDs seemed neat. The ability to trivially pull in already written functionality would also seem fantastic.
13. vlovich123 ◴[] No.44462438[source]
Doesn’t Rust nostd give up a comparable part that C++ would give up? It’s typically all the memory allocations that inhibit the use of data structures.
replies(2): >>44462647 #>>44462652 #
14. eddythompson80 ◴[] No.44462473{3}[source]
Zig has a pretty well documented 1.0 goals. It was the first thing I heard about zig from Andrew about. https://youtu.be/5eL_LcxwwHg
replies(1): >>44462756 #
15. TuxSH ◴[] No.44462543[source]
> You don't get the standard library

Why is that? Sure, allocating containers and other exception-throwing facilities are a no-go but the stdlib still contains a lot of useful and usable stuff like <type_traits>, <utility>, <source_location>, <bit>, <optional>, <coroutine> [1] and so on

[1] yes they allocate, but operator new can easily be overridden for the promise class and can get the coro function arguments forwarded to it. For example if coro function takes a "Foo &foo", you can have operator new return foo.m_Buffer (and -fno-exceptions gets rid of unwinding code gen)

replies(2): >>44462574 #>>44463081 #
16. juliangmp ◴[] No.44462574{3}[source]
That's the most frustrating part, a lot of the std library would work on a bare metal system (and would be rather useful), but getting those parts into your project and avoiding the ones that will give you compiler errors in form of esoteric poems is a nightmare.

Vendors at this point seem to give their implementation of some of the std library components, but the one's I've seen were lacking in terms of features.

replies(1): >>44462674 #
17. juliangmp ◴[] No.44462647{3}[source]
Yeah you don't get its std library, but Rust makes a distinction between core and std, and core is available. Doesn't sound like a lot but you get your standard types like Result and Option, you get slices since they're part of the language or if you need allocation you can define the global allocator in core::alloc.

This distinction makes it really comfortable to use.

Though one caveat about no_std is that you'll need some support library like https://docs.rs/cortex-m-rt/latest/cortex_m_rt/

18. ◴[] No.44462652{3}[source]
19. DanielHB ◴[] No.44462674{4}[source]
This is a problem with WASM as well, use a certain innocent function from the C++ std lib and suddenly your WASM binary grows by 10mb.
20. guappa ◴[] No.44462692[source]
Doesn't arduino use c++?
replies(1): >>44472202 #
21. arp242 ◴[] No.44462756{4}[source]
Yes, that was the point. To understand what that "0.14" means, we need to know those "well documented 1.0 goals" and some hour long YouTube video. That is, merely the "0.14 version number" without context is not enough, like your previous comment said.
replies(1): >>44462767 #
22. eddythompson80 ◴[] No.44462767{5}[source]
You look at the version, the milestones https://github.com/ziglang/zig/milestones, and it makes sense. The YouTube video is just more proof. Picking up a 0.14 software without looking the most basic thing about it like “oh, what kind of 0.14 is this” then complaining that “it’s not ready for prime time” is odd behavior
23. steeve ◴[] No.44462780[source]
It absolutely is and we (ZML) are using it with great success. That said, Andrew said he would absolutely would break compat if it meant things go in the right direction. Yes, it can be painful sometimes, yes I do not always agree with his choices, but it has never been a blocker nor a significant time sink.

And in the end, things do improve significantly.

In this case, I think the new IO stuff is incredible.

replies(1): >>44463039 #
24. xeonmc ◴[] No.44463039[source]
It also helps job prospects of Zig programmers within organizations that have already adopted Zig -- more breakage, more job security.
replies(2): >>44463251 #>>44468895 #
25. tialaramex ◴[] No.44463081{3}[source]
In the C and C++ languages there's a thing called a "freestanding" implementation. This is roughly analogous to Rust's nostd.

In C the freestanding environment doesn't provide any concrete features, you don't get any functions at all, you can get a bunch of useful constants such as the value of Pi or the maximum value that will fit in an unsigned integer, some typedefs, that's about it. Concrete stuff from the "C standard library" is not available, for example it does not provide any sort of in-place sort algorithm, or a way to compare whether two things are the same (if they fit in a primitive you can use the equality operator)

In C++ there are concrete functions provided by the language standard in freestanding mode. These, together with definitions for types etc. form the freestanding version of the "standard library" in C++. There's a long period where this was basically untended, it wasn't removed but it also wasn't tracking new features or feedback. In the last few C++ versions that improved, but even if you have a new enough compiler and it's fully compliant (most are not) there's still not always a rhyme or reason to what is or is not available.

In Rust it's really easy. You always have core, if you've got a heap allocator of some sort you can have alloc, and if there's a whole operating system it provides std.

In most cases a whole type lives entirely in one of those modules, Duration for example lives in core. Maybe your $5 device has no idea which year this is, let alone day but it does definitely know 60 seconds is a minute.

But in some cases modules extend a type. For example arrays exist in core of course - an array of sixty Doodads where Doodads claim to be Totally Ordered, can just be unstably sorted, that works. But, what if we want a stable sort, so that if two equal Doodads were arranged A, B they are not reversed B, A ? Well Rust's core module doesn't provide a stable sort, the stable sort provided uses an allocation and so the entire function you need just doesn't exist unless you've got allocators.

replies(2): >>44463597 #>>44463716 #
26. flohofwoe ◴[] No.44463127[source]
Well, that's why Zig is 0.x and not 1.x. I'm fine even with large scale breakage if the direction is right (and looking at the mess that C++ has become for the sake of backward compatibility, IMHO breaking changes are also the better option after 1.x, as long as there's features to help manage the required changes).

Also, "Zig the language" is currently better designed than "Zig the stdlib", so breaking changes will actually be needed in the future at least in the stdlib because getting it right the first time is very unlikely, and I don't like to be stuck with bad initial design decisions which then can't be fixed for decades (again, as a perfect example of how not to do it, see C++)

27. ulbu ◴[] No.44463251{3}[source]
advances the purposes of cynics as well, so big bonus.
28. scrubs ◴[] No.44463517[source]
Well, that's a sentiment I don't quite agree with. It willfully ignores industry experience with c/c++ whence zig, rust, D, and others.

If your micro controller is say <5000 lines maybe ... but an OS or a mellanox verbs or dpdk API won't fall so easily to such surface level thinking.

Maybe zig could help itself by providing through llvm what Google sometimes does for large api breaking changes ... have llvm tool that searches out old api invocation update to new so upgrading is faster, more operationally effective.

Google's tools do this and give the dev a source code pr candidate. That's how they can change zillions of calls with confidence.

29. gpderetta ◴[] No.44463597{4}[source]
What the standard says about freestanding is all well and good. But what do actual embedded c++ compilers actually ship?

Also embedded covers a very wide range of computers.

replies(1): >>44463781 #
30. TuxSH ◴[] No.44463716{4}[source]
I know how freestanding works, and I agree that Rust's "nostd" is much more thought out than C/C++'s freestanding, however

> This is roughly analogous to Rust's nostd.

"freestanding" is actually worse that this. It means that the compiler can't even assume things about memcpy and optimize it out (as on gcc it implies -fno-builtin), which pessimizes a lot of idiomatic code (eg. serialization).

The "-nostdlib" option is usually what one wants in many cases (don't link against libc but still provide standard C and C++ headers), such as when compiling privileged code with -mgeneral-regs only and such. This way you can benefit from <chrono>, etc.

If you are writing userland code you should be using a toolchain for this, instead of relying of freestanding/nostdlib which are geared towards kernel code and towards working around defective toolchains.

31. TuxSH ◴[] No.44463781{5}[source]
If you are targeting armv4t/armv5/armv6k+vfp (or armv7 but not optimized for it) for Aarch32, or Armv8.0-A and are fine with newlib, then devkitARM and devkitA64, respectively, get the job done and ship GCC 15.1.

There is also devkitPPC, shipping with the same toolchain (and which additionally has some Obj-C support iirc).

Custom patches to newlib and consorts (https://github.com/devkitPro/buildscripts/) introduce hooks and WEAK functions that allow to implement standard library functions on almost any platform, on a platform library basis or even on a per-program basis (with some restrictions on lock sizes).

replies(1): >>44463922 #
32. kzrdude ◴[] No.44463868[source]
Pandas (different world: Python) arguably peaked in hype (if not popularity) before reaching 1.0
33. gpderetta ◴[] No.44463922{6}[source]
Indeed. My point was that freestanding is a strawman, with likely little relevance for embedded developers.
34. pjmlp ◴[] No.44464014[source]
In deployments where C and C++ are the only two options available, and management is not willing to get another one, C++ still has lots of improvements over, as "Typescript for C".

Building our own types was a rite of passage for C++ programming back in the early 1990's, and university curriculums for C++ as well.

35. mamcx ◴[] No.44464834[source]
I can relate, because I have so much things in years that broke left and right, but at the same time (except if you are talking about pre/alphas) I think is unhealthy to be vary of breaking changes.

A language, in special, should be able to do it. Extreme compatibility is the way to make the mistake that is C.

A breaking change that fix something is a investing that extend infinity to the feature.

Fear to do it, like in C, is how you accumulate errors, mistakes, millions of dollars wasted, because is also compound debt.

P.D: I think langs should be fast to break pre 1.0, and maybe have room to do it each 5/7 years. Despite the debacle of Python (that is in fact more reflective of python than of breaking), there should be possible to make a relatively painless sunsetting with good caring

replies(1): >>44466078 #
36. flohofwoe ◴[] No.44466078[source]
The problem I have with python2 vs python3 wasn't breaking backward compatibility, but that their "solution" for UNICODE strings is such a weird mess (treating string- and byte-streams as something completely separate instead of treating strings as UTF-8 encoded views on byte streams) The only string encoding that matters today is UTF-8, all others are relics from the early 90s and the sooner we get rid of those the better - e.g. Python caused a whole lot of pain for a solution that would have been useful 30 years ago, but not today.
replies(1): >>44468405 #
37. kbolino ◴[] No.44468405{3}[source]
There's another problem that's affecting more than just Python too: grapheme clusters. It turns out that even a sequence of scalars (code points excluding surrogates) isn't always a safe abstraction anymore.
38. vendiddy ◴[] No.44468895{3}[source]
Do you honestly believe what you're saying
39. pjmlp ◴[] No.44472202{3}[source]
It does.