Now Reading
A Zig Diary

A Zig Diary

2023-01-09 05:54:55

Because it turned out I occurred to assist out with fixing an area to host a zig meetup right here in Stockholm on the place the place I work. Nevertheless I haven’t written a single line of zig in my life… I felt that it could be price doing one thing about that 😀

In the event you don’t know, zig is a brand new programs programming language!

I’ve discovered zig fairly intriguing for some time now however I haven’t had the time to look into it so this gave the impression of an pretty much as good excuse as any!
I’ll strive one thing new with this submit and simply write as I am going and doc my success/failure/reflections, this may make it a bit “rambly” 🙂

First off, I wanted to determine on what to try to construct simply to have a purpose and never simply do some aimless “twatting about”, one thing small however that also produce one thing. I made a decision on a easy picture to ascii converter. There are a large number of those round that may most likely be higher than this one however who cares!

I made a decision on this as its small, does a little bit of io, does a little bit of command-line, a little bit of “algorithm work” and possibly some c-interop, and it may most likely be optimized a bit if I wish to.

Lets go!

I wanted to get one thing constructing! The primary intuition mentioned “Let’s hit google and seek for ‘zig how to get started’”.

5 minutes later I had the compiler and toolchain put in, initialized my undertaking and have one thing working… spectacular!

A bit extra information could be attention-grabbing to you readers! So my google search turned up https://ziglang.org/learn/getting-started/ as the primary outcome, that in turns pointed me to the downloads page.
As I’m on ubuntu I made a decision to do the ‘snap’ set up by way of:

snap set up zig –traditional –edge

After this the getting began web page instructed me about zig init-exe and zig construct run and I used to be off to the races!

Can’t write code with no respectable enhancing atmosphere, so let’s see what we are able to do about that?

I do know that the “getting began” web page discuss this, however vscode as I take advantage of as an editor at dwelling already factors me to {the marketplace}, lets begin there.

Putting in “Zig” and “Zig Language Server (zis) for VSCode” and lets see what occurs!

One other 5 min and syntax is highlighting and a few rudimentary auto-completion is in place!

Studying the preliminary generated predominant.zig, clear and concise however quick. Good that there’s a check embedded within the generated code as effectively. I’ve by no means been a fan of getting checks and implementation in the identical file however we’ll see how that seems, particularly since testing appears builtin to the language. I suppose there may be nothing that power me to have the check in the identical file as implementation?

Attempting to uncomment the .deinit() within the check to see what occurs.

    var record = std.ArrayList(i32).init(std.testing.allocator);
    // defer record.deinit(); // strive commenting this out and see if zig detects the reminiscence leak!
    strive record.append(42);
    strive std.testing.expectEqual(@as(i32, 42), record.pop());

Good to get an early introduction to memory-handling this early, in any other case it may need come as a shock. I’m normally a fan of handbook memory-management but in addition working in c++ all day lengthy at work may make this one thing to get used to. Additionally what are these strive-statements, defer I get (and like!), however strive is a bit unclear, may need been good with a little bit of clarification immediately within the generated file? Only a fast remark like:

    // including a 'strive' right here will do x/y/z.
    // Learn extra at 'https://ziglearn.org/chapter-1/#errors'

So, what’s the very first thing that I want? I’ll must learn an information from stdin and or by way of an -i-flag. First I believed that I ought to use some lib, however I’m studying zig now, simply do the only factor you may your self on this easy case!

So getting argc/argv? A number of questions and reflections popped up.

Debug-printing one thing and getting this callstack is sort of dangerous, certain it tells me what’s improper but it surely provides me an error within the standard-lib and never in my code the place I launched the problem. It additionally hides my line from the hint, so I can’t even see the road the place I launched the error!

Not less than it mentions -freference-trace, however as a consumer this won’t be what I would like 🙂

wc-duck@WcLaptop:~/kod/zig_img_to_ascii$ zig construct run
/snap/zig/6044/lib/std/fmt.zig:86:9: error: anticipated tuple or struct argument, discovered [:0]const u8
        @compileError("anticipated tuple or struct argument, discovered " ++ @typeName(ArgsType));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    print__anon_4373: /snap/zig/6044/lib/std/io/author.zig:28:27
    print__anon_3784: /snap/zig/6044/lib/std/debug.zig:93:21
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

