3 ms·
Sorry, I explicitly meant statically typed languages. Rust, Nim, Zig, Odin, Jai, etc. > For many languages, print is special and the implementation is provided
by forrestthewoods 4y ago
Sorry, I explicitly meant statically typed languages. Rust, Nim, Zig, Odin, Jai, etc.
> For many languages, print is special and the implementation is provided as part of the language implementation.
Sure. Printing variables to strings is definitely worth language-level features imho. It's a bad thing if a language (C++) requires users to come up with extremely complex libraries (fmt/std::format) because the language lacks the features to make such a common operation simple and reliable.
C style printf is a dumpster fire. C++ iostreams are unuseably slow. Modern languages definitely solve this particular problem much better!
- atq2119 4y agoRust's print! implementation is pretty darn complicated, wouldn't you say?
- xigoi 4y agoHowever, Nim's is very simple: https://github.com/nim-lang/Nim/blob/version-1-6/lib/system/io.nim#L598 https://github.com/nim-lang/Nim/blob/version-1-6/lib/system/...
- elcritch 4y agoThe magic that makes Nim’s print / repr functions really neat is the `fieldPairs` iterator that works on any type. It’s a comptime function to iterate fields of a type, very handy and very simple to use. It can work on any type unlike Rust’s Debug macro which only works on types you own and can annotate. https://nim-lang.org/docs/iterators.html#fieldPairs.i%2CS%2CT https://nim-lang.org/docs/iterators.html#fieldPairs.i%2CS%2C...
- forrestthewoods 4y agoI don't know what Rust's print! implementation looks like. I also don't care. I am not a Programming Language programmer. I am a user of programming languages. Using C-style printf sucks balls. It's extremely error prone and it doesn't support complex types. Using Rust's print system is delightful. I can't make a type error and arbitrarily complex types can be printed with roughly zero effort via {:?} and #[derive(Debug)].
- lmm 4y ago> Sorry, I explicitly meant statically typed languages. Rust, Nim, Zig, Odin, Jai, etc. Requiring a macro is no better than what C does. Most of those languages have a less awful macro system than C's, but that's not an actual language advancement. The state of printing is still awful in the languages you mention.
- dilap 4y agoYou don't like Zig's solution? I think it's excellent. Normal zig code, executed at compile-time. No magic, no macros, fully compile-time error-checked formatting. https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L78 https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L...
- lmm 4y agoI don't, no. Proper stage polymorphism is great, but running arbitrary code at compile time without a coherent model of how you're doing that (which ad-hoc const/constexpr/etc. isn't) is like substituting for generics by having dynamic types. If I'm just going to run arbitrary code at compile time I might as well do that with a make rule.
- dilap 4y agoSure, it is basically a dynamic language at compile time, but I feel like the downsides of that are significantly mitigated by the fact that it's running at, you know, compile time -- you'll still get compile-time errors for any mistakes! (Some people even try to write entire programs in dynamic languages, as crazy as that is.) Regarding "might as well have a makefile rule," it's not really fair -- in practical terms having a seemless way to evaluate functions in your code at compile time is way different than doing codegen. Like, in practice, how would you write a type-safe format function using codegen? You could do it, but it would be very, very gnarly. Very different. Even Go -- which famously for a while tried to advocate codegen as an alternative to generics (w/ stuff like stringer to codegen print functions for human names for constants) -- resorts to dynamic types & runtime errors for formatting. So let's see: formatting approaches we've seen so far: – dynamic w/ runtime errors (e.g. Go, C#, C, ...) – static via baked into compiler support – static via special-case restricted compile-time evaluated language (e.g. rust macros) - static via full-lang compile-time eval (e.g. zig) I think you said all those are awful, so, I'm curious -- what's the better approach you have in mind?