[HN Gopher] Zig Pathtracer
       ___________________________________________________________________
        
       Zig Pathtracer
        
       Author : ibobev
       Score  : 76 points
       Date   : 2021-08-09 10:39 UTC (12 hours ago)
        
 (HTM) web link (msinilo.pl)
 (TXT) w3m dump (msinilo.pl)
        
       | pron wrote:
       | > taking it for what it was - a modern "C+" alternative
       | 
       | Andrew Kelley, Zig's designer, presents Zig as an alternative to
       | C because it can replace C where it is used, but even though C
       | served as a conceptual starting point in the language's design
       | process, comparing _the language itself_ to C (or  "C+"), as
       | opposed to C++, doesn't quite capture the language's design and
       | feel.
       | 
       | Superficially, what makes Zig feel "slim" compared to C++ is that
       | 1. it disallows any kind of name overloading (and, so, in
       | particular operator overloading) -- any (namespaced) name in a
       | Zig program can refer to only one definition -- and 2. it is a
       | very simple language that can be fully picked up in a day or two
       | by anyone with experience in any low-level language (C, C++,
       | Rust, or Ada). But Zig is both safer _and more expressive_ than
       | C++; any  "rich" C++ construct that makes clever use of, say,
       | templates, can be expressed in Zig and more easily, thanks to
       | Zig's comptime and introspection, and much more. It is no
       | coincidence that programs are short in comparison to other low-
       | level languages. It's not that the language is terse, but that
       | its simple constructs are powerful, similar to how Lisps can be
       | simple yet expressive, although Zig's comptime + introspection
       | replaces Lisp's macros as the "power feature" (and comptime +
       | introspection is easier to read and write than macros). So while
       | the language shares some basic primitives with all low-level
       | languages, like precise control over data representation, it
       | doesn't feel like any other language.
       | 
       | I see Zig as an entirely new, and quite revolutionary approach to
       | low-level programming, that doesn't follow any design tradition
       | in that space, neither C's sparseness nor C++/Ada/Rust's
       | linguistic richness. It is something new altogether.
       | 
       | Different languages appeal to different people based on their
       | aesthetic preferences and priorities (e.g. C++ and Rust
       | prioritise the code appearing as if written in a high-level
       | language when read on the page, while Zig prioritises
       | explicitness and compilation times), and surely some developers
       | would prefer C++ or Rust to Zig, just as surely as others would
       | prefer Zig, but to understand what Zig is, it has to be
       | experienced, because it really is hard to compare to anything
       | else. Thankfully, being so simple and easy to learn, experiencing
       | it requires very little investment. You may find it a promising
       | prospect for any low-level programming task, regardless of
       | whether it would have otherwise suited C or C++. It can replace
       | C++ just as much as C, and even C++ developers would find it
       | compares very favourably when it comes to expressive power.
        
       | smusamashah wrote:
       | That 99 line cpp path tracer linked in the post isn't really 99
       | lines. It's minified C++. If expanded to a more readable version
       | it will probably be around ~250 lines. Still not too big but
       | definitely not 99.
        
       | abainbridge wrote:
       | I have great hope for Zig. I agree with Andrew Kelley on most of
       | the design decisions I've paid attention to.
       | 
       | >for loop can only be used to iterate over elements of an array,
       | if you want to just execute a block N times, you need while...
       | 
       | The Zig docs suggest something like this:                   var
       | i: usize = 0;         while (i < 10) {             i += 1;
       | }
       | 
       | Is there a plan to provide a mechanism to stop "i" from remaining
       | in scope after the end of the loop? I couldn't find anything
       | relevant with a quick web search.
       | 
       | I use integer iterating for-loops a lot in C. I just checked a
       | 5000 line project of mine that deals with bitmaps. There are 100
       | occurrences of something like:                   for (int i = 0;
       | i < 10; i++) {
       | 
       | I think these would all become while-loops in Zig. Exposing 100
       | variables to a larger scope than they need to be sounds like a
       | source of bugs to me.
        
         | canadaduane wrote:
         | I'm new to Zig but I think this is how you would do it:
         | {             var i: usize = 0;             while (i < 10) : (i
         | += 1) {                 // use i             }         }
        
           | tored wrote:
           | Looks like a solution, a bit annoying to introduce an extra
           | block.
        
             | abainbridge wrote:
             | Yeah. And it fails the "make the easy way the right way"
             | test of language design.
        
               | dnautics wrote:
               | I give a c-like for loop (or while loop) a 40% odds of
               | making it into the language. That number being pulled out
               | of my nether regions.
        
         | hota_mazi wrote:
         | Of all the syntaxes I've seen to do this, I like Kotlin's best:
         | repeat(10) {             println("Counter is $it")         }
         | 
         | Kotlin optimizes nicely for the most default case while giving
         | you flexibility if you need it (different parameter name, step,
         | etc...).
        
           | Zababa wrote:
           | That looks way better than the while or for loop you usually
           | see. Maybe this could be done in Zig as a comptime function?
        
         | hiccuphippo wrote:
         | As a hack, you can use an array of u0 to make simple loops:
         | for ([1]u0{0} ** 10) |_, i| {
         | std.debug.print("{d}", .{i});         }
        
           | suby wrote:
           | Is there a performance penalty for this?
        
             | dnautics wrote:
             | see for yourself:
             | 
             | https://godbolt.org/z/Mj9T7vP44
        
           | tored wrote:
           | Not a Zig programmer, but that looks horrible.
        
             | AnIdiotOnTheNet wrote:
             | Yeah, it's a hack.
             | 
             | If you're doing it a lot you can abstract it into a
             | function to clean it up:                   fn
             | count(comptime n: usize) [n]u0 {             return
             | [1]u0{0} ** n;         }              for (count(10)) |_,
             | i| {             std.debug.print("{d}", .{i});         }
             | 
             | or, if you don't need to capture the index:
             | for (count(9)) |_| {             //I can do it 9 times
             | }
             | 
             | Personally I've found I rarely need this kind of loop, so I
             | just use the 'while' formulation because it is more
             | obvious.
        
               | dnautics wrote:
               | Hah! i thought it was not a hack so much as a 'joke' that
               | someone had discovered and posted to the discord, to much
               | amusement. Are people actually using this?
               | 
               | I will be amused when std.math.range shows up with this
               | implementation.
        
         | ncmncm wrote:
         | There is of course                 { var i: usize = 0; while (i
         | != 10) : (i += 1) {            ...       }}
         | 
         | I.e., you are not obliged to paste on a newline after every
         | semicolon. It is about as busy as the equivalent C++ loop, but
         | syntax is syntax. What you probably would be better off with
         | instead is a function that takes a lambda, and pass the body as
         | a lambda. In C++, that would look like
         | forloop(10, [&](auto i) {         . . .       });
         | 
         | I can't find anything to suggest Zig has lambdas. That's a
         | planet-sized hole, nowadays.
        
       | AnIdiotOnTheNet wrote:
       | > feel like compiler could use some more strict warnings, too
       | 
       | Warnings in Zig are called 'compiler errors'. Which is to say,
       | Zig doesn't do warnings. If the compiler thinks there is a
       | problem, you _must_ fix it. Usually you 've made a mistake, but
       | sometimes you just need to be explicit about what you want to
       | happen. In this particular case I believe there is an issue
       | raised about it, but I couldn't find it on github.
       | 
       | > Zig float literals have type comptime_float, which is
       | essentially the largest type, ie. f128. To use a different type
       | you have to cast it first and I'm not loving the syntax: [...]
       | 
       | > It is also a bit inconsistent, as some functions (like pow)
       | will take a type parameter and allow for comptime params: [...]
       | 
       | Yes, this is an inconsistency in the standard library that hasn't
       | yet been addressed as Zig currently doesn't place a high priority
       | on polishing the standard library.
        
       ___________________________________________________________________
       (page generated 2021-08-09 23:02 UTC)