Problem introducing this was simply me getting used to “c” for a very long time and writing:

std.debug.print("{s}n", arg);

and never:

std.debug.print("{s}n", .{arg});

This line is an important factor to me as a consumer, therefore it must be talked about within the precise error!

Subsequent up, can I run zig construct run with command line args? Couldn’t discover something within the big zig --help. Additionally tried to do one thing as zig run assist to only get assistance on run however no. After a little bit of guessing I discovered that zig construct run -- --arg --go --here works and move all args after -- to your app. Not likely sudden as it’s sort of a identified idiom , but in addition not documented… so far as I can inform?

std.debug.print() requires args and cannot simply print a string… sudden. Forcing a .{} isn’t actually ergonomic 🙁

std.debug.print("I simply need some outputn", .{}); // :(

Evaluating strings threw me, as many others it appears, off as there aren’t any customary manner doing it… having to outline your individual streq() appears a bit extreme as it’s not an unprecedented operation!

fn streq(comptime s1 : []const u8, s2 : []const u8 ) bool {
    return std.mem.eql(u8, s1, s2);
}

Positive, that’s only a wrapper round std.mem.eql(), evaluating strings is way from trivial if you’re to do it “accurately” and so on…

On the time of penning this submit I discovered that there’s the std.ascii module, however that wouldn’t have a easy .eql(), solely .eqlIgnoreCase(). I suppose that comes from “there must be one, and just one manner, of doing one factor” and std.mem.eql() already exists however I’d argue that that’s taking it a bit to far. From my viewpoint an std.ascii.eql(s1, s2) would supply extra readability on the callsite + making it simpler to find different “ascii”-functions and so on.

However after some ‘faffing about’, commandline is parsing, most likely actually badly 🙂

const CmdLineArgs = struct {
    enter: ?[]const u8 = null,
};

fn parse_args(alloc : std.mem.Allocator) CmdLineArgs
{
    var args = strive std.course of.argsWithAllocator(alloc);

    // skip my very own exe identify
    _ = args.skip();

    var out = CmdLineArgs{};

    whereas(args.subsequent()) |arg| {
        if(streq("--input", arg) or streq("-i", arg)) {
            out.enter = args.subsequent();
        }
        else if(streq("--help", arg) or streq("-h", arg)) {
            std.debug.print("HEEELPn", .{});
        }
        else{
            std.debug.print("unknown arg {s}n", .{arg});
        }
    }

    return out;
}

Time to load a source-image, and as this isn’t an train in writing an image-loader and zig prides itself with c-interop, lets drop stb_image.h in there and get that working!

This truly turned out a bit tougher than anticipated, principally resulting from how stb_image.h is applied with having to outline STB_IMAGE_IMPLEMENTATION. This pressured me so as to add an stb_image.c that simply embody stb_image.h and set the outline.

This lead me down into the zig-buildsystem and construct.zig and add this… fairly smooth!

    exe.addCSourceFile("src/stb_image.c", &[_][]const u8{"-std=c99"});
    exe.addIncludePath("src");
    exe.linkLibC();

However how did I learn the way to do that, it principally took googling “stb_image zig” and ending up with Andrew:s tetris-implementation on github. Possibly not the perfect and clearest documented factor. On the different hand you most likely shouldn’t must formally “doc” use a selected lib from zig 😀

Nevertheless a brief blog-post about it, and solely it, can be helpful… perhaps for kihlander.net?

Left the undertaking for a couple of days…

Sadly my note-taking was, to place it mildly, “missing” below the precise implementation of the to-ascii work. However it’s principally a couple of loops and I’m fairly certain that you’ll find higher assets on convert a picture to ascii that this weblog 🙂

Briefly, convert picture to grayscale, use common in a block of x*x pixels to map into record of character.

However I do have “The king of all cosmos” as ascii “artwork” a minimum of 🙂

Turning this:

Into this:

