[HN Gopher] Zig is hard but worth it
       ___________________________________________________________________
        
       Zig is hard but worth it
        
       Author : signa11
       Score  : 329 points
       Date   : 2023-06-01 10:44 UTC (12 hours ago)
        
 (HTM) web link (ratfactor.com)
 (TXT) w3m dump (ratfactor.com)
        
       | Alifatisk wrote:
       | May I ask what the hype is with Zig? What makes it so attractive?
       | 
       | Is it the performance? The easy interop with C? The ease of
       | controlling the memory allocation?
        
       | cynicalsecurity wrote:
       | Wait, it's a real language? I thought it was a sarcastic article
       | about an imaginary language called zig making fun of hipster
       | languages desperately trying to replace C/C++.
        
       | nickelcitymario wrote:
       | > [...] easy things seem easy primarily because they are
       | familiar. Easy is subjective. But simple things are simple
       | because they do not complicate; they have fewer concepts. Simple
       | is objective.
       | 
       | This should be printed out as a large poster in every office.
        
         | erichocean wrote:
         | Rich Hickey has done more to popularize that idea in recent
         | years than perhaps anyone else. [0]
         | 
         | In a lot of ways, Zig is to the _systems programming_ space
         | what Clojure is to the _information processing_ space.
         | 
         | If you have 5+ years experience, you want simple, not easy.
         | Both languages deliver real advances on that promise in their
         | respective domains.
         | 
         | ----
         | 
         | Back to the article, perhaps not coincidentally, the product my
         | startup is developing is written primarily in Zig (language
         | runtime), Clojure, and an in-house Forth/Factor/Joy derivative
         | for user-level scripting. I guess I really do care about
         | simplicity...
         | 
         | [0] Simple Made Easy:
         | https://www.youtube.com/watch?v=SxdOUGdseq4
        
       | WhereIsTheTruth wrote:
       | The issues I have with Zig are similar to the ones I have with
       | Rust, the syntax.. I will never get used to it, I find it
       | tasteless and non-ergonomic
       | 
       | But, I manage to set it aside because it provides enough
       | benefits, I mainly use Zig as a toolchain to crosscompile my
       | libraries.. and write some helper externs
       | 
       | Hopefully they manage to improve and ease out the syntax by 1.0,
       | I have hopes
        
         | jadodev wrote:
         | Have any examples of syntax you find tasteless? Things in Zig
         | that feel ergonomic to me: comptime params > separate generic
         | args; ptr.* > *ptr; optional pointers > possibly null normal
         | pointers; separate syntax for slices, arrays, & pointers > 1
         | syntax for ptr & arrays.
        
           | WhereIsTheTruth wrote:
           | var t: ?i32 = null;            if (t) {                t +=1;
           | }
           | 
           | This for example doesn't work, you have to capture, many
           | little things like that that stacks up and ends up creating a
           | non-ergonomic syntax
           | 
           | No for loop, so you have to do multilines things like, and
           | now you meet a new : construct, this pseudo for loop now
           | looks confusing to look at                 var i: i32 = 0;
           | while (i < 42) : (i+=1) {            }
           | 
           | Then constant casting between integers, and also floats..
           | also no operator overload for the math types etc..
           | 
           | Also not a fan of the pointer difference between [] * [:0],
           | too much different nitpicking that makes iterating slow and
           | painful, I understand the benefits, but the way it's done is
           | not enjoyable, at least to me
           | 
           | That's just whats on the top of my head, it's been a while I
           | haven't wrote Zig code so I may be remembering wrong
        
       | askkk wrote:
       | In new last version 0.10.1 it seems that for is not working with
       | two arguments?                 const std = @import("std");
       | const expect = std.testing.expect;            test "for basics"
       | {         const items = [_]i32 {4,5,3,4,0};         var sum: i32
       | = 0;         for(items, 0.. ) |value,_| {           sum += value;
       | }          try expect(sum == 16);       }            ubuntu
       | 22.04, snap zig version 0.10.1 ,        zig test 1.zig produces:
       | 1.zig:7:12: error: expected ')', found ','       for(items, 0.. )
       | |value,_| {                ^
       | 
       | Edited: To update, I tried snap, but using snap install --classic
       | --beta zig is a security risk because it can change the system
       | and is not sandboxed.
        
         | EscapeFromNY wrote:
         | For loop syntax was changed since 0.10.1.
         | 
         | Zig 0.10.1:                   for(items) |value| {}
         | for(items) |value, index| {}
         | 
         | Zig 0.11-dev:                   for(items) |value| {}
         | for(items, 0..) |value, index| {}         for(as, bs, cs, ds,
         | 0..) |a, b, c, d, index| {}
        
       | jeroenhd wrote:
       | I like Zig as a concept, but every time I've tried it, the
       | toolchain lacked good IDE and debugger support. I've tried some
       | plugins half a year ago but they either didn't work reliably or
       | they missed important features. I'm personally sticking with Rust
       | until the day comes that I can just add a VSCode/Clion plugin
       | that'll give me an interactive debugger with full autocomplete
       | support without fiddling around too much.
       | 
       | There's a lot to like with Zig, despite its unconvential syntax
       | and some language decisions I personally disagree with. The
       | language is still in development but it's very promising and I'll
       | definitely try to learn it before it reaches that magical 1.0
       | release.
        
         | jcalabro wrote:
         | I've definitely had a good experience writing Zig in VS Code
         | with the CodeLLDB extension on Linux [0] and the Microsoft C++
         | [1] one on Windows. It's also got the Zig extension which comes
         | with the Zig language server [2].
         | 
         | [0]
         | https://marketplace.visualstudio.com/items?itemName=vadimcn....
         | [1] https://marketplace.visualstudio.com/items?itemName=ms-
         | vscod... [2]
         | https://marketplace.visualstudio.com/items?itemName=ziglang....
        
       | LispSporks22 wrote:
       | > Only time will tell if comptime is the "greatest thing since
       | sliced bread" or not.
       | 
       | Common Lisp user here. Am I missing anything that Zig has in the
       | compile time department?
       | 
       | edit: Also, does the code in the comptime block have to be valid
       | Zig?
        
         | kllrnohj wrote:
         | Personally I think comptime is a questionably design and is
         | something both Rust & C++ did much better.
         | 
         | In C++ branches that don't have to "compile" are explicitly
         | marked as such with `if constexpr`. In Rust you've got macros
         | that are also explicit with required `!`. In Zig any branch can
         | be a ticking code rot time bomb, just like it was with C
         | #ifdefs. It's better in Zig in that it at least has to parse
         | and so you've got fewer blatant problems, but the category of
         | problems of "I flipped DEBUG from `false` to `true` and now I
         | have dozens of build errors to go fix" is still there. And you
         | really don't have any warning signs other than "this is
         | branching on something that _might_ be known at compile time "
         | 
         | But honestly that's also my general impression of Zig as a
         | whole. It's very definitely a "better C", not something that's
         | necessarily good/competitive with the broader state of the
         | ecosystem. It's like a love letter to C, completely with many
         | of the same general problems that C is known to have and that
         | other languages have addressed.
        
         | kps wrote:
         | It only has to be syntactically valid (parseable).
        
       | cies wrote:
       | From the article:
       | 
       | > Easy is subjective. But simple things are simple because they
       | do not complicate; they have fewer concepts. Simple is objective.
       | 
       | I'd argue both are subjective, or with a better word: relative.
       | 
       | I'd say Zig is easier and simpler than C in almost all regards.
       | The article does not specify what Zig is compared to in order to
       | make these statements. Probably the author had C in mind, but
       | that was not explicitly mentioned.
        
       | bakuninsbart wrote:
       | Where do you guys see good use cases for Zig? I'm intrigued by
       | the language but don't really have any good ideas on where to try
       | it out.
       | 
       | I thought about trying it out in as small data engineering
       | project, but I'm not sure if language support is sufficient for
       | the kind of tooling I would need eg. Database adapters.
        
         | jgalt212 wrote:
         | I've been thinking about using it for Python hot paths. I'm not
         | smart enough to write rust (at least without limitless supplies
         | of aspirin). And I'd like to avoid C for all the obvious
         | reasons.
        
           | Dowwie wrote:
           | Try Elixir.
        
         | pjmlp wrote:
         | In what concerns userspace, I don't see any good case, if I
         | want a better C, without much features, I rather stick to Go
         | even if I dislike some of the design decisions.
         | 
         | Or D, Nim, Swift, OCaml, Haskell, AOT C#, AOT Java,...
         | 
         | If any kind of automatic memory isn't possible/allowed, I would
         | be reaching out for Rust, not a language that still allows for
         | use-after-free errors.
         | 
         | Maybe it is a good language for those that would like to have
         | Modula-2 with a C like syntax, and metaprogramming
         | capabilities, and are ex-Objective-C developers.
        
           | distcs wrote:
           | > If any kind of automatic memory isn't possible/allowed, I
           | would be reaching out for Rust
           | 
           | I have come to the same conclusion but then I also fear that
           | Rust will continue to expand in scope and become a monster
           | language like C++. Do you or anyone fear that? Is that a
           | possibility?
        
             | TwentyPosts wrote:
             | Will Rust keep growing? Yes, I think so.
             | 
             | Will it turn into a C++-like monster? I don't know. Maybe,
             | but when it comes to C++ it always feels like its "monster"
             | status is largely a result of previous mistakes or early
             | design decisions piling up, and causing trouble (eg.
             | C-style arrays, exceptions, implicit conversions, fiddly
             | sum types rather than first class support, no pattern
             | matching etc.).
             | 
             | Rust will grow large, and probably complicated, but the
             | real issue with C++ are all these past mistakes and a shaky
             | foundation, and Rust is doing much, much better in that
             | regard. Time will tell if we'll eventually look back some
             | of Rust's design decisions as bad or unwieldy (probably).
        
               | riceart wrote:
               | > Time will tell if we'll eventually look back some of
               | Rust's design decisions as bad or unwieldy (probably).
               | 
               | I think time has already told for things like async and
               | lifetimes.
        
               | pjmlp wrote:
               | async, yeah it could be better, given the pains. However
               | note that adding async to .NET and C++ hasn't been a
               | panacea either, to the point that there is a prototype of
               | adding Go/Java green threading to .NET, done by the .NET
               | team. While with the C++ standard library there isn't an
               | executor runtime in the box.
               | 
               | Lifetimes are painful, and a other languages are
               | exploring better ergonomics or combining automatic memory
               | management with affine/linear types, yet it was Rust's
               | adoption that pushed other language designers to actually
               | look into this. So from that point of view, quite a
               | success, even if Rust vanishes tomorrow.
        
               | TwentyPosts wrote:
               | Can't say much about async, since I really lack the
               | experience to say whether async in Rust could feasibly
               | and realistically be much better than it currently is.
               | Some people say that it'd be great if it worked as
               | effortlessly as in Go, but I assume that you don't get to
               | have that without performance tradeoffs.
               | 
               | As for lifetimes, what's the issue? Do you have any
               | reason to believe lifetimes are frustrating because they
               | were badly designed, rather than the fact that they're
               | making complexity explicit which was previously hidden?
        
             | vilunov wrote:
             | Rust hasn't grown in scope very much since its release, but
             | in places where it has grown, particularly async and unpin,
             | I find that there features interact very badly with
             | lifetimes and borrowing. I am often forced to ditch
             | borrowing across async method calls and to put everything
             | in Arcs, even when the lifetime is well-defined and it
             | could be easily used if it had been scoped threads instead
             | of futures. I fear that newer features will be incompatible
             | with older ones in a similar way, but fortunately there are
             | no such features on the horizon.
             | 
             | Considering all that, I still see Rust as the most sane
             | choice for writing native programs. I don't really want a
             | "better C", I want to write memory-safe software with
             | confidence, and that means static analysis or a thick safe
             | runtime, whatever is more suitable for the use case.
        
               | mr_00ff00 wrote:
               | Technically though, isn't memory safety not necessary in
               | some cases?
               | 
               | For example, single player video games. You can exploit
               | your own machine if you want, but that's not an issue.
               | 
               | I like rust, but if I ran into async issues and annoying
               | stuff, I could see a world where I grab a non-memory safe
               | language to make games easily.
        
               | nequo wrote:
               | Crashing the program during runtime and having to debug
               | it then is still a worse experience than knowing before
               | running it that it cannot crash (due to memory errors).
               | 
               | This certainty comes at a cost, either by negotiating
               | with the Rust compiler or by putting up with a GC. But
               | depending on your calculus, that cost might be worth
               | paying.
        
               | yjftsjthsd-h wrote:
               | Memory safety isn't just a security thing, it's also a
               | reliability thing. That is, even if my games have zero
               | security sensitivity I'd still like them to not crash or
               | corrupt data.
        
               | pjmlp wrote:
               | It is an issue if it also allows players to work around
               | DLC and other goodies.
               | 
               | Or if having the game on the system can be used by
               | another malicious application as jumping point into root
               | access, starting it as subprocess and injecting the
               | exploit.
               | 
               | Example, Windows attacks via Notepad.
        
         | chjj wrote:
         | Do you maintain any C projects? Personally, I tried using zig
         | for its build system (which can also compile C and whose build
         | files are written in zig). One of the benefits of this was easy
         | cross-compilation to all major platforms.
         | 
         | It might not be a _real_ use-case or anything, but writing a
         | `build.zig` file for an existing C project might be a good way
         | to at least dip your toe in the water.
        
         | mcdonje wrote:
         | >Use Zig as a zero-dependency, drop-in C/C++ compiler that
         | supports cross-compilation out-of-the-box.
         | 
         | - ziglang.org homepage
        
       | ldelossa wrote:
       | I'm surprised that the reason I'm mostly interested in Zig is not
       | mentioned.
       | 
       | This is C interop.
       | 
       | I work with C quite a bit and I enjoy it, however writing a large
       | project in C can be tiresome.
       | 
       | Having an option like Zig which can import C headers and call C
       | functions without bindings is pretty attractive, especially when
       | you want to write something a big larger but still stay in C
       | world.
        
         | ziml77 wrote:
         | The thing that's espcially nice about that interop is that Zig
         | includes its own C compiler. That eliminates the pain of having
         | a build script locate an installed C compiler and figure out
         | what options should be passed to it.
        
           | lost_tourist wrote:
           | Why would I use zig c compiler in place of gcc or clang?
           | Mainly for zig interactivity or does it have some advantage
           | other than that over the aforementioned compilers?
        
             | TUSF wrote:
             | Zig's C/C++ compiler is just clang, but with header files
             | for most major platforms included, and sane defaults, so
             | there's no hassle getting it it to cross-compile. Some
             | companies have been using Zig solely for an easier to use
             | clang.
        
               | lost_tourist wrote:
               | Ah I see, thanks for your answer!
        
         | workethics wrote:
         | Not only that, but zig makes linking against old glibc versions
         | easy. For example, to make an x86_64 linux build linked against
         | glibc 2.9 when using zig build all you have to do is pass:
         | -Dtarget=x86_64-linux-gnu.2.9
        
           | GordonS wrote:
           | Damn, that's a magnificent feature! Maybe I should have
           | another look at Zig...
        
           | beefcafe wrote:
           | This is a killer feature for CTFs/OSCP/etc and why I started
           | using it.
        
         | Fiahil wrote:
         | C interop is not as much a "killer feature" as it used to be.
         | When you deal with data science, web and other similar domains,
         | reading and writing JSON ergonomically is much more important
         | than being able to call a C function directly. It's just a
         | nice-to-have.
        
           | afdbcreid wrote:
           | Yeah, but when you're doing systems programming (which Zig
           | aims at if I understand correctly), easy interop with C is
           | much more important than easy JSON marshalling.
        
         | billfruit wrote:
         | What about c++ interop?
        
           | Conscat wrote:
           | You can call internal and external linkage C++ functions from
           | Zig, but you can't do anything interesting like specialize
           | templates or evaluate constexpr functions.
        
         | esjeon wrote:
         | C-interop is pretty perfect for most usecases. The only trouble
         | I had was that, since command line arguments are converted to
         | slices in Zig, I have to convert them back to null-terminated
         | strings whenever I call C functions using any of the arguments.
         | Nothing difficult but slightly painful.
        
       | thih9 wrote:
       | > "I learned Zig in a weekend! ... Six hours! ... 6us!" say the
       | blissful lizards.
       | 
       | I don't get it; is this a reference? Could someone explain?
        
         | tylerscott wrote:
         | IIRC the mascot is a lizard so here the comment is portraying a
         | Zig enthusiast keen on promoting the ease of learning Zig as a
         | lizard. That was my take.
        
       | codedokode wrote:
       | I don't know anything about Zig except that it is a low-level
       | language. Can someone please explain how it is better than Rust?
        
       | Decabytes wrote:
       | Zig is not my favorite language to program in, but I think it's
       | focusing on a lot of the right stuff.
       | 
       | 1. Easy Build System 2. Drop in Replacement for c/c++ compiler
       | (zig cc) 3. Easy cross compliation 4. Single executable compiler
       | 5. Package manager 6. Debugabillity
       | 
       | It's the sort of developer focus that has a huge impact
       | especially when you are doing it for more than just a hobby.
       | Crystal, another language I love, is weak in this area. No tree
       | sitter, No tier1 windows support, Major libraries like the Lucky
       | Framework that don't build on Windows, a buggy LSP etc. Don't get
       | me wrong I love the language, and I will continue to work in it,
       | and all of these things are in various states of progress, but
       | it's already at 1.8 and some of these issues haven't been ironed
       | out yet. I'm not just armchair complaining, I know these are
       | hard, and I will contribute once I am more familiar with the
       | language
        
       | jsheard wrote:
       | I get what Zig is going for in making all operations as explicit
       | as possible, but I fear that it's going to turn away fields like
       | graphics and game development where it _would_ be a good fit
       | except for the lack of operator overloading forcing you to go
       | back to C-style math function spaghetti. It 's all fun and games
       | until what should be a straightforward math expression turns into
       | 8 nested function calls.
        
         | audunw wrote:
         | I like Zigs justification for not having general purpose
         | operator overloading (no hidden function calls and loops)
         | 
         | But I wish they added:
         | 
         | 1. Ability to declare completely pure functions that have no
         | loops except those which can be evaluated at compile time.
         | Something with similar constraints as eBPF in other words.
         | These could be useful in many contexts. 2. Ability to
         | explicitly import overloaded operators, that can only be
         | implemented using these pure guaranteed-to-finish-in-a-fixed-
         | number-of-cycles functions.
         | 
         | Then you'd get operator overloading that can be used to
         | implement any kind of mathematical function, but not all kinds
         | of crazy DSL-like stuff which is outside the scope of Zig (I
         | have nothing against that, I've done crazy stuff in Ruby
         | myself, but it's not suitable for Zig)
        
         | TwentyPosts wrote:
         | I am not much of a Zig-head, but the best compromise I can
         | think of is having a few operators which purely and solely
         | exist for this purpose. In other words, there is no operator
         | overloading, but you can define, say, "#+" for any two structs,
         | or something like that.
         | 
         | So if you want to encode matrix multiplication, then you'll
         | always have to write `mat1 #* mat2`. This feels like a hack,
         | and isn't all that elegant, but it'd be clear that every usage
         | of such an operator is a disguised function call. (And
         | according to what Andrew Kelley said, it's all about not hiding
         | function calls or complex operations in seemingly innocent
         | 'overloaded' symbols.)
         | 
         | If you want to take this one step further you'd probably have
         | to allow users to define infix functions, which would be its
         | own can of worms.
         | 
         | Honestly, I am not particularly happy with any of these ideas,
         | but I can't think of anything better either!
        
           | ljlolel wrote:
           | Idea: allow some weird Unicode operators like Julia does.
           | Then it'll be clear the weird operator is doing something
           | weird and new. And this already works in other languages.
           | There are lots of Unicode
        
             | spenczar5 wrote:
             | Writing greek symbols is sufficiently annoying that I
             | always kind of resent code that does this. It's not just
             | about the first time you are writing code, but also when
             | you are reviewing it, or trying to share a snippet with a
             | coworker, or lots more scenarios. Maybe it's just me, but
             | writing 'z = x [?] d' is really tedious.
        
               | kps wrote:
               | [?] is near-worst-case since it's not even Greek. I think
               | domain-specific keyboard layouts are as much of a good
               | idea as language-specific layouts, but they're a nuisance
               | to install on *nix (trivial on OS X). Using .XCompose is
               | the most practical *nix approach, in the absence of
               | program-specific methods like Julia's tab-completable
               | backslash names.
        
               | Conscat wrote:
               | I interpret this as meaning that ibus is difficult to set
               | up. FWIW, Emacs and Kitty let you input unicode without
               | it.
        
               | lvass wrote:
               | Just use C-x 8 in Emacs and you'll get any symbol by
               | name, with autocomplete.
        
               | [deleted]
        
           | thechao wrote:
           | Maybe an operator-overloading _region_?                   #{
           | m3 = m1 * m2 + m3;            m3 += m4;         }
           | 
           | Basically, pure syntactic sugar to help the author express
           | _intent_ without having to add a bunch of line-chatter.
           | 
           | Speaking of operator-overloading, I really wish C++ (anyone!)
           | had a `.` prefix for operator-overloading which basically
           | says "this is more arguments for the highest-precedence
           | operator in the current expression:                   a := b
           | * c .+ d;
           | 
           | Which translates to:                   a := fma(b, c, d)
        
             | MH15 wrote:
             | Huh I've never seen this approach. Very interesting
             | solution, could be adapted to the JavaScript matrix
             | libraries I bet.
        
               | estebank wrote:
               | In Rust you could use a proc macro that parsed the block
               | and translates the token to a new token stream that uses
               | method calls with the appropriate operator precedence,
               | for arbitrary operations you could want to define. You're
               | effectively writing a compiler plugin and language
               | extension at that point. For targeted niche domains, this
               | might be worthwhile.
        
               | bakkoting wrote:
               | There's a not-very-active proposal to add operator
               | overloading to JS which takes a similar scoped approach:
               | 
               | https://github.com/tc39/proposal-operator-overloading
        
               | thechao wrote:
               | This is how TeX handles math -- the "$" operator is an
               | "inline" version of the same.
        
           | renox wrote:
           | > I am not much of a Zig-head, but the best compromise I can
           | think of is having a few operators which purely and solely
           | exist for this purpose. In other words, there is no operator
           | overloading, but you can define, say, "#+" for any two
           | structs, or something like that.
           | 
           | And those operators wouldn't have any precedence.
           | 
           | > If you want to take this one step further you'd probably
           | have to allow users to define infix functions, which would be
           | its own can of worms.
           | 
           | As long as these infix function are preceded by a
           | recognizable operator ("#" in your example), I think that
           | this would be fine.
        
         | flohofwoe wrote:
         | Zig has a builtin @Vector type that might come in handy for
         | most cases where in C++ a math library with operator
         | overloading would be used:
         | 
         | https://www.godbolt.org/z/7zbxnncv6
         | 
         | ...maybe one day there will also be a @Matrix builtin.
        
           | jsheard wrote:
           | That still breaks if you layer any abstractions on top, for
           | example if you wanted to build an AoSoA packet of Vec3s you'd
           | have to define an addition of those in terms of a function.
           | 
           | https://www.godbolt.org/z/v8Ta8hEbv
           | 
           | Zig is exactly the kind of language where you'd _want_ to
           | build a performance-oriented primitive like that, but AFAICT
           | the language doesn 't let you do it ergonomically.
        
             | flohofwoe wrote:
             | That's true, but OTH that's already getting into territory
             | where operator overloading might start to become
             | detrimental because it hides important implementation
             | details which might not be expected from a simple '+'.
        
           | Conscat wrote:
           | It's a LOT worse than C++ SIMD libraries.
           | 
           | In C++ (EVE, Vc, Highway, xsimd, stdlib), you can specify the
           | ABI of a vector, which allows you to make platform specific
           | optimizations in multifunctions. Or you can write vector code
           | of a lowest-common-denominator width (like 16 bytes, rather
           | than specifying the number of lanes), which runs the same on
           | NEON and SSE2. Or you can write SIMD that is automatically
           | natively optimized for just a single platform. These features
           | are available on every notable C++ SIMD library, and they're
           | basically indispensable for serious performance code.
        
           | throwawaymaths wrote:
           | Probably not. @Vector is not a mathematical vector, it's
           | SIMD. it makes sense because there are times when those live
           | in registers and a poly fill for stack memory isn't
           | burdensome.
           | 
           | @Matrix makes less sense because when it gets big, where are
           | you getting memory from?
        
             | flohofwoe wrote:
             | For 'game-ey' math code, a matrix is at most 4x4 floats (64
             | bytes), that's fine for a value type that might live on the
             | stack.
             | 
             | vec2..4 and matching matrix types up to 4x4 is basically
             | also what's provided in GPU shading languages as primitive
             | types, and personally I would prefer such a set of "SIMD-y"
             | primitive types for Zig (maybe a bit more luxurious than
             | @Vector, e.g. with things like component swizzling syntax -
             | basically what this Clang extension offers: https://clang.l
             | lvm.org/docs/LanguageExtensions.html#vectors-...).
        
               | cmbothwell wrote:
               | You might like Odin, it has a similar philosophy to Zig
               | and supports swizzling:
               | 
               | https://odin-lang.org/docs/overview/#swizzle-operations
               | 
               | Matrix types are also built in:
               | 
               | https://odin-lang.org/docs/overview/#matrix-type
               | 
               | I've thought for a little while that Odin could be a
               | secret weapon for game dev and similar pieces of
               | software.
        
               | flohofwoe wrote:
               | I'm actually dabbling with Odin a bit in the scope of
               | language bindings for the sokol headers:
               | 
               | https://github.com/floooh/sokol-odin
               | 
               | It's a very enjoyable language!
        
         | pron wrote:
         | As someone who works on another language that is relatively
         | reluctant to add language features (Java) we regularly face
         | such dilemmas. A user shows up with a problem that could be
         | helped by the language. The problem is real and a language
         | feature would work, but there are many such problems, and
         | adding features to solve all of them will make the language
         | much bigger, overall causing greater harm (even those who don't
         | themselves use the feature need to learn it to be able to read
         | code). What we try to ascertain is how big of a problem it is,
         | how many programs or lines of code it affects, and is there
         | possibly a single feature that could solve multiple problems at
         | once.
         | 
         | So I would ask you this: what portion of your program suffers
         | from a lack of user-defined infix operators and how big of a
         | problem is it overall? Even if it turns out that the problem is
         | worth fixing in the language, it often makes sense to wait some
         | years and then prioritise the various problems that have been
         | reported. Zig's simplicity and its no-overload (not just
         | operator overloads!) single-dispatch is among its greatest
         | features, and meant to be one of its greatest draws.
        
           | markisus wrote:
           | In robotics, numerical linear algebra expressions comprise a
           | large part of the code base. If not by line count, then
           | definitely by the amount of time spent writing, reading, and
           | debugging such code. This makes Zig unusable for these
           | applications, at least not without additional tooling. You
           | can get a feel for how unergonomic this is by avoiding the
           | use of all arithmetic operators in your code and instead
           | forcing yourself to use user defined plus(a,b), minus(a,b),
           | assign(a,b), etc, or programming directly with the C blas
           | api.
        
             | erichocean wrote:
             | > _You can get a feel for how unergonomic this is by
             | avoiding the use of all arithmetic operators in your code
             | and instead forcing yourself to use user defined plus(a,b),
             | minus(a,b), assign(a,b), etc, or programming directly with
             | the C blas api._
             | 
             | You've dramatically overstated your case, since that's true
             | of every Lisp-like language.
             | 
             | Lisp is a perfectly suitable language for developing
             | mathematics in, see SICM [0] for details.
             | 
             | If you want to see SICM in action, the Emmy Computer
             | Algebra System [1] [2] [3] [4] is a Clojure project that
             | ported SICM to both Clojure and Clerk notebooks (like
             | Jupyter notebooks, but better for programmers).
             | 
             | [0] https://mitpress.mit.edu/9780262028967/structure-and-
             | interpr...
             | 
             | [1] Emmy project: https://emmy.mentat.org/
             | 
             | [2] Emmy source code: https://github.com/mentat-
             | collective/emmy
             | 
             | [3] Emmy implementation talk (2017): "Physics in Clojure"
             | https://www.youtube.com/watch?v=7PoajCqNKpg
             | 
             | [4] Emmy notebooks talk (2023): "Emmy: Moldable Physics and
             | Lispy Microworlds":
             | https://www.youtube.com/watch?v=B9kqD8vBuwU
        
               | KerrAvon wrote:
               | Why do you think this is true of Lisps? Emmy would not
               | seem to be a good example because it actually does
               | overload arithmetic operators to support extended data
               | structures. Look at, for example:
               | 
               | https://cljdoc.org/d/org.mentat/emmy/0.30.0/doc/data-
               | types/m...
        
               | erichocean wrote:
               | > _forcing yourself to use user defined plus(a,b),
               | minus(a,b), assign(a,b)_
               | 
               | This is the complaint I was responding to. Here is that
               | code in Clojure (a Lisp):                   // What the
               | GP claims is bad for doing math:         plus(a,b)
               | minus(a,b)         assign(a,b) // <= I have no idea what
               | this does, or has to do with math.                  //
               | Let's actually use the original math operators, but with
               | function notation:         +(a,b)         -(a,b)
               | // And here's the Clojure/Lisp syntax for the same:
               | (+ a b)         (- a b)
               | 
               | Lisp doesn't have "operators", so it doesn't have
               | "operator overloading." What it does have is multi-
               | dispatch, so yeah, the implementation of `+` can depend
               | on the (dynamic) types of both `a` and `b`. That's a good
               | thing, it means that the `+` and `-` tokens aren't hard-
               | coded to whatever the language designer decided they
               | should be in year 0, with whatever precedence and
               | evaluation rules they picked at the time.
               | 
               | The point I'm making is that you absolutely DO NOT need
               | to have special-cased, infix math operators to "do math"
               | in a reasonable, readable way. SICP is proof, and Emmy is
               | a breeze to work with. And it turns out, there are a lot
               | of advantages in NOT hard-coding your infix operators and
               | precedence rules into the syntax of the language.
        
             | hellcow wrote:
             | Using plus(a,b) for complex types sounds fine to me... I
             | have to imagine if I were working with a huge file of these
             | for a while it would start to feel normal, just like every
             | language has a different syntax but you eventually feel
             | comfortable using.
        
               | KerrAvon wrote:
               | Are you sure you would find this more ergonomically
               | pleasing:
               | 
               | assign(x, plus(a, plus(b, plus(c, b))))
               | 
               | When you could have:
               | 
               | x = a + b + c + d;
               | 
               | Or:
               | 
               | (let x (+ a b c d))
               | 
               | ?
        
         | tuhats wrote:
         | I have played around with using @Vector for linear algebra.
         | 
         | This removes the need for operator overloading for a vector
         | type, which covers most use cases of operator overloading and I
         | often in fact think is the only legitimate use case.
         | 
         | I don't get to use `*` for matrix multiplication, but I have
         | found I do not mind using a function for this.
         | 
         | I have only been playing with this in small toy programs that
         | don't to much serious linear algebra and I haven't looked at
         | the asm I am generating with this approach, but I have been
         | enjoying it so far!
        
         | bodge5000 wrote:
         | I'm no expert on zig, but the one area I have seen it shooting
         | up in popularity is game dev. Though I guess that is largely as
         | a replacement for C, so "C-style" wouldnt be much of a concern
        
           | jsheard wrote:
           | Zig looks like a fine C replacement, but C isn't what people
           | are using to make games in the vast majority of cases. It's
           | all C++, and operator overloading is part of the "sane
           | subset" that everyone uses even if they hate the excesses of
           | modern C++ as a whole.
        
             | felixgallo wrote:
             | as a long time game dev, I actively don't want operator
             | overloading. That's some spooky action at a distance
             | nonsense. I'm not sure I have seen a codebase that involved
             | operator overloading, either, and I've worked in or near a
             | good quantity of well-known titles.
        
               | jsheard wrote:
               | There's no accounting for taste, but the two major
               | publicly available engines (Unreal and Unity) both use
               | operator overloading in their standard math types.
        
               | Taywee wrote:
               | You'd rather use explicit function calls for all linear
               | algebra and geometry operations? I don't think adding two
               | vectors using an overloaded + is that spooky or distant.
        
               | flohofwoe wrote:
               | FWIW Zig can do that without operator overloading:
               | https://www.godbolt.org/z/7zbxnncv6
        
               | cyber_kinetist wrote:
               | First of all that only works with vectors, but I want
               | operator overloading to also work on things like matrices
               | or custom types (for example quaterions, or a symmat3
               | struct that represents a symmetric 3x3 matrix using only
               | 6 floats).
               | 
               | Additionally, for efficient math code you often want
               | vector / matrix types in AOSOA fasion: for example
               | Vec3<Float8> to store an AVX lane for each X/Y/Z
               | component. I want vector/matrix operations to work on
               | SIMD lanes, not just for scalar types, and Zig currently
               | can't support math operators on these kinds of types.
        
               | felixgallo wrote:
               | I have a marvelous proof that you can solve that with
               | comptime but unfortunately the margins of this website
               | are too small to contain it.
        
               | lvass wrote:
               | Do us a pastebin, please.
        
               | kprotty wrote:
               | Vectors in Zig are SIMD types. Vectors in games are
               | probably algebraic types. Using SIMD for the latter may
               | not be that useful if 1) specific elements are accessed
               | frequently 2) transformations involve a different
               | operation happen on each element.
        
           | mr_00ff00 wrote:
           | Would love to see zig in game dev. I've tried some rust and
           | while I love rust in general, I find game dev in it a bit of
           | a mess.
        
             | adastra22 wrote:
             | Have you tried bevy? I'm starting with bevy for a non-game
             | project, but I'm blown away by how simple it is to use once
             | you get used to the magic.
        
               | the__alchemist wrote:
               | Bevy isn't on the same level as tools like UE and Godot.
        
               | adastra22 wrote:
               | Depends on what you're doing. I'm writing a non-game app
               | that requires a scenegraph, raycast mouse selection tool,
               | and other tools of the sort typically required by games
               | and provided by a game engine. But there's a lot of game
               | stuff I don't need, and I need to make major
               | customizations to the rendering engine. It ended up being
               | easier to implement in bevy, due to its modularity, than
               | it would have been in UE4 or Godot.
        
               | Ygg2 wrote:
               | To be fair Godot isn't on same level as UE.
        
               | mr_00ff00 wrote:
               | Maybe I need to give bevy a second go. My big issue is I
               | felt I was learning to speak "bevy" instead of using
               | rust. A lot of functions I wrote required queries of
               | components, but the queries were built and called behind
               | a magically wall.
               | 
               | I don't have much game dev experience though outside of
               | simple games using libraries like raylib to just move and
               | draw stuff. Maybe once things get complicated enough they
               | are all like bevy.
        
               | adastra22 wrote:
               | This is true on both fronts, I think. Bevy magics away
               | the interface between you and the engine via the ECS
               | macros, in a way that is very unusual for a systems
               | programming language like Rust. But that's more or less
               | how all game engines are these days from what I
               | understand.
        
           | pjmlp wrote:
           | Not really, it is mostly around communities like Handmade,
           | most studios couldn't care less and it doesn't fit most
           | engines that they are using.
        
         | sigsev_251 wrote:
         | To be fair, there is an operator overloading proposal for
         | C2y/C3a and there is at least one compiler that offers operator
         | overloading as an extension.
        
         | kapperchino wrote:
         | For the math stuff you can do things like a builder pattern
         | where you can flatten the nested functions. But operator
         | overloading is definitely preferred
        
       | iskander wrote:
       | Is there anything akin to Maturin for Zig?
       | 
       | I would love to use it as an extension language for Python.
        
       | helen___keller wrote:
       | My main issue with Zig is that I'm scared to invest time in
       | writing something nontrivial to see the community/adoption
       | flounder then regret not using Rust or C++ later
       | 
       | The language itself is fun. The explicit-ness of choosing how
       | allocation is done feels novel, and comptime is a clean solution
       | for problems that are ugly in most languages.
       | 
       | Aside from lack of community I'd say the biggest nuisance is
       | error handling in nearly everything including allocations. I get
       | that allocation can fail but the vast majority of programs I
       | write, I just want to panic on an allocation failure (granted
       | these aren't production programs...)
       | 
       | Edit: in retrospect, allocator error handling verbosity is
       | probably necessary due to the power the language gives you in
       | choosing allocators. If I use the general purpose allocator then
       | my edge case is PC out of memory; if I use a fixed buffer
       | allocator, a failed allocation is a code bug or a common error
       | case, so we might want to handle the failed allocation and
       | recover
        
         | faitswulff wrote:
         | My impression of the Zig language as a total outsider is that
         | it seems like it has the underpinnings of success: it has a
         | niche, it has a governance model, and it has real commercial
         | users. It just has to not blunder very hard on the way to some
         | level of promised stability.
        
         | distcs wrote:
         | > If I use the general purpose allocator then my edge case is
         | PC out of memory
         | 
         | What does PC mean in this context?
        
           | nativecoinc wrote:
           | Maybe "the whole computer is out of memory" (general purpose
           | allocator). Contrast with a custom allocator which might only
           | be able to work with a few kilobytes (for example).
        
           | helen___keller wrote:
           | Personal computer
        
           | kubanczyk wrote:
           | player character
        
         | loeg wrote:
         | > Aside from lack of community I'd say the biggest nuisance is
         | error handling in nearly everything including allocations. I
         | get that allocation can fail but the vast majority of programs
         | I write, I just want to panic on an allocation failure (granted
         | these aren't production programs...)
         | 
         | The C strategy for this was just to wrap malloc() with
         | something called xmalloc or malloc_nofail or whatever:
         | void *malloc_nofail(...) {         void *res = malloc(...);
         | if (res == NULL) {           abort();         }         return
         | res;       }
         | 
         | (Or whatever.) The same would work in Zig, I think.
        
           | helen___keller wrote:
           | Yes you can easily make a one liner allocation function in
           | zig that takes an allocator as input with a comptime type and
           | panics if allocation fails and returns the unwrapped
           | allocation
           | 
           | I just say nuisance because zig code often looks like Go code
           | in that almost every return type becomes an error union as
           | allocation error handling (and maybe other errors) trickle up
        
             | TylerE wrote:
             | From my experience with Zig (limited but not zero) it seems
             | like an ok solution to a problem I don't have, and don't
             | forsee having.
        
         | bsder wrote:
         | > My main issue with Zig is that I'm scared to invest time in
         | writing something nontrivial to see the community/adoption
         | flounder then regret not using Rust or C++ later
         | 
         | This is 100% a real concern.
         | 
         | If I'm going to choose Zig, it's because it is _SO_ much better
         | on some axis that the community /adoption isn't an issue as I
         | gain the benefits almost immediately. That means that C++ and
         | Rust probably aren't in the scope of choice anyway.
         | 
         | I especially like the comment from elsewhere in thread where
         | they are using it for scripting, of all things, because they
         | can pop out code that builds and works on Windows _and_ Linux.
         | That 's a good example--you gain the benefits immediately even
         | if you later have to unwind that to something like Python.
        
         | kuroguro wrote:
         | I suppose you could write a few line wrapper that panics :)
         | 
         | But yeah, most of the time I don't even want to think which
         | allocator to use let alone handle it's errors.
        
           | eatonphil wrote:
           | This is basically what I've come to do in the Zig scripts I
           | write at work.
           | 
           | It took a bit of getting used to when I joined but we agreed
           | as a team to have all meaningful scripts written in Zig not
           | bash (for one, bash doesn't work on Windows without WSL and
           | we need to support Windows builds/testing/etc.).
           | 
           | It makes about as much sense as any other cross-platform
           | scripting option once I got used to it!
           | 
           | Some examples:
           | 
           | Docs generation: https://github.com/tigerbeetledb/tigerbeetle
           | /blob/main/src/c...
           | 
           | Integration testing sample code: https://github.com/tigerbeet
           | ledb/tigerbeetle/blob/main/src/c...
           | 
           | Running a command wrapped in a TigerBeetle server run: https:
           | //github.com/tigerbeetledb/tigerbeetle/blob/main/src/c...
        
             | rowls66 wrote:
             | I am truly puzzled by this. I understood Zig to be a very
             | low level language like 'C'. Why would you write scripts in
             | it?
        
               | eatonphil wrote:
               | It's significantly nicer to write than C (my opinion
               | obviously). I see it as a general purpose language.
               | 
               | But mostly the team decided to do this because we wanted
               | to unify on one language and double down on the
               | investment in Zig.
               | 
               | I'm not a fanboy (nothing wrong if anyone is, just
               | clarifying about myself); I think this choice was right.
        
               | 59nadir wrote:
               | For what it's worth I think this is an excellent choice.
               | Back in 2019 I was deciding whether I wanted to pursue
               | Zig full-time and one of the upsides that I determined
               | was that once you reach critical mass writing all of your
               | code for tools and things in Zig you end up with things
               | that are really exactly what you need and with a very
               | high baseline for speed, flexibility, and so on.
               | 
               | Right now I'm considering the same thing but with Odin
               | and for many of the same reasons that I had for Zig; it's
               | an excellent language to write foundational code in and
               | once you do, you end up being able to build significantly
               | more understandable, reliable, stable and consistent
               | things.
               | 
               | This, but on a company level, is a real multiplier. Once
               | you adopt a couple of Python scripts and that's OK, you
               | give up the possibility of wielding this sharp spear.
               | 
               | Edit:
               | 
               | I think "How I program C" by Eskil Steenberg is an
               | interesting window into what you can get if you laser
               | focus on a language and environment and allow yourself to
               | build up a mountain of code that you dogfood:
               | https://www.youtube.com/watch?v=443UNeGrFoM
               | 
               | At some point I will likely soft-retire and at that point
               | it's exceedingly unlikely that I'll bother with using
               | other people's libraries except a few key ones that I
               | think are decent, and at that point there really is no
               | reason I'd sit down and write these fundamentals in
               | anything but a lower-level language. Odin, Zig or
               | something like it would pretty much be the only thing on
               | the table.
        
               | hoosieree wrote:
               | Binary executables are a nice feature, especially for
               | distributing to users.
               | 
               | It's much easier for most people to download a standalone
               | "mac" or "windows" binary than to know if they already
               | have the right version of Python or Perl or Clang (and
               | all the transitive dependencies your project adds).
        
               | eatonphil wrote:
               | We don't host the built binaries of these scripts (we
               | could!), but we bootstrap the local environment through a
               | single bash script or batch script (Windows) that pulls
               | down the Zig compiler. Then everything else in the repo
               | depends only on that until we get until client-language
               | specific bits which of course depend on other languages.
               | 
               | But yeah it is quite simple still.
        
               | vaughan wrote:
               | I'm moving all my scripting to TypeScript using Bun (JS
               | runtime written in Zig).
               | 
               | For scripting its a way better choice. `bun:ffi` also
               | makes it trivial to run C or Zig code when you need to.
        
               | rowls66 wrote:
               | I guess I don't see C as programming language for writing
               | scripts in either. In my view any language that requires
               | a separate complication step is not a scripting language,
               | and therefore not a language in which one writes scripts.
               | In C or Zig you write programs.
               | 
               | Maybe I am just being too pedantic.
        
               | eatonphil wrote:
               | I didn't call it a scripting language. Nor do I think C
               | would be great to write scripts in either. :) I only said
               | we write scripts in Zig. But if you'd like to call these
               | files programs instead of scripts then that's ok too!
        
           | chrsig wrote:
           | I think for the problem space zig is trying to fit in, it's
           | pretty essential to have custom allocator support thoroughly
           | baked in.
           | 
           | It's the sort of thing that lets a data structure be used on
           | both a gpu and cpu, allocation out of shared memory, or
           | ensure that no dynamic allocations are happening at all.
           | 
           | Most programs don't have those concerns - so zig may not be
           | the best choice for them. For the programs that do have those
           | concerns, forethought about allocators is pretty important.
           | Right tool for the job, and all that.
        
       | mgkimsal wrote:
       | https://archive.is/cMm11
        
       | galaxyLogic wrote:
       | Love the picture. People often say how easy something was for
       | them. They are saying they are a very capable, smart person.
       | Would you rather hire someone for whom everything is easy, or
       | someone for whom things seem difficult?
       | 
       | In other words saying they learned something fast or that
       | something is easy for them, is at least partially self-promotion.
       | So claims of how easy something was for them it have to be taken
       | with a grain of salt.
       | 
       | The interesting thing for the rest of us is WHY something is
       | easy, or difficult. That would be helpful for others to know.
       | This article is just that, it tells us why Zig can be difficult.
       | What to look out for.
        
       | jksmith wrote:
       | Is this a writeup about Zig, or any Wirth language written 50
       | years ago? Asking for some Modula2 OG.
        
       | latch wrote:
       | I've now written a lot of zig code (http.zig, websocket.zig,
       | log.zig, zuckdb.zig, etc.) I think Zig falls into an "easy to
       | learn, average/hard to master" category.
       | 
       | Some insiders underestimate the effort required for newcomers to
       | build non-trivial things. I think this is because some of that
       | complexity has to do with things like poor documentation,
       | inconsistent stdlib, incompatible releases, slow release cycle,
       | lack of package manager, etc. For an insider living and breathing
       | Zig, not only aren't these huge challenges, they aren't really
       | "Zig" - they are just transient growing pains. For someone
       | getting started though, the current state of Zig is Zig.
       | 
       | I wish Zig had a polished package manager (there's one in the
       | current development branch, but you don't as much use it as fight
       | it). They could then move some of the less polished code into
       | official experimental packages, helping to set expectations and
       | maybe focus the development efforts.
        
         | JC770 wrote:
         | I just start to learn Zig,any suggest to beginners?Bro
        
           | hiccuphippo wrote:
           | Other than the main documentation, check ziglearn.org and
           | ziglings.org. Also read the std code, specially the tests
           | when you want to know how to use something.
        
         | zoogeny wrote:
         | I've lately thought that a package manager is as essential to a
         | new language as a standard library. I would also add a LSP and
         | standard code formatter to that list.
         | 
         | It is a bit unfortunate because all of the above is a pretty
         | tall order. We're getting to the point that new languages are
         | expected to boil the ocean by the time they reach 1.0
        
           | chrsig wrote:
           | > I've lately thought that a package manager is as essential
           | to a new language as a standard library. I would also add a
           | LSP and standard code formatter to that list.
           | 
           | Agreed. Especially on a formatter. The number of code review
           | comments it cuts out is incredibly time and energy saving.
           | 
           | > It is a bit unfortunate because all of the above is a
           | pretty tall order. We're getting to the point that new
           | languages are expected to boil the ocean by the time they
           | reach 1.0
           | 
           | In order to get into production? yes. there are minimum
           | requirements that must be met. those are higher now than in
           | the past, because of lessons learned the hard way. those
           | problems have been solved (for some value of solved) in
           | existing ecosystems -- a new language wont change the need
           | for them to be solved.
           | 
           | it shatters the dream of hacking up something on a weekend
           | and having it turn into a hit success, but it also removes
           | the case of hacking up something in 10 days and suffering the
           | consequences for the next 30 years.
           | 
           | Until they have what you mentioned, the languages _aren 't_
           | ready for large scale use -- they need to grow into it. They
           | can be useful prior to that -- enthusiasts and early adopters
           | can reap what benefits are provided. That adoption is what
           | fuels the development of things like a standard code
           | formatter.
           | 
           | edit: fixed omission of a unit of time after '30'
        
             | 6keZbCECT2uB wrote:
             | Not sure about lsp, but I think if you defined your
             | language in tree sitter, you might be able to define a
             | basic autoformatter generically on tree sitter to
             | accelerate bootstrapping your language.
             | 
             | You could also use an existing language agnostic package
             | manager like nix, guix, or conda to bootstrap your language
             | package manager.
             | 
             | Lsp is something I don't know of a way to make that easy
             | without overly constraining the design space.
        
             | clessg wrote:
             | > but it also removes the case of hacking up something in
             | 10 days and suffering the consequences for the next 30
             | years
             | 
             | Ha, I thought this sounded distressingly familiar!
             | 
             | "In September 1995, a Netscape programmer named Brandan
             | Eich developed a new scripting language in just 10 days. It
             | was originally named Mocha, but quickly became known as
             | LiveScript and, later, JavaScript."
        
           | savolai wrote:
           | Would love to understand better what exactly is language
           | specific about package managers? You would think a winner
           | would emerge in this space like one has in version control to
           | be used with all languages, just separate repos for different
           | ecosystems?
        
             | anon84873628 wrote:
             | I was also wondering this. Why does every language need to
             | reinvent the wheel?
        
             | vineyardmike wrote:
             | Different languages do imports differently. There are
             | different constructs for "exports" and modules and
             | namespaces that prevent a common single directory
             | structure.
             | 
             | Pip used to store packages in a global location, now most
             | of python used a Virtual Environment per project.
             | 
             | Node uses a "vendor" directory within the project
             | structure. This is probably the easiest case.
             | 
             | Go used to store everything globally in the "go path" but
             | now with go modules it does something else.
             | 
             | Java doesn't need source code, just single JAR files, but
             | it needs it within the classpath.
             | 
             | C/++ is very flexible, but varied depending on how you
             | build and set up your project.
             | 
             | Swift/ObjC requires doing whatever apple wants and dealing
             | with their tooling.
             | 
             | Everything is different. If you want "one winner" the
             | closest you get it is the system package manager (of which
             | multiple exist) and pointing your project to its package
             | cache. But not all system package managers handle multiple
             | concurrent versions of the same package.
             | 
             | Maybe one day people will standardize against Nix which
             | seems to be the closest?
        
           | arp242 wrote:
           | Zig has a pretty decent LSP.
           | 
           | I'm not so sure a package manager is really all that
           | essential; it can certainly be convenient but especially in
           | the space Zig is looking at it's pretty workable without one
           | (without complex deep dependency trees you can use git
           | submodules or just copy a directory). Or let me put it this
           | way: I never really missed a package manager in Zig.
        
             | BaculumMeumEst wrote:
             | > I'm not so sure a package manager is really all that
             | essential
             | 
             | I agree with you, but this is subjective. Not having a
             | package manager will probably turn off many from the
             | language. But it's OK for the Zig folks to make a call that
             | a lot of people won't agree with if it doesn't fit their
             | vision of the language.
        
             | ReleaseCandidat wrote:
             | > I'm not so sure a package manager is really all that
             | essential;
             | 
             | For open source software (libraries or programs, that
             | depend on other libraries or programs), it is essential (if
             | you're not distributing single functions like with Unison).
             | For closed source it doesn't matter that much.
        
               | arp242 wrote:
               | "cp -r ~/some-lib ~/my-project/" works well enough if
               | some-lib doesn't have dependencies on its own. Or git
               | submodules if you want something a bit more fancy. I
               | sometimes do this even for languages with package
               | managers, as it avoids a world of complexity.
               | 
               | Obviously a package manager is _useful_ , but Zig is
               | relatively low-level and long dependency chains are much
               | less common than in e.g. Python, Ruby, and of course
               | NodeJS. So I'd argue it's not _essential_. All the other
               | things mentioned in the to top comment are far bigger
               | issues IMO.
        
               | TylerE wrote:
               | [flagged]
        
               | tuckerpo wrote:
               | Why? A submodule can be frozen at a given commit. They're
               | trivially updated or rolled-back, too.
        
           | latchkey wrote:
           | > I've lately thought that a package manager is as essential
           | to a new language as a standard library.
           | 
           | This was the approach Ceylon took. Sadly, despite a lot of
           | effort, the language never took off.
        
           | johnnyjeans wrote:
           | I disagree. I actively avoid languages that rely on package
           | managers simply because they only give the illusion of being
           | beneficial. It ends up being more boilerplate I have to learn
           | to use an ecosystem, because they don't actually solve
           | dependency hell and now there's a whole additional
           | complicated tool with its own DSL I have to contend with in
           | order to fix what's broken (or even diagnose issues.)
           | 
           | The more peripheral crap I have to deal with to use your
           | language, the less I'm likely to use it in the first place. I
           | don't need, want or care to learn yet another idiosyncratic
           | fragile system. Finding source tarballs is a complete non-
           | issue, and inevitably I'm going to have to manually build
           | things anyways to figure out what erroneous assumption a
           | library is making about the underlying system which is
           | causing the build to fail or the runtime to crash, so the
           | package manager just ends up being extra steps. Without fail,
           | that has always been my experience with language package
           | managers.
           | 
           | In the pursuit of making things simpler, we're really just
           | making them harder.
        
             | zoogeny wrote:
             | I'm not sure I understand this issue. The existence of a
             | standard package manager doesn't prevent you from manually
             | vendoring dependencies if you want to. I have personal
             | experience working on node.js projects where several
             | dependencies were just `cp` into a directory and treated
             | like local modules, no npm involved at all.
             | 
             | It's like `apt` or `brew` for system dependency management.
             | It is there if you want it but you can just as well
             | download a tar and config/make/install yourself if you
             | want.
             | 
             | In many ways, it is like a standard lib. No one forces you
             | to use it. If you prefer the simplicity of your own
             | implementations then I see no reason why you can't just
             | write your own.
             | 
             | But when you want the advantages of a package manager, and
             | there are advantages that you may not appreciate but others
             | do, then having a standard one built into the language
             | feels preferable to having a dozen non-standard
             | independently competing variations that the community
             | cobbles together.
        
             | fauigerzigerk wrote:
             | The cynic in me would say that including a standard package
             | manager is absolutely necessary to stop several of them
             | popping up every year :)
        
             | gen220 wrote:
             | Just curious, not snide: what language fits this criteria?
             | 
             | C/C++? Using Python 3.7+ in a way that completely ignores
             | Pip, because the stdlib is now quite expansive?
        
               | thegeekpirate wrote:
               | Odin
        
               | seba_dos1 wrote:
               | Python is quite often being used without pip, as the
               | modules are often packaged by distros already (and in
               | many distros they _have_ to be packaged this way in order
               | to include the application that uses them in the repos).
        
               | paulddraper wrote:
               | Must be C/C++.
        
             | JohnFen wrote:
             | I agree entirely. Relying on a package manager in order for
             | a language to be useful indicates to me that there's a
             | deficiency in the language.
        
               | pornel wrote:
               | Is every language supposed to come with HTTP and TLS
               | stack, clients for every database, de/serializers for
               | every format, every image and video codec, every
               | de/compressor, GUI toolkits, 3D rendering, Bluetooth...
               | where do you stop?
               | 
               | And then how do you maintain all of this bloat to a
               | competitive level, so that users don't need to reach for
               | faster/newer alternative packages anyway?
               | 
               | And how do you maintain portability and backward
               | compatibility of a language with such a vast API surface?
               | 
               | In modern development there's just too much stuff to keep
               | everyone happy with batteries included. Sooner or later
               | users will need something that isn't built in, and that
               | will cause pain and crappy workarounds if the language
               | doesn't have first-class support for dependencies.
        
               | pdntspa wrote:
               | You could manage it like .net did before
               | chocolatey/winget -- pretty much a free-for-all, just add
               | yourself to the COM list through whatever means you want
               | and have at it
               | 
               | But that was a mess. I still have nightmares from dealing
               | with windows assembly cache issues.
               | 
               | Honestly it reminds me of some of the shit I've had to
               | deal with with pip (what do you mean you can't resolve
               | this dependency???)
        
               | JohnFen wrote:
               | I suppose that I just never had a problem maintaining any
               | dependencies in code I write. Package managers have long
               | been a bit of a pain for me as a developer, and with some
               | languages (like Python), they are a huge PITA for me as a
               | normal user of applications.
               | 
               | So overall I don't view them in a very positive light.
               | They're something I have to put up with.
               | 
               | No matter, it is what it is. Carry on. :)
        
               | pornel wrote:
               | When Python was originally designed disk space was
               | precious, and access to the Internet was rare, and its
               | dependency management was designed for that world. Its
               | multiple retrofitted package managers never fully fixed
               | it.
               | 
               | However, better integrated package managers can work
               | well. In case of Node.js and Cargo, the main argument
               | against them is that it's _too easy_ to add dependencies.
        
             | jeroenhd wrote:
             | The problem with source tarballs is that you need to then
             | manually watch out for updates and bugfixes for every
             | dependency you pull in. You also need to deal with the
             | bespoke build system of your packages of choice or manually
             | build something compatible with your project. You can also
             | choose not to and skip vulnerable, buggy code for a few
             | years like some companies do, but that's hardly an
             | advantage. You also need to ship (and possibly license) all
             | of your dependencies.
             | 
             | Alternatively, you can let the system package manager do
             | all the hard work for you. That works great, as long as you
             | only target one OS or put in the work to maintain
             | compatibility with multiple OS releases.
             | 
             | My experience with languages without package managers is
             | that large, maintained projects all invent their own
             | package manager (remote git repos? shell scripts
             | downloading files? a two-stage build process written in the
             | language itself?) in combination with some sort of Makefile
             | generating hell script that breaks for a while when a new
             | OS release comes out.
             | 
             | This approach works if you're the entire system. SerenityOS
             | can do this, because it's basically an entire operating
             | system and userland all inside one repository. ChromeOS can
             | probably do it as well, since the app portion isn't running
             | OS-native code anyway. For everyone else, it's just making
             | someone else do the work of the package manager manually.
        
           | paulddraper wrote:
           | > new languages are expected to boil the ocean by the time
           | they reach 1.0
           | 
           | The reason is that there are existing high-quality
           | languages/ecosystems.
           | 
           | (Which is a good thing!)
        
           | adamrezich wrote:
           | package managers are relatively easy to put together and
           | release with your language--provided that you want your new
           | package manager and surrounding ecosystem to work exactly the
           | same as other, popular ones, without putting any effort into
           | improving the status quo. doing better than other languages'
           | package managers takes significant effort, because it's both
           | a computer engineering problem _and_ a social engineering
           | problem.
           | 
           | it's nice when a new language has a package manager right out
           | of the gate, but I would like to see more new languages take
           | a more measured approach and aim to significantly _improve_
           | upon past efforts, instead of merely replicating them out of
           | some sense of obligation.
        
         | cassepipe wrote:
         | To get an idea, what is your programming background ? Are you a
         | C or C++ programmer ?
        
         | VyseofArcadia wrote:
         | I used Zig for a weekend project and _loved_ it, but I am
         | resolved to not use it for anything else until it hits 1.0. I
         | don 't have time to write and re-write and re-re-write my code
         | as the language and stlib stabilize.
        
           | Tozen wrote:
           | If that's the thinking, looks like it will be a long wait.
           | Appears to be another 2 to 3 years before 1.0 hits. And it
           | publicly came out in 2016, so add all those years up.
        
       | TaupeRanger wrote:
       | Maybe a few years ago it would've been "worth it". But with LLMs
       | coming to swallow up all coding tasks and turning programmers
       | into prompt engineers within a few years time, I can't see it
       | being "worth it" any more.
        
         | mr_00ff00 wrote:
         | I don't want to make assumptions, but have you tried systems
         | programming with LLMs?
         | 
         | A few years and everyone will be prompt engineers is laughable.
         | I hope I can actually use it productively for more than unit
         | tests in a few years.
        
         | Taywee wrote:
         | You still need to understand the code you are generating,
         | testing, and debugging. LLMs don't replace a need for more
         | expressive programming languages.
        
       | jiripospisil wrote:
       | I've been playing with it and so far but I'm more impressed with
       | their build system rather than the language itself (it seems to
       | be way more flexible and simpler than alternatives which is
       | pretty rare). They did however get the module system right. You
       | can just organize the file structure in any way you like. I hate
       | Rust's "everything is a single module" system with passion.
        
         | mike_hearn wrote:
         | How do you find it simpler? From taking a quick look it appears
         | to just be an API for invoking build steps, and the build
         | script is itself a Zig program.
         | 
         | I ask if it's really simple, because the JVM space went in the
         | same direction with Gradle (build script = program) and by the
         | time it gets more sophisticated that can turn out to be pretty
         | painful. In particular, IDEs struggle to get the information
         | they need, scripts can become highly complex, and there are
         | various other problems.
        
           | pjmlp wrote:
           | Gradle is Ant reinvented, by those that didn't learn why we
           | moved into Maven.
        
       | rayiner wrote:
       | Alternative languages are cool, but I struggle to see the point
       | of a systems programming language that doesn't offer static
       | memory safety in 2023. Rust isn't necessarily the best and final
       | answer--it seems like there is a broad design space to explore
       | for memory-safe systems programming languages. But Zig seems to
       | occupy the same local maximum as C--a relatively simple, non-safe
       | systems language--and doesn't have a killer feature that
       | justifies not just using C.
        
         | haberman wrote:
         | The killer feature of Zig IMO is comptime. C++ has spent over a
         | decade now marching towards making more and more of the
         | language available at compile time, but in an awkward and
         | complicated way (constexpr, consteval, constinit). Zig comes
         | out of the gate with a unified and coherent compile-time
         | evaluation feature that effectively obsoletes not only
         | constexpr/consteval/constinit, but C++ templates too. This is
         | "doing more with less" in a way that I find really compelling.
        
           | Conscat wrote:
           | Zig does not have anything analogous to constinit, because
           | Zig does not have object lifetimes or constructors. Comptime
           | is also a massive pain to use for generating new data types
           | (you have to return a type from a comptime function), and it
           | cannot express anything analogous to CRTP.
        
         | helen___keller wrote:
         | If we're comparing C to Zig I'm not sure what memory safety
         | even needs to be mentioned for.
         | 
         | For C to Zig there's plenty of reasons one might prefer Zig.
         | For memory safety obviously you might opt to choose neither.
        
           | rayiner wrote:
           | In a vacuum, one might prefer Zig. But given that everyone
           | already knows C and the ecosystem is so highly developed, it
           | takes a gamechanging feature like Rust's memory safety to
           | make an alternative language attractive (beyond a "this is
           | cool" project--which I totally support).
        
             | helen___keller wrote:
             | That is probably why Zig has such a focus on seamless C
             | interop. There's a good thread in these comments talking
             | about this.
             | 
             | Regardless, point taken. You're more or less describing the
             | internal fear I have (mentioned in another thread) that if
             | I dedicate time to a nontrivial Zig project I will regret
             | it if/when there's no Zig community in N years
        
             | alwaysbeconsing wrote:
             | I haven't tried Zig, but "all the things you like about C
             | plus better versions of most/all of the awkward bits" seems
             | like a reasonable value proposition. Especially since the
             | compiler can apparently let you use C painlessly alongside
             | your Zig -- enabling incremental rewriting.
        
               | j-james wrote:
               | Can you use Zig painlessly alongside C? Does `zig cc` or
               | an equivalent provide for writing Zig libraries that then
               | can be called by a main C function?
        
               | [deleted]
        
               | helen___keller wrote:
               | Yes probably as painlessly as a nonC language can get.
               | First class support for C calling conventions, struct
               | layouts, and so on
               | 
               | https://ziglearn.org/chapter-4/ See here
        
               | j-james wrote:
               | Yeah, I read through that: unless I'm missing something I
               | think what I'm curious about is "calling C code from Zig
               | and vice versa" in the to-be-written section.
               | 
               | Nim also has support for `ctypes` and compiles to C as
               | its main target: yet though its interop is powerful it
               | lacks in ergonomics, formerly you had to manually wrap
               | every function you wished to use and this was only
               | recently fixed by a macro-heavy external library.
               | 
               | I'm wondering what Zig does because IMO even if you have
               | an excellent technical solution getting people to
               | actually use it alongside C is hard, it has to be
               | _seamlessly_ seamless. Nim 's C interop is rarely used
               | outside of wrappers and it even more rarely is used to
               | produce C libraries (though perhaps that's more a fault
               | of incompatible type systems)
        
               | TUSF wrote:
               | With Zig, you just write something like:
               | const c = @cImport({           @cDefine("SOME_MACRO",
               | "1");           @cInclude("raylib.h");       });
               | 
               | Which translates the header files directly into Zig and
               | allows you to call into them under whatever namespace you
               | assigned them under. You even get completions (assuming
               | you're using the language server)
        
         | krupan wrote:
         | Honest question here (that I have every time I see someone talk
         | about memory safety in 2023), are you aware of Ada/Spark?
        
       | sarchertech wrote:
       | I tried Zig for a few weeks but ended up choosing Odin for a game
       | dev side project I'm working on. Odin feels a lot more high
       | level, but still gives you low level control when you need it.
        
         | 59nadir wrote:
         | I've settled on Odin as well and I think it's currently way
         | ahead for game development than Zig is. Even for other things
         | I'm currently more likely to write it in Odin, despite writing
         | Zig from 2019 to 2022. The reasons really come down to error
         | handling being better in Odin overall with payloads being
         | attachable to errors as well as the context system and zero
         | values making it relatively painless to really only talk about
         | the things that need talking about and letting the rest be
         | unsaid.
         | 
         | There are also several similarities: Custom allocators as part
         | of the ecosystem and language, no RAII, easy ways to propagate
         | and handle errors the right way, tagged unions with table
         | stakes like exhaustiveness checking.
         | 
         | I think Odin and Zig have some fundamental differences (and
         | plenty of similarities) and when trying Odin out I was
         | surprised to find that I preferred the Odin way overall.
         | 
         | For gamedev stuff Odin wins due to a few things; swizzling on a
         | code level is super nice, array programming built-in to the
         | language, vendor libraries shipped with the language that allow
         | you to just get going almost no matter what you're doing, and
         | so on.
        
           | truckerbill wrote:
           | I want to invest in Odin but I see the velocity and growing
           | mindshare that Zig has and I wonder if it's not better to
           | settle for that. Also how do you find the compile times?
        
             | Tozen wrote:
             | Part of "mindshare" are organizations pushing it on social
             | media and marketing. Choose the language that solves your
             | problems and that you like. Don't make a choice because a
             | group is telling you what to like, is bullying others
             | because they like something different, or are trying to
             | shove something down your throat for their profit or
             | benefit. Perfectly fine to have an independent mind, and
             | make decisions best for you.
        
             | 59nadir wrote:
             | I think by the time I have a massive project where compile
             | times could actually hurt the newest endeavor with
             | compiling to an intermediate form, etc., will already be
             | released so it's likely that I'll dodge that entirely.
             | 
             | For what it's worth I haven't found any language constructs
             | that seem to make the compile time grow considerably, so I
             | think the risk of adding a library and suddenly being faced
             | with massive compile times is fairly low in comparison to
             | some languages. With that said, I'm only using the core lib
             | and vendor libraries.
             | 
             | JangaFX by way of GingerBill reports that their 200kloc
             | EmberGen[0] project takes 5 seconds to compile:
             | 
             | > On my old machine, it took 5 seconds, and now it takes
             | 2.2 seconds on my new machine.
             | 
             | Before some paths in the compiler had multithreading added
             | to them that number was 15 seconds for the same project. As
             | far as I know both of these numbers are for unoptimized
             | builds, i.e. development builds.
        
             | mr_00ff00 wrote:
             | Just looked at Odin and I really like the syntax, but I
             | feel the same way. I feel like the community and ecosystem
             | is the key elements and zig seems to be headed in the
             | direction to grab that.
        
               | sarchertech wrote:
               | They're very different languages despite having some
               | similar capabilities.
               | 
               | I also found the game dev libraries in Odin far easier to
               | use then the ones in zig.
        
               | mr_00ff00 wrote:
               | Yeah I did briefly look for zig game libraries and
               | couldn't find much.
               | 
               | I see the basic differences, but I'll have to dig deeper.
        
       | parasense wrote:
       | The main take away is:
       | 
       | > Something that makes Zig harder to learn up front, but easier
       | in the long run is lack of undefined behavior.
       | 
       | Reminds me of the old discussions of Fortran Vs C, and
       | specifically in the early times before C had a standard library.
       | What we call "undefined behaviour" was just an idiom of the
       | language where the "behaviour" was sometimes on purpose, but
       | recognised might not be portable. And so the point here is the
       | idea of undefined behaviour is tied to portability on some
       | levels, and isn't just some purely academic idea about the
       | compiler or abstract syntax trees.
       | 
       | So I'm concerned about the potential over-zealous prejudice
       | against undefined behaviour, but I think we can all agree
       | deterministic software is better than otherwise. The catch is
       | that sometimes UB is deterministic, and yet dares to not be
       | idiomatic.
        
         | kps wrote:
         | C89's 'undefined behavior' was a failed attempt to say "you get
         | what the hardware gives you".
        
           | jsmith45 wrote:
           | Yeah. In hindsight for a fair bit of it, it could have been
           | sensibly changed to implementation defined behavior, or to
           | constrained unspecified behavior. (Constrained such that
           | people know what the possibilities are, but the compiler need
           | not document its choice, and might not make the same choice
           | in all circumstances. The latter could allow for scenarios
           | where letting an optimizer do the faster thing when
           | detectable, and what the hardware natively does otherwise,
           | for example. Obviously still a potential footgun, but less of
           | one than full undefined behavior).
        
           | tialaramex wrote:
           | This makes no sense because C89 is defined for execution on a
           | abstract machine, something which doesn't exist and thus has
           | no hardware.
           | 
           | Such beliefs are however compatible with the inveterate C
           | programmer excuse that their nonsense programs _should_ be
           | correct if only the standards committee, compiler vendors, OS
           | designers, and everybody else in the known universe were not
           | conspiring to defeat their clear intent.
        
             | kps wrote:
             | From the C89 Rationale, "The potential for efficient code
             | generation is one of the most important strengths of C. To
             | help ensure that no code explosion occurs for what appears
             | to be a very simple operation, many operations are defined
             | to be _how the target machine's hardware does it_ rather
             | than by a general abstract rule. An example of this
             | willingness to live with _what the machine does_ can be
             | seen in the rules that govern the widening of char objects
             | for use in expressions: whether the values of char objects
             | widen to signed or unsigned quantities typically depends on
             | which byte operation is more efficient on the target
             | machine."
        
               | tialaramex wrote:
               | > _many operations are defined_
               | 
               | My emphasis. Undefined Behaviour is not an example of
               | operations being defined.
        
         | pklausler wrote:
         | Ironically, C is now way more portable than modern Fortran is.
         | The Venn diagram of feature portability across the 6 or 7
         | actively-maintained Fortran compilers is very messy.
        
         | Symmetry wrote:
         | Assuming that bytes are 8 bits long or that negative numbers
         | are represented with two's complement is a lot less dangerous
         | these days than it was when C came along.
        
       | jasfi wrote:
       | Nim isn't hard, it just has a small community.
        
         | anta40 wrote:
         | I haven't done any production-level stuff with Nim (still
         | learning it), I think overall it's a nice language (I also like
         | Python & Pascal).
         | 
         | If your goal is applying for job, Go is obviously a better
         | pick.
        
       | michaelcampbell wrote:
       | I don't know Zig so I can't comment much on the content, but the
       | author's writing style I enjoyed immensely; enough to make me
       | want to pick up Zig for fun. I do have some C background, albeit
       | decades ago, so maybe I'm in the right spot for it.
        
       | badrabbit wrote:
       | Everything is hard when you first learn it. If you find it easy,
       | that's only because you don't have to learn part of it because
       | you learned the concept in a different language. Even learning to
       | count was hard when we were small children.
       | 
       | A better measure IMO is how long it might take _you_
       | specifically. For example, Rust is much easier for me to learn
       | than Haskell because I have never coded in a functional language
       | before. Golang was very easy to pick up on. I never took time to
       | learn python and powershell, I just kept referencing existing
       | code and googling for examples because they were both mostly
       | familiar languages with a different syntax.
        
       | thadt wrote:
       | > Crucially, there is basically no documentation for the standard
       | library except for the source code itself.
       | 
       | From the viewpoint of someone learning about a new language, I
       | find the accessibility of the standard libraries goes a long way
       | toward helping me understand how things fit together. It is a
       | first stop to see how experts in the language use it. Browsing
       | through the standard libraries of languages like Zig, Go, and
       | Python - they're usually well-documented and readable enough to
       | be a tutorial, even before you've dug into learning it. Others
       | (Rust, C++) are a bit more, ah, _technical_ for the novice.
        
         | TwentyPosts wrote:
         | Afaik Zig has the issue that basically everything happens on
         | the Discord server, where it can't be indexed via search
         | engines, or found by anyone who wants to have a quick question
         | answered. This would be "fine" if the standard library and
         | language were much better documented, but it isn't, and it's
         | still ripe with bugs.
         | 
         | In other words, you're forced to use the Zig Discord server if
         | you want to find answers to any simple questions, and this is
         | (sadly) not obvious at all to newcomers to the language.
        
           | scns wrote:
           | The new Zulip version can make chats accessible from the
           | outside. In the thread about it someone wrote OSS Projects
           | should switch to it.
        
           | girvo wrote:
           | This is true for Nim as well, in that most of the discussion
           | is on the Discord/Matrix server. I'm not a fan personally, at
           | least IRC was easily archived and searchable in practice.
           | 
           | I really dislike how Discord has become "forums in the 2020s"
        
         | Vecr wrote:
         | Rust has the standard library documentation at
         | https://doc.rust-lang.org/std/ or on your local computer, if
         | there's really nothing like that for Zig I think that's a
         | problem. Are you sure there's no `info zig` or something like
         | that?
        
           | sciolistse wrote:
           | There is https://ziglang.org/documentation/master/std but
           | it's not always been correct, and the descriptions are
           | lacking. The new one should hopefully fix that.
           | 
           | Personally I've never had an issue reading through the source
           | for zig std, and if your editor supports it you can just 'go
           | to implementation' on most things. Hopefully the code remains
           | relatively readable since I find it preferable to see the
           | actual code + some basic tests rather than trying to navigate
           | those documentation sites.
        
         | tialaramex wrote:
         | I certainly wouldn't recommend trying to figure out C++ by
         | reading either of the three major C++ standard libraries.
        
       | pron wrote:
       | > there's not a direct correlation between the slimness of a
       | language's syntax and ease of learning
       | 
       | That's absolutely true, but (the standard library aside) the
       | "syntax" -- or, rather the syntax and core semantics -- of a
       | programming language are arbitrary axiomatic rules, while
       | everything else is derivable from those axioms. So while it is
       | true that a small language can lead to a not-necessarily-easy-to-
       | learn overall programming experience, it is the only arbitrary
       | part, and so the only part you need to _memorise_ (or consult the
       | documentation for when dealing with some subtlety you may have
       | forgotten). So a smaller language reduces the need for  "language
       | lawyering" _after_ you learn it.
       | 
       | Some languages (e.g. lisps) are deceptively small by relying on
       | macros that form a "second-order" language that interacts with
       | the "first-order" language, but Zig doesn't have that. It has
       | only one language level, which is small and easy to memorise.
       | 
       | But yes, Zig is a bigger language than C, but a far smaller
       | language than C++. What's amazing, though, is that C++ is
       | strictly more expressive than C (i.e. there are programs that
       | could grow exponentially faster in C than in C++, at least
       | without the help of C macros), but Zig is as expressive as C++
       | (i.e. program sizes may differ by no more than a small constant
       | factor) while being much closer to C in size, and it achieves
       | that without the use of macros.
        
         | ImprobableTruth wrote:
         | You still have to memorize the "design patterns" that replace
         | 'missing' features. Especially annoying for something like
         | interfaces where there's a bunch of variants and people often
         | use implementations with awful error reporting reminiscent of
         | C++ templates.
         | 
         | Now, it's definitely neat that you can do reasoning from first
         | principles on it, but I'm not sure how much of a gain that is.
        
         | mannykannot wrote:
         | On the other hand, Brainfuck.
        
         | the_duke wrote:
         | I'm not a Zig expert, but I have a different take here.
         | 
         | Zig has comptime, which is essentially a compile time macro
         | written in the main language and with type reflection
         | capabilities.
         | 
         | They can introduce complex behaviour and fail in very cryptic
         | and unexpected ways, which results in an experience very
         | similar to macros or C++ template literals.
        
           | pron wrote:
           | The objects that are manipulatable by comptime are ordinary
           | program objects and types -- not ASTs. That means that while
           | it's true you can get compile-time errors in similar
           | situations to macros, the errors themselves are like ordinary
           | runtime errors in an untyped language -- while occurring at
           | compile-time, they look like runtime error in Python or JS --
           | rather than errors due to some "second-order" manipulation of
           | symbols like templates or macros, and so are easier to
           | diagnose (you get a regular stack trace for one).
           | 
           | There is also another interesting difference, albeit a
           | theoretical one. Zig's comptime is what's known in formal
           | languages to be _referentially transparent_ (it basically
           | means that you cannot distinguish between two otherwise
           | identical objects that differ only in their reference name)
           | while macros are not. Because referential transparency is
           | strictly less expressive than  "opacity" (but it's also
           | simpler!), it's surprising that so many practical use cases
           | for macros can be addressed with the less powerful (but
           | simpler and much easier to debug) comptime. That's quite a
           | discovery in language design. While other languages also have
           | comptime-like constructs, they also have other complex
           | features that have made it hard to see just how powerful
           | something like comptime _alone_ can be.
        
             | auggierose wrote:
             | It's not really surprising that purely functional
             | programming is expressive. Indeed, it is as expressive as
             | "opaque" programming.
        
               | pron wrote:
               | There's nothing pure functional here (perhaps the term
               | "referential transparency", which some FP fans have come
               | to misunderstand and perpetuate its misunderstanding is
               | what may have given you that impression). Referential
               | transparency is very much less expressive than
               | referential opacity, as there are certain statements that
               | simply cannot be expressed if your language is
               | referentially transparent. For example, in programming, a
               | referentially opaque expression can refer to the name of
               | the variable holding some value. In programming,
               | languages like Zig and Java are more referentially
               | transparent than languages like C and Haskell because the
               | latter have macros.
        
               | auggierose wrote:
               | Referentially transparent means that you can replace an
               | expression with its value without changing the meaning of
               | the program. If everything you can do must be
               | referentially transparent, then that's purely functional
               | programming, because applying functions without side-
               | effects is pretty much the only thing you can do then. Of
               | course, there are some other techniques like rewriting,
               | which strictly speaking are different from purely
               | functional programming, but I consider these two things
               | to be pretty much the same thing.
        
               | pron wrote:
               | > Referentially transparent means that you can replace an
               | expression with its value without changing the meaning of
               | the program.
               | 
               | Not quite. A referentially transparent expression (E) is
               | one where you can replace any of its subexpressions (A)
               | with another (B) that has the same _meaning_ (not
               | value!!!!) as (A) without changing the _meaning_ (not
               | value!!!) of E. However, in purely functional languages,
               | the meaning of any expression is a value, but _that 's_
               | the important thing about them, not the fact that they're
               | referentially transparent as imperative languages equally
               | are. We often use the word "semantics" or "denotation"
               | instead of "meaning" in the above, and we say that a pure
               | functional one is one that has "value semantics", i.e.
               | one where the meaning of an expression is a value.
               | 
               | Most programming languages are referentially transparent
               | when not using macros (that was the whole point of
               | talking about referential transparency in programming in
               | the first place), and that's important because it
               | demonstrates both the expressive power and the complexity
               | of macros.
        
               | norir wrote:
               | Do you have sources for your definition? The original
               | definition that I'm finding from Quine seems to broadly
               | support the interpretation that an expression is
               | referentially transparent if it can be replaced by its
               | value without altering program semantics, as others have
               | stated. Regardless, it isn't clear to me how macros are
               | any more or less referentially transparent than function
               | calls in an impure language.
        
               | pron wrote:
               | The thing that is preserved is "meaning" or "referent" --
               | the term Quine uses (hence, "reference transparency") --
               | not "value". The distinction between referent/meaning and
               | value is the most important aspect of distinguishing
               | between pure FP programming languages and others, and yet
               | that's the thing that is so commonly confused by FPers
               | using the terminology, which makes it quite pointless.
               | 
               | In most programming languages the reference or meaning of
               | a term is _not_ a value; in pure functional languages the
               | meaning is a value and _that 's_ what makes them special,
               | not their referential transparency which they share with
               | imperative languages.
               | 
               | Here's an example from C:                   int global_x
               | = 0;              void f() { x++; }         void g() {
               | x++; }
               | 
               | f and g have the same meaning in C (but the function
               | `void h() { x += 2; }` does not) yet `m(f)` and `m(g)`
               | will not have the same meaning if M is defined as:
               | #define m(x) #x
               | 
               | However, f and g are interchangeable anywhere else (this
               | is not actually true because their addresses can be
               | obtained and compared; showing that a C-like language
               | retains its referential transparency despite the
               | existence of so-called l-values was the point of what I
               | think is the first paper to introduce the notion
               | referential transparency to the study of programming
               | languages: https://github.com/papers-we-love/papers-we-
               | love/blob/main/l... You may be surprised to see that
               | Strachey also uses the word "value" but his point later
               | is that value is not what you think it is)
        
               | norir wrote:
               | Thank you. That response was clarifying. I understand now
               | what you mean. Funnily enough though, the paper you cited
               | begins:
               | 
               | "Any discussion on the foundations of computing runs into
               | severe problems right at the start. The difficulty is
               | that although we all use words such as 'name', 'value',
               | 'program', 'expression' or 'command' which we think we
               | understand, it often turns out on closer investigation
               | that in point of fact we all mean different things by
               | these words, so that communication is at best
               | precarious."
               | 
               | Rather than debating the semantics of the colloquial
               | usage of referential transparency, I'm more interested in
               | the question: what can I tell at the call site of a
               | function without knowing the definition of the function?
               | In an impure language, I cannot tell whether the call has
               | side effects without looking at the definition. This is
               | true whether I am using a macro or simply a regular
               | function call.
               | 
               | Now, even if my language of choice is impure, referential
               | transparency of expressions is still a useful concept
               | that can inform how I write my program. I can use naming,
               | for example, to suggest whether a function call may have
               | side effects even if the language compiler can't verify
               | the property. Not perfect, but better than nothing. And
               | if I'm really confused by a bug, I can always just assume
               | that the name is misleading and the function may have
               | unintentional side effects. In other words, I can use the
               | concept of referential transparency to implement a
               | metaprogramming system in my head.
        
               | whateveracct wrote:
               | I'm very sure the commenter is being a little pedantic
               | 
               | But even pedantry can't argue that Java is a
               | fundamentally more referentially transparent language
               | than Haskell lol. That threw me for a loop.
        
               | pron wrote:
               | Right, the incorrect and quite pointless common use of
               | "referential transparency" in FP fan circles tends to
               | throw people off when they first see and understand the
               | actual meaning of the term.
        
               | whateveracct wrote:
               | Well it's not pointless. The term as used in FP has a
               | pretty well-defined meaning [1] and it is a quality only
               | some programs have. And a program having that quality
               | enhances (fast-and-loose) equational reasoning.
               | 
               | [1] I can point at most Java code and prove how it fails
               | the definition. It's not especially hand-wavey.
        
               | auggierose wrote:
               | Do you have a pointer to a paper where "referentially
               | transparent" is defined in your sense? I grant you that
               | values of a programming language should be distinguished
               | from the meaning of an expression, which will be a value
               | of some sort in the logic. In that sense, _any_ language
               | with a denotational semantics will be referentially
               | transparent. So maybe what you are really saying is:
               | macros usually don 't have a denotational semantics. Not
               | sure that it is helpful to call this referential
               | transparency, because it differs from the meaning most
               | people associate with it.
        
               | whateveracct wrote:
               | Can you give me an example of a Haskell expression which
               | isn't reverentially transparent (without
               | unsafePerformIO)?
               | 
               | > An expression is called referentially transparent if it
               | can be replaced with its corresponding value (and vice-
               | versa) without changing the program's behavior.
               | 
               | ^ that is the definition of referential transparency I am
               | aware of.
               | 
               | You seem to be implying that FPers have bastardized the
               | term through their misunderstanding.
               | 
               | But the bog standard FP definition is a real and useful
               | concept. Maybe it stole something else's name? But I
               | don't think it's due to being mistaken. Because the FP
               | concept itself is pretty rigorous.
        
               | pron wrote:
               | > Can you give me an example of a Haskell expression
               | which isn't reverentially transparent (without
               | unsafePerformIO)?
               | 
               | Yes: https://github.com/ncaq/debug-trace-var The trick,
               | however, is not unsafePerformIO (destructive mutability
               | has nothing to do with referential transparency in
               | general, although it breaks it in Haskell specifically)
               | but with TemplateHaskell, as quoting has everything to do
               | with referential transparency.
               | 
               | > But the bog standard FP definition is a real and useful
               | concept.
               | 
               | Actually, it's rather tautological. It defines FP
               | circularly (see my comment here:
               | https://news.ycombinator.com/item?id=36152488). It says
               | nothing more than the far more useful explanation: "the
               | meaning of every expression is a value".
        
               | whateveracct wrote:
               | hm okay so basically anything that doesn't use TH or
               | unsafePerformIO is gonna be referentially transparent.
               | And TH is even deferentially transparent at TH-time. It
               | only "breaks it" when evaluating the whole program. But
               | each "stage" maintains the property.
               | 
               | I'm assuming any pure language with macros is also r.t.
               | at each stage and only pedantically breaks r.t. when
               | combined. But I don't think that especially hurts the
               | ability to do fast and loose reasoning so long as the
               | core language is pure.
               | 
               | It definitely doesn't seem correct to say Java is more
               | referentially transparent than Haskell here. You don't
               | have to go into such niches in Java to lose that
               | property.
        
               | pron wrote:
               | > You don't have to go into such niches in Java to lose
               | that property.
               | 
               | It's not so easy. You'd have to examine debugging
               | information in stack traces and use reflection. You can't
               | write such a "trace" operator in Java or in Zig. Of
               | course, without macros, C is almost perfectly
               | referentially transparent and Haskell is, too (except for
               | unsafePerformIO).
        
               | whateveracct wrote:
               | You can also mutate a list that is passed in and suddenly
               | you cannot do substitution to reason about your program.
        
             | norir wrote:
             | > Zig's comptime is what's known in formal languages to be
             | referentially transparent (it basically means that you
             | cannot distinguish between two otherwise identical objects
             | that differ only in their reference name) while macros are
             | not.
             | 
             | In general this is true, but it is possible to write a
             | hygienic macro engine that is referentially transparent.
             | Many (likely most) macro engines are indeed unhygienic
             | though. I am not convinced that comptime is a better
             | approach than a well designed hygienic macro system but it
             | is an interesting research area.
        
             | Symmetry wrote:
             | I haven't had a chance to play with comptime in Zig yet but
             | I'm sort of curious how it compares to Nim's compile time
             | facilities. You can declare variables with 'var' for true
             | variables, 'let' for things that are runtime constant
             | within a scope, or 'const' for compile time constants whose
             | values can come from functions or whatever as long as it
             | can be resolved by the compiler. And then you've got 'when'
             | as a compile time equivalent of 'if'.
        
               | [deleted]
        
         | distcs wrote:
         | > Some languages (e.g. lisps) are deceptively small by relying
         | on macros that form a "second-order" language that interacts
         | with the "first-order" language, but Zig doesn't have that.
         | 
         | What are some other examples of such languages that rely on
         | second-order languages? You mentioned Lisps. Would Forth be
         | another example? Are there more examples?
        
           | spenczar5 wrote:
           | I think Ruby is sometimes used in a way that looks second-
           | order. It allows so much metaprogramming that you can really
           | make a full DSL. For example, RSpec:
           | describe "order" do          it "is marked as complete" do
           | expect(@order).to be_complete          end               it
           | "is not yet shipped" do            expect(@order).not_to
           | be_shipped          end        end
        
           | pron wrote:
           | C++ templates. Also the rich type-level language in languages
           | like Idris (these are qualitatively different, but I'd say
           | they're another example of a second-language-within-a-
           | language that operates at a different level of objects).
        
             | ImprobableTruth wrote:
             | If type level functions are a "second language", then so is
             | Zig's comptime.
        
               | pron wrote:
               | It's not. comptime reifies types as regular objects
               | (pretty much like maps), so you're not working at the
               | type level; it's no more of a second language than
               | reflection in Java. Of course, you cannot express things
               | like the famous vector concatenation that's expressible
               | with dependent types
               | (https://gist.github.com/cbiffle/82d15e015ab1191b73c3)
               | (unless the vector sizes are known at compile time,
               | obviously).
        
       | KingLancelot wrote:
       | [dead]
        
       | ok123456 wrote:
       | One annoying thing I ran into when trying zig is they don't
       | distribute debs any more for Debian distributions. They just tell
       | you to use a snap. I don't have snap, and don't want it.
       | 
       | Compiling it requires the latest llvm toolchian (16), which is
       | only realistically going to be available as a package if you're
       | on a bleeding edge distribution.
        
         | pacaro wrote:
         | I understand this, but haven't found this to be an issue
         | personally. I just download the pre built tarball, expand it,
         | make sure that /opt/zig-latest symlinks to the right folder,
         | and setup path
         | 
         | That's more work than apt-get install for sure, but not so much
         | more
        
           | hellcow wrote:
           | You can also use something like zigup to make fetching the
           | latest master/managing multiple versions easier.
        
         | eatonphil wrote:
         | What's wrong with downloading the binary? curl + mv + chown
         | should do it?
        
         | netule wrote:
         | Zig's in the process of getting added to the mainline Debian
         | repositories: https://bugs.debian.org/cgi-
         | bin/bugreport.cgi?bug=995670
         | 
         | Hopefully, this process will continue soon as the bug seems to
         | be getting a bit stale.
        
       | stared wrote:
       | What are the use-cases in which it might be worth switching from
       | Rust to Zig?
        
         | epage wrote:
         | matklad, of rust-analyzer fame among many other things, wrote
         | up their thoughts on Zig:
         | https://matklad.github.io/2023/03/26/zig-and-rust.html
         | 
         | I've seen some put it as "zig is good when `unsafe` heavy
         | code".
         | 
         | Personally, even when writing life-or-death software,
         | allocation errors were too much of a pain to deal with and much
         | prefer Rust's approach for 99% of software. The question is if
         | another language like zig provides enough value to justify
         | existing for that 1% of use cases (all numbers made up :) ).
        
         | logicchains wrote:
         | When you need to be very careful about memory allocation and
         | use various custom allocators for stuff, and you don't care too
         | much about memory safety. Rust makes working with custom
         | allocators somewhat painful, in exchange for safety, so if you
         | don't need the safety, no point going through that pain.
        
           | notfed wrote:
           | What kinds of programs don't care about memory safety?
        
       ___________________________________________________________________
       (page generated 2023-06-01 23:00 UTC)