.......;:.........;x:,oo..:%;.;o,................ 
..................o%;,%x,.:%o.o%:.................
..................;x:,oo,.:x;,;x:.................
..................:o,,::,,,o,,:o...........,,.....
..................;%:,xo,,:%;,o%,..........:,.....
.................,;x;:%%;,opercento:ox:.................
.................,oxoo%#o:%%%;%x:,................
..........,.....,,oopercentx%#%x##xxxo;,...........,,...
.........,;,....,,xxoo%#@@@#xooxo,..........,;;...
........:oo;,...,:xxoo%#@@##xooxx,.........,;oo:..
........,;o;,..,,;xooo%#@@##xooxx,,.........:;;,..
,.,....,.:;,..,,,;xooo%#@@##xooxx,,,.........:,...
,,,,,,,,,,,,,,,,,oxxoo%#@@##xooxx:,,,,,,,,,,,,,,,,
;;;;:;;;;;::;;:;;xxooo%%###%xooox;::::::::::;:::::
;;oo;;oo;;;;;;;;;;oo;;;;ox;;;;;oo:;;;;;;;;;;o;;;;;
ooooo;oo;;;;;;;;;:x#%xo;ox;;ox%%o:;;;;;;;;;oo;;ooo
oopercentxoooo;;;;;;;;:;%###%xoxox%%##x:;;;;;;;;;oo;;oxo
ooxoooooxxxxxxxo:o####%%%%%%%###%o;xxooooxxoo;ooxo
ooooooox#######x;xxxooooxxoooooxxx:x%%%%%%%xoo;ooo
ooooooxxxxxxxxxo;;::,,:::;;::,,:;;:xxxxxxxxxxooooo
ooooxxoooooooooo;:::,,,:;o;:,,,:,;:ooooooooooooooo
xxxxxooooooooooooo;;::;;xpercento;:::;;o;ooooooooooooxoo
xxxxxxoooooooxo:x%%xooxxxxxxooox%%o;oooooooooooxoo
%xxxxxxxxxxxxxo;x%%%%%%oxxxx%%%%%%x:oxxxxxxxxxxxoo
#xxx%@@@@@@@@#oo%##%%%xoxxxox%%%%%%;x@@@@@@@@@%xox
%xx%%%#@@@@@@%:o%##%%%xxxxxoxx%%##%o;#@@@@@@#%%xxx
xxx%%%%%%%%%%o:x%%%%xxoxxxxooxx%%%xo:o%%%%%%%xxxxo
xxxxxxxpercentxxxxx;:xxxxxxooxxoxxoxxxxxxo,oxxxxxpercentxxooox
xxxxxxxxxxxxx;:ooooooooxo;oxooooooo;,;xoooxxxooooo
xxx%%xoxxxxxx;,;;;;o;ooo;;;oo;;;;;;;,oxxxxxoooxpercentxo
ox%#%xoox%@@#;,;;;;;;;::::,::;;;;;;:.o####xooo%#%o
oo%@#xoox%@@#:.:;;:;:,...,...,:;,;;:.;@@@#oooo%@%o
ooxxxo;ooxxxx:.:;;:,,:;;,,,;;:,,:;;,.;xxxxo;;oxxxo
;;;oo;;oooooo,.,:;:.:o;:...:;o:.:;:, :oo;;;;;;;;;;
;;;;;;;;;;:;;. .::;:;;.,,,,,,;;:;::. ,;;:::;;;;;;;
:::;;;;;;;;;;. .,::;,:;ooooo:,::::.. ,;;:;:;;;::::
:::;;;;ooooo;    ..::,,,,,,,,:::..   .;o;;;;;;;;::
;:::;oxxxxxx;     ,;::,....,,:::.     ;xoooooo::::
;::::;;;;;;;:     ,:;;::,,:::;;:.     :::;;::;::,,
:,,:::::,,,:,     ,:;oo:. .;oo;:.     ::,,,,,,::,,
,,,::,,,,,,,,,    ,:;xx;, :oxo;:.    ,,,,,,,,,,,,,
,,,,,,,,,,,,,,,.  .,:;;;: :;;;:,.  .,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,  .,,,,, ,,,,,.  ,,,,,,,,,,,,,,,,
,,,:::;;oxxo;::::, ...... .......,::::;oxoo;:::,,,
ooxx%%%#@@@%oxx%%x;.....  .....,;x%%xxo#@@@#%%xxoo
@@@@@@@@@####@@@@@x:,..,:::, .,;%@@@@######@@@@@@@
@@@@@@@@@@@@@@@@@#%o;,;x###x;,;o%#@@@@@@@@@######@
@@@@@@@@@@@@@@@@#%xo;x#@@@@@%o;ox%##@@@@@@@@@@@@@#
%x%#@@@@@@@@@@@#%%xo;%@@@@@@@x;ox%%##@@@@@@@@@@%%x
xoox%@@@@@@@@@##%xxox##%xxx%@#o;ox%######@@@@@%ooo

Ugly ascii artwork sure… however nonetheless! And the code is as crapy as ever!

It appears higher in my terminal 😀 However I believe it comes right down to tweaking the “alphabet” used, deciding what number of chars to make use of in width and so on. Nothing actually attention-grabbing for this submit.

Time for a couple of reflections and conclusions.

First off all, zig don’t really feel prepared for “primetime” for me however I do really feel that it has a promising future. It has many good concepts that sit proper with me and appears effectively suited to the sort of work that I normally do. However would I recommend our crew to go “all out zig” at the moment… hell no!

The great

Good defaults

I just like the defaults in terms of how the language is designed and the way the builds are setup with Debug/ReleaseSafe/ReleaseSmall/ReleaseFast.

Reminiscence allocation is specific

As somebody that has been coding c and c++ on this manner for a very long time (or a minimum of tried to advocate for this fashion) it really feel proper at dwelling having this builtin to the language with the instruments wanted to make it pretty streamlined.
Forcing the consumer to take accountability for reminiscence is an efficient factor. However that can be mentioned as a “programs programmer”, who’s accountability it’s to consider these sort of issues every day. Would it not go over as effectively with one in all my faculties working in gameplay the place iteration time is of an essence when prototyping issues and design can change, radically, from hour to hour? In all probability not?

comptime appears like a robust paradigm

comptime feels highly effective. With the ability to not have to make use of a “particular” language corresponding to templates on your generic code, I like that! It feels clear and simple to learn and perceive. However how is it to debug? As it’s “simply zig”, may there be some sort of particular construct or perhaps a method to step via and consider generic code in a debugger?
This might be such a robust function, to have the ability to use your day-to-day debugger to debug your compile-time evaluated code!

Construct System

Simple to get going and builtin as a firstclass a part of the language. Not being an afterthought.

This labored rather well for me on my small test-project and I suppose it might work rather well for larger tasks as effectively. However how would it not scale to actually massive code-bases, particularly with plenty of customized construct steps ( you Apex-engine, you!), that’s to be seen?

Attempting to “work effectively with” c as a substitute of changing c!

I actually like that zig is attempting to work with the present panorama that’s already there as a substitute of attempting to exchange it from the bottom up. There’s simply a lot nice and effectively established libraries and instruments on the market already. Making it straightforward to work together with these as a substitute of attempting to exchange them appears like the precise option to me.

Issues like zlib, curl and sqlite will most likely not be re-written any time quickly!

The dangerous

Compile occasions.

The compile occasions are removed from “good”, to place it politely 🙁 And this only for a small commandline app that might most likely compile in non-noticeable time in c. Throwing a giant undertaking on this is able to most likely not be sustainable immediately.

time to construct, clear (no ./zig-cache and ./zig-out) on my machine:

actual 0m11,741s

consumer 0m8,777s

See Also

sys 0m5,789s

YAUSA!!!

time to construct, small replace to ‘predominant.zig’ on my machine:

actual 0m1,074s

consumer 0m0,953s

sys 0m0,183s

… for such a small change, not likely “stellar” 🙁

I do know that that is being labored upon and with the brand new self-hosted compiler it has grow to be (in accordance with “the interwebs”) so much higher however im undecided how far you may take it?

With all comptime and so on it is going to be an issue to get it quick. The computations should be accomplished regardless and the extra calculations that needs to be accomplished compile-time the costlier it is going to be! However I’ll be comfortable to be confirmed improper and it’s definitively potential that it could get to an honest state!

@compileError, I don’t need errors down within the stdlib!

Getting errors deep down within the stdlib once I made an error in my very own code isn’t actually good. See the error mentioned above on sending invalid parameters to std.debug.print() and getting the error deep down within the stdlib.

Easy methods to handle this, I don’t know. This is identical drawback as static_assert() and template-errors in c++. Nevertheless zig ought to have the ability to leverage that it has correct modules as a substitute of glorified copy-paste that’s c-includes 🙂

I do see @compileError as a very good paradigm, however with out this drawback solved it appears like it’ll find yourself because the c++-style wall-of-text that it’s important to decipher with the intention to discover the actual error you made.

Hopefully that is a minimum of seen as an issue by the zig-community and there ought to a minimum of be issues that may be accomplished to make it much less painful?

Please give me a method to iterate over an integer vary!!!

ARGH! The loops over a spread of integers!

var block_h: u32 = 0;
whereas (block_h < block_cnt_h) : (block_h += 1) {
    var block_w: u32 = 0;
    whereas (block_w < block_cnt_w) : (block_w += 1) {
    }
}

If I had a swedish “krona” for every bug this launched throughout my quick time with zig I’d most likely have the ability to afford a very low-cost cup of “snut-kaffe” (cop espresso in swedish). This was actually cumbersome to make use of and much from good. Actually clunky!

Nevertheless on the meetup I received to ask Loris Cro about this and received the reply that that is going to be addressed sooner or later, see https://kristoff.it/blog/zig-self-hosted-now-what/ below “New for loop syntax”! That one appear fairly good and can hopefully take away this gripe of mine sooner or later!

I suppose this, once more, comes right down to “there must be one, and just one manner, of doing one factor” and in idea I discover that to be a valiant purpose however when it will get in the way in which of ergonomics like this it’s removed from good. Nevertheless because it appears as whether it is being addressed, the principle builders appear open to alter if it might actually profit the language as on this case! And it’s at all times simpler to provide a small function than take away one thing that turned out to be a mistake, so it’s most likely an excellent factor that options is simply not thrown in there if they aren’t confirmed to be wanted!

Native features

Nope, not there. This tripped me up a bit. That is truthfully nothing main however personally I’ve began utilizing native features increasingly and I believe they make my code less complicated and cleaner over all. I do know that there was discussions within the zig-community about it however I haven’t tried to seek out what the conclusions has been.

Documentation is nice… the documentation that’s there that’s!

Yeah… the documentation. It’s good! When you’ll find it and it exists 🙁 Often you find yourself in some weblog, some github situation or related. However zig is a younger language, it’s not that sudden that documentation is missing at this time limit!

The ugly

Nonetheless preventing the syntax

I’m nonetheless preventing the syntax. My 20 years of writing c and c++ journeys me up on a regular basis. This nonetheless I suppose is extra on me than the precise syntax… perhaps? There are numerous utilization of single characters like _, !, ?, : that make the code terse, however is kind of the hurdle when you’re new to the language.

However thanks for not utilizing the dreaded backtick (`) for something!!! Please go google “backtick scandinavian keyboard” for some “opinions” from us up north!

the popular, idiomatic, format 🙂

Once more that is only a alternative that’s neither good or dangerous, only a alternative… that I’d not have made! I don’t prefer it, however as it’s a matter of style it’s sort of foolish to complain about as nobody will ever show the opposite proper as there is no such thing as a proper/improper ( besides in terms of space-vs-tab and snake_case_being_the_way_god_intended() 😉 )!

So the place do that take me? I’ll nonetheless regulate zig and its improvement. Will it grow to be my major language of alternative? Not but, however perhaps sometime. I actually hope/suppose that zig has a future and we are going to see extra of it.

If nothing else and zig simply disappears some day (unlikely!) it is going to a minimum of have introduced attention-grabbing concepts to the programming world and proved/disproven that they work and what they will convey to the desk!

I do suppose that I’ll maintain fidgeting with zig sooner or later. I’ve had some thought going like “everybody has to have written an NES-emulator of their life proper?”, and perhaps it might be price doing that in zig only for the enjoyable of it?

I’m additionally intrigued about attempting out zig as a buildsystem for my information serialization library (all of us received one proper?) “datalibrary” and see how that seems!

Ultimately… this was sort of enjoyable, would do once more! And right here, lastly is a hyperlink to the crappy supply for the img-to-ascii converter!

https://github.com/wc-duck/zig_img_to_ascii

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top