#Please help me understand Zig, I am trying to not use AI

1 messages · Page 2 of 1

formal tulip
#

Wait, are you trying to make an emulator or run something on te gameboy

onyx widget
#

^

stone jewel
#

if this tests exists somewhere you should run it as a rom

onyx widget
#

I'm talking about your code

compact sage
#

the original one has a lot of forbidden regions/ mirrored regions, etc etc

onyx widget
#

show me a snippet of your code

#

what is the dang difference

compact sage
#

rn there isnt any difference, once I start implementing more it will break

onyx widget
#

the read methods are the same. the write methods are the same

#

what is diff

#

is it the values in bytes that will be diff?

compact sage
formal tulip
#

Also, considering that the gameboy is in a different arch, why are you attempting to directly map its memory space to x86_64's memory space?

compact sage
stone jewel
#

The true validation on an emulator are test roms imo
I do that for my NES emulator

onyx widget
#

nbd

compact sage
formal tulip
#

Wait, I think I understand what is going on now

compact sage
#

I cant test test roms until i have implemented more stuff

onyx widget
#

you can add it as test-only method to the struct, or you can just do it manually in the test - no private fields, take advantage :P

formal tulip
#

Yeah, there is no reason to test the emulator under a fake condition

#

It just makes the test unreliable

onyx widget
#

you bigly overthinking it

compact sage
compact sage
formal tulip
#

At best, it is not useful, at worst, it drives bad design decisions

formal tulip
compact sage
#

it is

#

i am trying to verify whether the cpu implemntation is working or not

#

not how it interacts with the rest of the system

onyx widget
stone jewel
#

I agree it isn't, but you can only test it with real program imo
You are emulating, you don't really have the memory mock issue

onyx widget
#

is it stored in the mocked memory itself, or in the emulated hardware?

onyx widget
#

I am talking about the design of your program

#

I understand emulators, I am trying to understand what you are doing

#

because the problems you are describing don't make sense to me

compact sage
onyx widget
#

then why can't just do that for the real virtual mem structure

stone jewel
#

Nothing stops you to use prohibited regions if no one uses it for nothing btw
You can not emulate them (Wrong) or emulate them and have UB behaviour (Kinda ok) or search what happened in games on that region

formal tulip
#

It may very well be the case that certain memory accesses correspond to different CPU behaviours

compact sage
#

my problem is simple:

  • I have a component A which has a dependency B
  • I need to mock the internals of dependency B for a specific test of A
    That is all I need
formal tulip
#

In an arch such as the Gameboy's, this would make sense

stone jewel
#

Why would you separate them

compact sage
#

talking about gameboy specific stuff or my emulator design is not the goal

stone jewel
#

is my question

formal tulip
#

As the whole system is very closely tied together

stone jewel
#

We generally don't like X Y questions =(

#

Because at hand here is a bigger issue

#

Why you need to mock them

#

It is not clear

#

Note, I have also written emulators, and I develop for the gba for fun

formal tulip
#

Anyways, you are designing an emulator, not a hardware component. Treating things as independent from each other is an unnecessary goal

compact sage
stone jewel
#

Why?

compact sage
#

the test requires it

formal tulip
stone jewel
#

Feels like outside the point

formal tulip
compact sage
#

can i do this in zig or not?

stone jewel
#

The test might require whatever, just skip the test, test yourself the same assumption if you want static guardrails

#

the answer is yes, but we see at as pointless

onyx widget
#

or make it a runtime vtable

#

pick yer poison

formal tulip
onyx widget
#

to be clear, that is how "mocking" works in all languages

compact sage
#

I cant skip the test

compact sage
stone jewel
#

This vtable would have minimal runtime perf hits

onyx widget
#

a mock is just a way to inject some code that does something differently. all other languages do this using things like interfaces, vtables, generics, w/e. zig does not do these in as "pretty" ways, so it's going to look as shitass as it is

stone jewel
#

but the better way is rewrite the test to your constraints

#

Or make CPU truly separate from memory and Create the Test Suite with Custom Memory types

#

But this is gonna make you write specific code as a handler for the CPU test

compact sage
#

making the cpu separate from memory like passing it explicitly everywhere?

stone jewel
#

And you will miss integration issues later on if you don't test those

#

Not necesarily

#

Just CPU is it's own type

#

and doesn't know about memory

#

it knows maybe about the BUS

reef stirrup
compact sage
#

its here

stone jewel
#

We won't provide code per se either

formal tulip
#

As i said, it is not hardware design

stone jewel
compact sage
stone jewel
#

OOP is not an objective

formal tulip
#

Because there are a lot of ways to design interfaces

stone jewel
#

And interface design is important

#

there isn't a single prescribed way of doing so

formal tulip
#

And Zig should not prefer one over the other

stone jewel
#

Like ink said, an interface is a vtable in most langs

#

so

formal tulip
#

Because each one has its own merits

onyx widget
stone jewel
#

In this case for this specific code with the intentions of this specific user I would:

  • Create a standalone CPU emulator with callbacks for memory writes
  • Create a Test Handler for the CPU bit of the equation, it loads the test from the jsons and creates a highly standarized set of test
  • Since Mem is abstracted as read/write via callbacks, the compiler can inline this calls easily, specially if it's comptime known
  • You then create you Emulator that holds mem and cpu, CPU calls the callbacks of mem that you init at the start of your emulator
#

this way you get a closure over the set of memories

compact sage
formal tulip
#

comptime polymorphism vs runtime polymorphism, for example, is not just a styling preference

#

each one has actual usecases and situations where it is preferable over the other

onyx widget
# compact sage I thought zig liked having a single way of doing things, instead of everyone doi...

it aims to have one obvious way to use the language, not a singular way to do every single thing. programming is a field rife with seemingly minimally different, but importantly distinct approaches to many things, with lots of different tradeoffs. it is impossible to literally only have "one" way to do absolutely everything, and generics/interfaces/polymorphism is one where there are so many different tradeoffs that, even beyond the concern of not wanting to endores needless abstraction, it would be irresponsible as a low level language to endorse one specific model for this kind of abstraction, when such a wide berth of approaches exist

compact sage
#

I mean rust does this with Traits and dyn Traits, you can make it easier without having to put one path down

onyx widget
#

zig ain't rust

#

different design priorities

#

rust embraces super complex abstraction

#

zig encourages thinking about the particulars a lot before even considering abstractions

plucky niche
stone jewel
#

In this case, you can move on and just abstract over two functions (if you want you can pas the vtable at comptime)

plucky niche
#

I feel like zig is a lot about not taking away power from the user for no reason

stone jewel
#

Callbacks are fun

plucky niche
#

like closures, why do you need to take a ctx object by hand in zig? because look at rusts FN types and the issues and confusion it causes

onyx widget
#

and the hidden performance issues

compact sage
#

also is there a way to do inclusive range in for loops

plucky niche
#

a lot of zig is doing things by hand because the solution is NOT as obvious as a lot of languages make it seem

formal tulip
stone jewel
#
pub fn step(
        self: *Cpu, 
        comptime Memory:  type,
        comptime readFn: fn(ctx: *Memory, addr: u16) u8,
        comptime writeFn: fn(ctx: *Memory, addr: u16, val: u8) void,
        ctx: *Memory
    ) void {
        const opcode = readFn(ctx, self.pc);
        self.pc += 1;
        // handle opcode...
    }
plucky niche
stone jewel
#

I fucking know

plucky niche
#

else this is unreadable

stone jewel
#

But shit is failing ok

#

an I am getting a tad mad =D

onyx widget
compact sage
#

hmmm

#

how do i see output in tests btw

plucky niche
#

i would, even tho its pointless, write this as a..(b+1)

onyx widget
#

bre

compact sage
formal tulip
#

I mean, considering that range + int is not a valid operation in Zig, I don't see how one might come to the conclusion

plucky niche
onyx widget
# compact sage how do i see output in tests btw

tests are not intended to emit output, they are intended to test conditions. if you want to debug stuff, you can use std.log.err (note that reaching a call to this will also mark the test as failed)

plucky niche
#

hiding complexity is not equal better code

#

if the complexity is relevant

#

my programming teacher always said "you cant hide complexity" it will show up somewhere

#

he religiously mentioned this every lesson

formal tulip
#

law of leaky abstractions moment?

stone jewel
#

The friction is because you are doing all this for a thing you can manually replicate in your own model and adapt

#

but you are not adapting, so we gotta get creative

formal tulip
#

I still do not get why you want to have all components be strictly separate

#

you are making an emulator to run ROMs, you are not designing hardware

compact sage
#

i mean i can just do it normal rn, the test will just break in future once the memory stuff gets more implementation

formal tulip
#

yes, that's the point of testing

#

or rather, the philosophy of testing

onyx widget
#

embrace the YAGNI mindset

#

do things when you need to

compact sage
#

YAGNI?

plucky niche
#

you aint gonna need it

onyx widget
#

You Aren't Going to Need It

formal tulip
#

you write a breaking test, you implement code until it works, then you write a breaking test again

#

that's the test driven development

compact sage
formal tulip
#

you should not design tests that pass implemented code

#

you should write code that passes created tests

compact sage
#

oh

onyx widget
#

if you look at the first paragraph, it links to the stdlib docs

compact sage
#

oh my bad

onyx widget
#

all good

#

you can also have them locally with zig std

#

(it runs a little local server that you can see in the browser)

formal tulip
stone jewel
#

If you want, you can take the cpu tests and take the assumptions of memory out

#

and so make them your own

formal tulip
compact sage
#

its like 10000+ tests for each opcode (200+) so it will be hard

#

wait maybe not that many

stone jewel
#

They are JSON, you can parse them and out code based on it

compact sage
#

how do i create a formatted string?

#

trying to look into std.fmt

#

but cant find the exact function

reef stirrup
#

yeah, std.fmt.bufPrint

onyx widget
#

depends on where the string is going

compact sage
#

but isnt that print

onyx widget
#

if you need it to be dynamically allocated, you can use fmt.allocPrint

formal tulip
#

wdym

reef stirrup
#

it's print to buffer!

compact sage
formal tulip
#

bufPrint does not perform a syscall

#

since it does not write data to a file

compact sage
#

i thought print meant print to a console

coral violet
formal tulip
#

no, print literally just means to print a human readable string

#

to either a fixed buffer or a file

#

or an array list

coral violet
#

the console is just a file descriptor at the end of the day zeroClueless

onyx widget
formal tulip
onyx widget
#

and writers can print to anywhere, including to in-memory buffers

coral violet
formal tulip
#

fair

coral violet
#

Even getting stdout/stderr to the terminal is hell on earth

onyx widget
#

well, it ain't that bad, it's just silly

#

because it ain't embrace posixy things

compact sage
coral violet
onyx widget
#

but ye

stone jewel
coral violet
coral violet
reef stirrup
# coral violet Even getting stdout/stderr to the terminal is hell on earth

Getting the colors (ansi) to work in the terminal and making it comfortable to type was actually a nightmare true, but what a result!!

    try app_log.print(.info, .{ "built for ", .os_arch, " on ", .timestamp, .nl }, .{
        zterm.TagConst(.os_arch, "{s} {s}", comptime .{ @tagName(builtin.os.tag), @tagName(builtin.cpu.arch) })
            .setColor(zterm.pallete.sky_magenta),
        zterm.Tag(.timestamp, "{d:04}.{d:02}.{d:02}T{d:02}:{d:02}:{d:02}Z", .{
            irl_date.year,
            irl_date.mon,
            irl_date.day,
            irl_time.hour,
            irl_time.min,
            irl_time.sec,
        }).setColor(zterm.pallete.sky_magenta),
    });
onyx widget
compact sage
# coral violet Yeah `bufPrint` is all you need then
    var buf: [32]u8 = undefined;

    for (0..0x100) |ins| {
        const file_name = try std.fmt.bufPrint(buf, "{}.json", .{ins});
        std.log.err("{s}", file_name);
    }
``` is this how you use it? sorry kinda new to all this buffer and pointer stuff
onyx widget
#

that would work too ye

coral violet
onyx widget
#

I wrote it in a way that statically guarantees the buffer is exactly as big as it needs to be

#

and note: declaring the buffer inside or outside the loop doesn't matter

#

but I think it's nice to keep it close to where it's needed

coral violet
compact sage
# onyx widget that would work too ye
❯ zig build test --summary all
test
└─ run test zigb
   └─ compile test zigb Debug native 2 errors
src/Cpu.zig:107:9: error: local variable is never mutated
    var file_name: [32]u8 = undefined;
        ^~~~~~~~~
src/Cpu.zig:107:9: note: consider using 'const'
src/Cpu.zig:110:26: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'
        std.fmt.bufPrint(file_name, "{}.json", .{ins});```
compact sage
#

i get this error

onyx widget
#

ah, just need to &buf

#

arrays are values

plucky niche
#

because it doesnt matter if you access stale memory or undefined

#

both are bad

onyx widget
#

they don't implicitly coerce to slices until you take em by ref

coral violet
plucky niche
#

if it was 0 terminated then you may need to fill it with zeroes

#

but other than that

onyx widget
compact sage
coral violet
plucky niche
compact sage
onyx widget
stone jewel
#

so what you use is what you get

onyx widget
#

at worst, that would entail incrementing and decrementing the stack pointer

#

and realistically, it just doesn't do anything because the codegen will just allocate the whole stack frame needed

compact sage
#

oh ok

plucky niche
onyx widget
#

no

#

it just don't matta

#

the previous contents are overwritten

plucky niche
#

i mean yeah, obviously you need neither zfill nor undefined fill if you know how large the thing you wrote is. i meant specifically when you use nullterm

compact sage
plucky niche
stone jewel
#

It's only problematic if you have memory assumptions in the system @plucky niche

plucky niche
#

yeah

onyx widget
#

so I catch unreachable as an assertion of that fact

plucky niche
#

you never need to override for non terminell terminated stuff, that was my point

compact sage
onyx widget
#

dir is just the directory handle where you expect these json files to be inside

#

if they're in cwd, std.Io.Dir.cwd()

#

if they're in some subdir, you can open it with like std.Io.Dir.cwd().openDir

#

I would personally probably pass their path in as a build option

compact sage
#

cwd is where i run zig build run or where the file is

#

?

onyx widget
#

it is where you run the command in

#

your "current working directory"

compact sage
#

oh ok

onyx widget
#

once you run the command the file doesn't exist anymore, it's been compiled into the binary n allat

compact sage
onyx widget
#

to be clear, I'm not saying you have to do this

compact sage
#

oh ok thank you

#

sorry for asking so many questions, I am very new to zig

onyx widget
#

but this is what I would do because I'm a perfectionist who doesn't like relying on relative paths in projects n all that

compact sage
#

it has a lot of things I have never used in any other languages

onyx widget
#

I appreciate that you are using it in the first place

#

ever since I've founded it as a forum I get nothn but complaints about having to use it smh

compact sage
#

its nice to have a place where people can focus on a topic without disrupting normal conversation in general

stone jewel
#

when Ink and I started helping on zig help back in 0.8 days, it was a single channel

#

it was awful have to say

onyx widget
#

yeah, very difficult to keep up with so many questions in one thread of conversation

#

(discord's forums aren't really perfect either tbh, I long for zulip threads)

stone jewel
#

And we were fast answerers lol

onyx widget
#

them's the days

compact sage
#

is there a way to define functions inside a test


test "something" {
  fn process_test_file(file_name: []u8) io.File.OpenError!void {
      const file = try dir.openFile(io, file_name, .{});
      defer file.close(io);
  }
  ...
}
#

cause this isnt working

onyx widget
#

same way as defining functions in any other functions

test "something" {
    const nice_name = struct { // like "helper" or something
        fn foo() void {}
    };
    nice_name.foo();
}
compact sage
#

oh ok

reef stirrup
compact sage
#

can anyone tell me how do i read a json file in zig

#

I am reading the documentation but its not clear to me

fierce sage
#

Are you talking abour reading file, or parsing JSON string?

solid dock
#

i assume reading a json file and parsing it

compact sage
#

so how do i do that

solid dock
compact sage
#

yeah

#
        const file = dir.openFile(io, file_name, .{}) catch continue;
        defer file.close(io);
compact sage
#

how do i work with file as a json file

solid dock
#

do you want to fully load the file into memory before parsing?

fierce sage
solid dock
#

you can either use the API function that takes in a std.Io.Reader (which is your file reader) or you can just parse the whole text once you have it in memory

compact sage
#
        fn process_test_file(file: std.Io.File) !void {
            // do stuff with file.json
        }
#

trying to implement it like this

fierce sage
#

i don't recommend passing File it self, as it needs IO to do anything on the file handle anyway

#

pass reader or raw bytes

compact sage
solid dock
#

i fucking hate windows 11, my computer hard-froze

compact sage
#

I do not understand how to use an allocator

fierce sage
solid dock
#

you either initialize an allocator at the start of your program and pass it down the rest of your program, or you take it off juicy main

#

you're probably gonna take it off juicy main (which is copying init.gpa)

compact sage
fierce sage
#

don't be scared of allocators, you don't even have to use it, just pass it where its necessary

ancient marten
#

std.testing.allocator

solid dock
#

then for the moment, it's best if you use std.testing.allocator, yeah

compact sage
#

oh ok

solid dock
#

i'm pretty sure the documentation has a section for picking your allocator, hang on

#

yup

compact sage
#

thanks

#

i dont understand something, why does dir.readFile take a buffer and also return a buffer

#

like what

fierce sage
#

bc it might read less than the size of buffer

#

so it returns smaller slice

compact sage
#
test "sm83-single-step-tests" {
    const io = std.testing.io;
    const dir = try std.Io.Dir.cwd().openDir(io, "tests/sm83-ssts/v1", .{});
    const allocator = std.testing.allocator;

    // load test .json;
    // for test in test.json:
    //     set initial processor state from test;
    //     set initial ram state from test;
    //
    //     for cycle in test:
    //         cycle processor
    //         if we are checking cycle-by-cycle:
    //             compare our r/w/mrq/address/data pins against the current cycle;
    //
    //     compare final ram state to test and report any errors;
    //     compare final processor state to test and report any errors;
    const helper = struct {
        fn process_test_file(file: []u8) !void {
        }
    };

    for (0..0xff + 1) |ins| {
        var path_buf: [32]u8 = undefined;

        const file_name = try std.fmt.bufPrint(&path_buf, "{x:02}.json", .{ins});
        const file = dir.readFile(io, file, ??? ) catch continue;
        helper.process_test_file(file);

        if (ins == 0xCB) {
            for (0..0xFF + 1) |sub| {
                const sub_file_name = try std.fmt.bufPrint(&path_buf, "{x:02} {x:02}.json", .{ ins, sub });
                const sub_file = dir.readFile(io, sub_file_name, ??? ) catch continue;
                helper.process_test_file(sub_file);
            }
        }
    }
}
#

this is basically what I am trying to do

#

am i doing it right?

pliant hazel
#

i still dont get it

zinc stump
#

WASM and embedded

compact sage
#
    const file_buffer = try allocator.alloc(u8, 500 * 1024); // 500 KiB
    defer allocator.free(file_buffer);

    for (0..0xff + 1) |ins| {
        var path_buf: [32]u8 = undefined;

        const file_name = try std.fmt.bufPrint(&path_buf, "{x:02}.json", .{ins});
        const file = dir.readFile(io, file_name, file_buffer) catch continue;
        try helper.process_test_file(file);

        if (ins == 0xCB) {
            for (0..0xFF + 1) |sub| {
                const sub_file_name = try std.fmt.bufPrint(&path_buf, "{x:02} {x:02}.json", .{ ins, sub });
                const sub_file = dir.readFile(io, sub_file_name, file_buffer) catch continue;
                try helper.process_test_file(sub_file);
            }
        }
    }
``` ok this works nicely
#

am i using the allocator right?

stone jewel
#

yea

compact sage
#
test
└─ run test zigb
   └─ compile test zigb Debug native 1 errors
/usr/lib/zig/std/mem/Allocator.zig:444:50: error: access of union field 'pointer' while field 'union' is active
    const slice_info = @typeInfo(@TypeOf(memory)).pointer;
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/usr/lib/zig/std/builtin.zig:550:18: note: union declared here
pub const Type = union(enum) {
                 ^~~~~```
#

what does this error mean

#
        fn process_test_file(file: []u8) !void {
            const value = try std.json.parseFromSliceLeaky(std.json.Value, allocator, file, .{});
            defer allocator.free(value);
        }
#

I am just doing this

peak widget
#

value is not a pointer. I think you're not supposed to free a json.Value, you pass an arena allocator and deinit/reset it

compact sage
#

my program just gets stuck idk why

peak widget
#

(value is not a pointer, so allocator.free(value) can't compile)

compact sage
#

no i took care of that

#
 fn process_test_file(file: []const u8) !void {
    const parsed = try std.json.parseFromSlice(std.json.Value, allocator, file, .{});
    defer parsed.deinit();

    std.log.err("{}", .{parsed.value.array.items.len});
}
#

just trying to print length and this gets stuck

#

no idea why

#
test "sm83-single-step-tests" {
    const io = std.testing.io;
    const dir = try std.Io.Dir.cwd().openDir(io, "tests/sm83-ssts/v1", .{});
    const allocator = std.testing.allocator;

    // load test .json;
    // for test in test.json:
    //     set initial processor state from test;
    //     set initial ram state from test;
    //
    //     for cycle in test:
    //         cycle processor
    //         if we are checking cycle-by-cycle:
    //             compare our r/w/mrq/address/data pins against the current cycle;
    //
    //     compare final ram state to test and report any errors;
    //     compare final processor state to test and report any errors;
    const helper = struct {
        fn process_test_file(file: []const u8) !void {
            const parsed = try std.json.parseFromSlice(std.json.Value, allocator, file, .{});
            defer parsed.deinit();

            std.log.err("{}", .{parsed.value.array.items.len});
        }
    };

    const file_buffer = try allocator.alloc(u8, 500 * 1024); // 500 KiB
    defer allocator.free(file_buffer);

    for (0..0xff + 1) |ins| {
        var path_buf: [32]u8 = undefined;

        const file_name = try std.fmt.bufPrint(&path_buf, "{x:02}.json", .{ins});
        const file = dir.readFile(io, file_name, file_buffer) catch continue;
        try helper.process_test_file(file);

        if (ins == 0xCB) {
            for (0..0xFF + 1) |sub| {
                const sub_file_name = try std.fmt.bufPrint(&path_buf, "{x:02} {x:02}.json", .{ ins, sub });
                const sub_file = dir.readFile(io, sub_file_name, file_buffer) catch continue;
                try helper.process_test_file(sub_file);
            }
        }
    }
}
#

can you find any issues?

peak widget
#

stuck where?

#

(use a debugger or add log()s to see what the code does)

compact sage
peak widget
#

maybe change test { to pub fn main(init: std.process.Init) !void { and zig build-exe?

compact sage
#

ok nvm its not stuck its just slow af

compact sage
#

there's so many minor inconveniences while using zig

onyx widget
#

those are shrimply the complexities that other languages hide that zig makes you handle in the pursuit of writing better software

compact sage
onyx widget
#

ignoring and abstracting away those complexities is what makes most software un-robust. most of the best software that is robust and stable gets to be that way only after years of manually applying discipline and lessons - of course, zig isn't a silver bullet to achieving this, but it outlines the areas where such discipline will be needed from the outset

compact sage
#

there are many things that you can abstract away and never have to worry about them

onyx widget
#

the most basic example is memory allocation

#

in basically most languages, memory allocation is basically shuffled under the radar

#

even in C, the manual memory management language, basically mostly treats it like it can't happen by default

#

even most of the best C codebases probably started with such an assumption, and had to manually evolve to handle those failures gracefully

compact sage
#

who is ultimately zig for?

stone jewel
onyx widget
#

systems programmers, and people who like writing robust software in the same way systems programmers do

inland blaze
stone jewel
#

Wouldn't say that

compact sage
#

I want a hobby language to make cool stuff with, I make stuff gaming adjacent so I want performance, ease of use and easy portability across platforms

stone jewel
#

Not everybody here like or know how to program C or C++

compact sage
onyx widget
#

I find zig very easy to use

compact sage
#

also the documentation sucks guys

#

sorry to say

#

it's like, so bad

onyx widget
#

I mean, no apologies needed, it does suck

compact sage
#

compared to rusts docs

onyx widget
#

we are aware of this

stone jewel
#

We are aware

onyx widget
#

it's basically the top 2 complaints

#

from beginners and veterans

stone jewel
#

And there is not much that can be done with the language moving

compact sage
#

I spent so much time manually figuring out how to read a json file

onyx widget
#

yea

#

again, we know

#

we've heard it a billion times

stone jewel
#

To be fair, enter into json.zig and read the code

#

no fr

inland blaze
stone jewel
#

Read the Source

#

Test usually tell you how to use the thing you need to use

onyx widget
#

in another sense, zig is for people who are comfortable with re-inventing the wheel (though without actually obligating you to do so), and reading the source code for what you're using (which it makes much easier to do compared to C/C++ and Rust)

compact sage
# inland blaze Heh

I like the rich type system of Rust, the way you can guarantee so many things at compile time, you never have to even think about it at runtime.

onyx widget
#

you do have to think about it at runtime

#

the idea that you don't is wildly incorrect

compact sage
#

It's not gonna be unexpected

#

anyways your code can fail is always explicit in Rust

onyx widget
#

the static guarantees model a subset of your program's invariants

stone jewel
#

Rust only promises you that your code takes that shape (In that sense any type system can expres this with more or less pain) and that their memory safety guarantees are correct

#

The runtime invariants are still for you to handle

onyx widget
stone jewel
#

including panics and the sorts

compact sage
onyx widget
#

integer overflow is also implicit - and in the likely event zig gains ranged integers, even arithmetic in zig will only be able to fail explicitly, vs in rust where it is implicit

onyx widget
compact sage
#

zig doesn't make it as easy as rust to do it so

#

everything is manually imperatively done

onyx widget
#

Because rust hides more than zig

stone jewel
#

Zig doesn't believe in automagic

onyx widget
#

Because rust is less explicit

compact sage
#

obviously both are turing complete languages, you can do anything in anything. But the type system of Rust is far far superior by default

onyx widget
#

Not for raw pointers

fierce sage
#

fr

onyx widget
#

Zig excels by far in any endeavour that requires unsafe wrt type systems

compact sage
#

I don't think 90% of people who use rust have to deal with raw pointers

#

for example, I never did, in any of the applications i used

onyx widget
#

Sure, hence they have different audiences

#

Rust seccludes systems. Zig embraces them

compact sage
#

you model the reality of your problem in the way Rust wants it

onyx widget
#

You can still only model a subset of it

#

You must still evaluate the actual behavior at runtime

inland blaze
#

Safety yay

compact sage
onyx widget
#

I mean in the sense of what you can model

compact sage
#

but you can guarantee how those runtime systems will interact at compile time

inland blaze
onyx widget
#

In order to perfectly model your program in the type system, you would have to write a finite state machine

inland blaze
#

The one feature I really to see is the one by Mitchell, for multiple or descriptions on doctests

onyx widget
#

And model your program entirely at comptime

#

With tne runtime merely being a mirror of it

#

By this fact, rust does not guarantee any logical correctness, only the specific invariants you care about

compact sage
#

I just don't see the pros I gain from using zig, are that worth it compared to the cons of not using rust.

onyx widget
#

Like I said, different audiences

#

If I used rust, I would largely be programming in unsafe, which is just not worth it compared to using plain old C

stone jewel
#

There is this I heard once in my doom scrooling, it goes along the line of:
"The major burden of knowing magic is that there is no longer moment of quiet wonder, or moments of luck, you got to manage it yourself"

fierce sage
#

learning zig is ruff

compact sage
#

yeah I am just judging it as a newcomer, there's like so much friction trying to learn zig

fierce sage
#

and indeed not super welcoming, as best src is source code anyway

compact sage
#

interacting with anything outside zig with zig is super tough

#

like io and files and stuff

onyx widget
#

If we're talking about friction to newcomers, I don't think rust is earning any awards there :P

compact sage
#

atleast with rust, the docs are great

inland blaze
#

Aside that, I like to consider the backing each language had, Rust had a whole Mozilla and team of research, and it's already stable. Zig on the other hand it's purely on Andrews vision and community.

onyx widget
compact sage
#

also not to mention the zls lsp is not that good, it doesn't show literally most of the errors

onyx widget
#

Can I ask, what is your point here? Why have you attempted to learn zig when you have near zero enthusiasm for it?

fierce sage
#

i would refer to tutorials or guides maybe as docs are not really that bad, you can search any function and check what it even does or check how its used in std

onyx widget
#

You know it's pre-1.0, but seem to expect a 1.0 experience. Seems like misaligned expectations

compact sage
#

I want to learn zig, I find rust has a lot of stuff that I like but a lot of features I don't use, and it's a very complex language. I was attracted to Zig because I thought it was a very simple language with a very small set of syntax and features you need to know.

But my learning process has been full of friction and hurdles trying to the even the most basic stuff like reading a file or printing to stdout

inland blaze
#

Same dilemma I had with all Rust, Go and Zig

onyx widget
#

The language being simple means you do have to do more work

compact sage
#

but i find it not so simple actually, it has so many builtin functions, that increase the language complexity a lot for me

onyx widget
#

Fewer abstractions between you and the reality of the code means you become the master of orchestrating what other languages would for you

inland blaze
#

More than simple I find it verbose/explicit

#

Which is entirely Zigs goal

stone jewel
#

Found the damn quote:

“Look, a shooting star!”
“I’ll pass.”
“What?”
“Wizards can’t wish on shooting stars. Or anything else, really.”
“Why not?”
“That’s how it works. The price for learning magic is that you become responsible for your own magic. No more lucky breaks, no more synchronicity, no more spontaneous moments of quiet wonder – you have to do it all yourself. And in exchange, you get to shoot fireballs out of your hands.”
“... was it worth it?”
“Fuck yes.”

#

Thanks tumblr

onyx widget
#

Hell, even Rust's format syntax is a builtin, whereas zig's is userland

fierce sage
stone jewel
#

You can build your own std, and is what big projects usually do (And some crazy people)

#

There is nothing magical about std

inland blaze
#

Zig Boost

coral violet
#

And a lot of zig builtins are just things that other languages provide on the std in less optimal ways like @abs

coral violet
onyx widget
ancient marten
onyx widget
coral violet
compact sage
#

I think the main issue for me is it's hard to get info on "how do I do X in zig" google is useless for the most part, LLMs too. My only options remain are reading the subpar documentation or ask stuff here and wait for others

fierce sage
#

indeed

#

i agree with that

stone jewel
#

Mostly true.
I enjoyed learning zig without google

#

There is the langref, there is the code

#

Figure it out

onyx widget
stone jewel
#

If you want an LLM to do it, I do recommend you to get a local one read your zig std and ask it to research it

fierce sage
#

tbh its ruff, but after 12h of zigging you start anyjoying it trust me, maybe start with simplier projects or something

coral violet
stone jewel
compact sage
#

I feel like the rate at which I can learn zig is being limited by a lot of external factors outside my control.

With Rust I learnt it pretty fast, because the linters are great, compiler error messages are state of the art. and LLMs work well for the most part and docs are also pretty good.

I know "Zig isnt 1.0" etc but just stating my experience

ancient marten
onyx widget
fierce sage
coral violet
stone jewel
#

I think your method of approaching it is the one stopping yourself 😅

onyx widget
#

Yeah idk Zig's error messages are pretty good today

#

They used to be kinda crap

onyx widget
#

But now you just need to read them

fierce sage
coral violet
onyx widget
compact sage
stone jewel
#

lol, it didn't improve much until a few ver ago

coral violet
stone jewel
#

Oldie but useful

onyx widget
coral violet
#

Zig SHOWTIME is still a rly good source for concept explanation, wish they made more

ancient marten
stone jewel
#

Sad his troll ass just comes to meme nowadays xD

stone jewel
onyx widget
#

Eh, he did his part

stone jewel
compact sage
#

stuff like reflection and having to use it for generics is very new to me, I have never used stuff like that in any language

#

it feels very hacky, seeing a language refer to itself

stone jewel
#

Ruby does that, and does rust

#

Well

#

for metaprogramming

#

iinstead of Generics

#

but still

compact sage
#

idk its just what I am used to i guess

#

I do not like macros in rust a lot, proc macros tho are very cool

stone jewel
#

Ruby reflects on itself and you can create generics that way =3
is indeed just different

compact sage
#

since you can basically do very cool stuff like embedded html/SQL etc and validate them at comptime

coral violet
compact sage
#

btw, how can I convert a u16 to a packed struct(u16)?

ancient marten
stone jewel
#
const data: u16 = @bitCast(packed);
coral violet
stone jewel
coral violet
#

And if you are mergings strings instead of using statements you are just using sql wrong

compact sage
compact sage
coral violet
coral violet
compact sage
#

the main benefit of this is rust-analyzer can just hints and errors while writing code. You don't have to compile or run your sql engine to figure out when some large query you wrote went wrong

stone jewel
#

That is just asking for problems imo

coral violet
compact sage
onyx widget
#

yeah am aware of that package, I wouldn't be comfortable with my tooling running directly to interact with an arbitrary database automatically

stone jewel
#

You should if possible do:
Bring data -> Transform it into your program domain data -> Deal with your own data -> Send message to something that will insert it or deal with the interaction on your data/db

coral violet
#

Not to mention most sql lsps allow for testing queries on the fly with ide shortcuts

compact sage
stone jewel
#

That's so dirty to me ugh

coral violet
onyx widget
#

whatever, no sense arguing about it. some people like control over their tools, and others like em to run wild

compact sage
#

I mean if you had something like rust-analyzer you understand why its beneficial

onyx widget
#

I have used it

compact sage
#

and also not using an ide

onyx widget
#

rust analyzer is quite a piece of technology

coral violet
#

You dont need it; its a bandaid for bad development practices

onyx widget
#

I just hate using rust

stone jewel
#

x2

onyx widget
#

and think that the things rust does are anathema to what I value

stone jewel
#

but anything that is a bandaid for bad practices is bad software for me

#

(Not rust analyzer itself, but things like in-code validation of other languages...)

coral violet
#

The biggest downfal of rust was it getting so web-piled and doing all the same mistakes and awful practices those people do

coral violet
# compact sage what? an lsp?

Inline validation for external languages that have their own way better tooling (with no impact on compilation speeds either)

#

Especially given that just because a sql query is valid in mysql doesnt mean its valid in postgress, the rabbit hole of sql is so big there is no concievable way that rust's inline checking actually works properly

compact sage
coral violet
#

Not to mention they will explode the slow compilation speeds to a whole new magnitude for no reason at all

compact sage
#

without proc macros, stuff like clap and serde won't be so good at all

coral violet
compact sage
onyx widget
#

I think they mean wrt the quality of software

coral violet
compact sage
#

have you used clap?

onyx widget
#

sure have, and no thanks

stone jewel
#

Still no thanks

onyx widget
#

I know it may be hard to grasp, but just as much as you seem to think we don't understand your perspective, you seem to lack any grasp of ours

coral violet
#

Using text protocols for native development is the stupidest shit ever and i hate how much rust is polluting the space with it

#

All the "fast text parsers" can be beaten by the most lazy half assed binary protocol implementation

inland blaze
coral violet
stone jewel
inland blaze
#

There's a cli namespace?

coral violet
#

Or is that std.progress?? I forgot (the thing they use for the build system)

inland blaze
#

So basically

#

No external library

#

Just strings

peak widget
#

std.progress is zig's fancy progress "bar"

compact sage
peak widget
#

unrelated to parsing CLI arguments

stone jewel
#

args just works so it's easy to handle it

inland blaze
#

Oh

coral violet
# inland blaze No external library

Yeah, there is no need to, unless you need more than 40 options or some fancy graphical stuff libraries will just tie you to their constrains and be generally slower

inland blaze
#

I was wondering for external library mostly

onyx widget
coral violet
#

bun had a lot of issues because they were using clap and couldnt do the features they wanted to (this before the AI slop, like 0.3 days)

inland blaze
#

On Zig?

#

They were using zig clap?

#

That's so silly

coral violet
#

Yep, they were in the early days and instantly regretted it, tho honestly that seems to be the entire thing about bun, ship as fast as possible and regret everything later

compact sage
stone jewel
#

C++ sucks

coral violet
stone jewel
#

As someone that uses it for fun

inland blaze
#

I don't really get serde

stone jewel
#

That's just it

inland blaze
#

I see a point in Rust via macros but

onyx widget
inland blaze
#

I don't understand how is it beneficial in Zig

stone jewel
#

My C nowadays looks like zig, why not use zig?

halcyon marten
stone jewel
#

You seem to work in black and white my dear, we are working a bit in the middle

#

We don't think zig is perfect, but it accomplish exactly what we expect

onyx widget
#

a 3D middle

#

it's not like there's a spectrum that goes C, C++, Rust

stone jewel
#

that's what keeps us comming back

coral violet
# compact sage I mean if Zig is just C+ then idk why people wouldn't just use either C++ or C, ...

So let me get this straight.
You complain that zig has "to many builtins" yet you are saying that people would prefer to use a language that has 5x the keywords and builtins? Im failing to see the logic here.

Zig is lower level than C while providing some high level abstractions (like defer) that C doesnt, it also doesnt have some pitfalls that C does (goto hell) and is exicit about its intent; thats what makes it modern and a C alternative

#

And on the topic of libraries; all C & C++ libs can be used seamlessly in zig with a simple translateC step on the build file

onyx widget
#

yeah, putting all of your criticisms together mostly just makes it sound like "Zig isn't Rust"

#

I'm sure you don't intend that

#

but that's pretty much where this is heading

halcyon marten
inland blaze
#

I feel you are a bit forcing yourself into Zig

coral violet
stone jewel
coral violet
onyx widget
#

if for every point about zig you just say "but rust does it this way which is good", then you should just use rust. you shouldn't use zig just because it conceptually represents an appealing aesthetic called "simplicity"

lofty bear
#

oh nice, this thread looks like an average quick question in #zig

coral violet
halcyon marten
compact sage
#

my main reason for using zig is just that it's a "simpler" language that lacks a lot of features, which maybe forces me to learn new stuff and implement some stuff from scratch, but I am contemplating why not just learn C at that point

coral violet
onyx widget
stone jewel
#

you will either love it, or learn why we stay here xD

#

Or both!

#

(Or neither but that's the bad end)

compact sage
#

my main deterrent for C is the lack of generics and no proper build system (I hate cmake)

inland blaze
coral violet
lofty bear
onyx widget
halcyon marten
onyx widget
#

but you should try it anyway

onyx widget
#

lacking generics is a good lesson in the very fundamentals of abstraction

stone jewel
#

Yes

#

Or you can use their Generic Keyword, is so nice lol

onyx widget
#

very quickly forces you to learn type erasure and writing agnostic algorithms without a compiler to copy paste your code

inland blaze
stone jewel
#

or learn how to do OOP in C

#

that's a nice lesson

coral violet
stone jewel
onyx widget
#

bespoke lexers >> regex

stone jewel
inland blaze
stone jewel
#

I should make a post about it

compact sage
stone jewel
onyx widget
#

there are many avenues of abstraction

stone jewel
onyx widget
#

type erasure and agnostic algos among them

#

and good old DOD

stone jewel
#

Message Passing

onyx widget
#

yems

halcyon marten
coral violet
stone jewel
#

Slot based systems

coral violet
#

I'd rather waste a day writting a parser for my use case than touch regex ever again

stone jewel
#

Command based abstractions

onyx widget
#

which, to be clear, you can also learn all these things in zig. but if the point is to learn new lessons through restriction, C is certainly the ultimate logical conclusion

coral violet
onyx widget
#

you certainly seem to be capable of committing yourself to gritting your teeth and learning a language you think isn't that beneficial, so if you're going to do that, I do really suggest trying out C

onyx widget
#

because it sucks

compact sage
#

the main thing I need for a perfect C is rust enums and generics, that would be the perfect language for me. a good build system would be nice to have too

halcyon marten
onyx widget
stone jewel
#

There is no perfect language, something will always stick out

onyx widget
#

because earlier you said you were chiefly using zig to learn

inland blaze
#

There's no perfect language

compact sage
#

like perfect for what I am looking for

inland blaze
coral violet
stone jewel
#

Since we are at it, try vale, I do wanna see someone testing it

inland blaze
#

Crystal

onyx widget
#

lmaooo

#

kaezrr we're apparently giving you homework

coral violet
compact sage
inland blaze
#

Go

onyx widget
#

well, zig certainly gets the easily portable and efficient stuff down

lofty bear
#

learn ATS for bulletproof low level lang zeroClueless

stone jewel
#

Ada is another bulletproof one

lofty bear
stone jewel
#

yea

coral violet
stone jewel
#

They have native memory pools that are basically arenas for memory sections @lofty bear

inland blaze
#

Spark

compact sage
#

Also I am doing it mostly as a hobby so it has to be fun and kinda approachable, good tooling and dev ux helps in that

coral violet
#

Good tooling will never happen in a pre 1.0 language; zls is pretty much worthless with generic code.
DX is very subjective and depends on how you think about software

#

Some people think anonymous functions & colosures are good DX, others hate them and their hidden magic properties

lofty bear
#

ruby apparently is DX dream until you wake up in macro hell

inland blaze
#

Java 😋

compact sage
#

DX that strikes a good balance between convenience but without affecting the end result. For example not languages like javascript that trade dx for everything

lofty bear
#

how come most graph related tools are written in Java, annoying

compact sage
halcyon marten
lofty bear
coral violet
coral violet
compact sage
coral violet
#

Try odin, maybe a rust piled brain will like it more given it has concepts that resemble traits and also has explicit function overloading

inland blaze
#

C3

onyx widget
#

odin and C3 are pretty neat choices too, yeah

#

both a bit more C-spirited than Zig

#

but also go a bit further in what you might call "modernization"

#

ie Odin was mostly developed for gamedev

inland blaze
onyx widget
#

not imo

#

but to each their own

halcyon marten
onyx widget
coral violet
compact sage
onyx widget
#
const helper = struct {
    fn foo() void {}
};
helper.foo();

also lets you write multiple of them in there

onyx widget
coral violet
coral violet
compact sage
#

no like it has a pretty huge stdlib right

#

has sdl and everything directly in the stdlib or something

inland blaze
#

vendored libraries

coral violet
inland blaze
#

it's trying to be like Ruby i guess

#

joy of programming goal type

compact sage
#

it's also very game dev domain focused, I don't want that

coral violet
inland blaze
lofty bear
#

then time to pull off Andrew's trick and write yet another language

coral violet
inland blaze
onyx widget
#

it's very C inspired, so obviously you get all the suckiness associated with that, but ey

#

fn void main

coral violet
compact sage
#

also like I want the language to be somewhat popular and have a community around it, otherwise I can't really discuss stuff or ask for help

onyx widget
#

any language you'll hear about has at least some community around it

#

just depends on the degree to which that is the case

coral violet
#

Even OCamll has a community

compact sage
#

first time hearing about c3 tbh

#

ocaml I have heard a lot in the functional programming groups

onyx widget
#

you've heard about it now

coral violet
inland blaze
#

Poor 🔥

compact sage
#

functional programming must be the anthesis to everything you guys stand for isnt it, the most abstracted abstractions of all abstractions

inland blaze
#

why doesn't zig work with .z

onyx widget
#

can appreciate many of its concepts

#

hell, a lot of modern language features are inspired from FP

#

but the core values of FP are quite antithetical to zig yes

inland blaze
#

You should try F#

coral violet
inland blaze
#

boooooooo

onyx widget
#

(the features I refer to are stuff like optionals and error unions, with operators that make them very akin to monads)

compact sage
#

yeah like personally I really like functional programming, I think if there weren't any performance detriments, any pure FP language would be my ideal hobby language for building stuff

coral violet
onyx widget
zinc stump
#

What was that FP lang with the zig backend called?

inland blaze
#

Haskell

onyx widget
#

pf

#

man I didn't know they rewrote haskell in zig

compact sage
lofty bear
#

GHC's haskell has relatively low performance overhead, it's just harder to reason about algorithmic complexity + their toolchain is large

onyx widget
#

if'n you don't mind me asking

compact sage
onyx widget
#

fair enough

#

well, if you want the performance, you do also gotta accept the restrictions that come with it

zinc stump
#

Write your own dream language zeroClueless

coral violet
inland blaze
#

I feel this became a

lofty bear
#

forth is very FP like and low level

inland blaze
#

#programming-discussion more than understanding Zig now

lofty bear
onyx widget
inland blaze
#

Thread closed because too much heat idk me no english

coral violet
#

If you want modern FP with decent performance, Elixir is the way (tho its more geared for networking than anything)

zinc stump
compact sage
#

I was basically looking for Rust--

#

but feel like Zig is C*

zinc stump
#

For me personally, zig is that rust--

lofty bear
compact sage
#

I mean I still haven't given up on zig, I will finish my current project before ultimately deciding if its for me

#

but yeah, I will complain here

onyx widget
#

that's fine, just also expect us to pushback :P

compact sage
#

that's fine, most of my complains are due to being unfamiliar with this stuff and seeing it for the first time

onyx widget
#

imdeed

zinc stump
#

If you find zig is not for you, try C, and if you also don't like that, I suggest you try zig again and see how you feel after having experienced C!

compact sage
#

I mean I already know the annoyances of C, I would rather learn zig than deal with them

onyx widget
#

knowing C certainly does elucidate many of Zig's decisions

compact sage
#

I learnt C as part of my college course, never built anything serious in it

onyx widget
#

well, I would personally argue that building something a bit more serious (ie requires sitting down and thinking about how to design stuff without necessarily having a direct answer simply available to you) is an important part of fully learning a language

compact sage
#

btw, when I do !void as the return type, how does zig know whats the error type

onyx widget
#

but fair enough

#

it analyzses the function body, and based on the runtime code, puts all the possible errors together

#

ie, if it sees you do return error.Foo in one reachable branch, and try foo() on another function with an error set error{Bar,Baz}, the IES would be error{Foo,Bar,Baz}

compact sage
#

oh it creates an error type on the fly

onyx widget
#

"on the fly"-ish

#

it is lazy about it

#

in reality it doesn't resolve the error set until it has to

#

ie, it can't do it when you declare the function

compact sage
stone jewel
#

and only works with functions with bodies (so no over function pointers)

onyx widget
#

it does it when you query info about the function type, and when you call it

onyx widget
stone jewel
compact sage
#

so I can't just return a number let's say? as an error?

stone jewel
#

Error types are just subsets of said set

onyx widget
#

non

stone jewel
onyx widget
#

just to clarify something: errors and error unions are not like rust's result type

stone jewel
onyx widget
#

they are more like a tool for controlling control flow, and distinguishing between the happy path and error path

compact sage
#

so like in rust the result type can have anything as an error right, is that not possible in zig

stone jewel
onyx widget
#

non, like I said, they don't serve the same purpose

onyx widget
#

I swear it must have been the case a long time ago in an older version

stone jewel
compact sage
stone jewel
#

and retro-actively said, it doesn't matter

stone jewel
coral violet
stone jewel
onyx widget
#

if you have more complex data to handle, or something where "this is an 'error' case with more data to deliver and handle", then it shouldn't be thrown away into the error path, and you should handle it like a normal path. or, if it really is just part of the error path, then using the diagnostics pattern is the most appropriate thing to do

coral violet
onyx widget
stone jewel
#

is a pattern for "Need to push something as an error outside with extra data"

compact sage
stone jewel
#

that means you have used all your correct resources and need explicit user handling

onyx widget
#

it doesn't make sense with the way zig has designed them

#

if it was like that, you couldn't simply try errors

#

since all errors would need to be distinct and closed sets

zinc stump
#

Can always use an out pointer to get some more information

coral violet
# onyx widget dewit

Still got some features to implement gonna do it afterwards (the entire goal is to no stop parsing on errors so diagnostics will need some thinking)

onyx widget
#

but the way they actually work is that all error sets are just subsets of the global error set (which can be referred to as anyerror)

#

it's very akin to the C approach to error codes

#

in fact that's kinda what andrew modelled it based off

coral violet
compact sage
#

also how do you guys debug your zig programs

stone jewel
#

gdb, lldb, and prints

onyx widget
#

printf debugging most of the time, every now and then lldb

stone jewel
#

depends on the kind of bug

zinc stump
#

There's an lldb fork that adds better zig support iirc

onyx widget
#

can't beat the classics

coral violet
compact sage
#

lldb and gdb which one is better? idk how to use both

stone jewel
coral violet
zinc stump
#

std.debug.print + lotta tests helps

stone jewel
#

lldb can be better with zig thanks to llvm

coral violet
onyx widget
#

gdb is always kinda finnicky

compact sage
onyx widget
#

no

stone jewel
#

Kindof

coral violet
#

Can say lldb works rly well, just can be a pain to setup in some environments

stone jewel
#

The true answer is NO

onyx widget
#

it's divorcing it from the codebase, but zig will always support emitting LLVM

stone jewel
#

The General bit is that the codebase is not dependent of llvm to generate code

#

But LLVM is the faster backend

onyx widget
#

I love andrew but man, we are going to always have to deal with that damn misconception for years onwards

coral violet
stone jewel
zinc stump
stone jewel
#

When zig actualy puts nice Dwarf itself, debugging with gdb or lldb will be a as good as the tooling around zig for those tools

coral violet
#

Sadly using llvm seems to be the only way to get crypto/hashing code to not slow to a crawl...

onyx widget
#

yeah

stone jewel
#

Oh and tracy your stuff, adding metadata into your program helps
and for the graphical side, renderdoc

onyx widget
#

we are forced to use llvm at work still

#

can't use self-hosted at all still

#

hopefully someday

compact sage
#

for logging, is std.log enough or do you guys use third party solutions

stone jewel
#

( I consider performance as a kind of bug so tracy is technically debugging)

coral violet
#

The same code that takes less than 500ms to run using llvm can take more than 6 seconds with the zig backend... (for crypto that is) its quite the pain rn

stone jewel
onyx widget
zinc stump
stone jewel
onyx widget
#

we use a custom logger at work, but that's for a bunch of reasons, like wanting more log level granularity, and wanting to pass around a logger interface thingie that can make scopes required, and also because we do a bunch of IPC stuff that it simplifies the data flow of

stone jewel
#

since multiple sinks is kinda bad in current std.log api

coral violet
compact sage
onyx widget
#

you override the logfn to something that respects a runtime log level

compact sage
#

is there no cli flag

onyx widget
#

no

stone jewel
coral violet
compact sage
onyx widget
#

where would it even get the CLI flag from

#

you are the one writing the main entry point

stone jewel
compact sage
coral violet
#

Thats not a flag

onyx widget
#

and yeah, that not a flag, that's called an env var

compact sage
#

yeah

zinc stump
#

I presume they also want -q and -v

coral violet
#

Environment variables and flags are 2 different concepts and serve different purposes.
But zig doesnt generally introduce things on a whim, you can do it with your own abstraction but there is no reason to when you can make use of comptime and proper build flags for this

stone jewel
#

having a general env variable that your program currently have is a choice... (for libraries)

#

I don't like personally exposing envs that could be an API that the user can use to implement said logic

onyx widget
#

This is the Way

coral violet
#

I dont like env vars at all, build time flags are superior and more controlable

lofty bear
#

almost at 2k messages, i wonder how much that would cost in LLM tokens

stone jewel
#

Like, you want to make a choice between wayland and X11 or Arcan in Linux

#

(Curse you @lofty bear )

coral violet
# stone jewel Sometimes needed

Yeah its a necessary evil for things like terminal color detection but especially if you look at the web people you will see them passing sensitive credentials via env vars and its just awful

stone jewel
#

you also don't want them on the binary, you want to pass them via a secure network at startup

coral violet
onyx widget
#

human token-maxing out here

stone jewel
#

and way too insecure

#

But I use both so shrug

onyx widget
#

yeah, implicit config files only make sense as an explicit choice for an application, not a language's runtime

#

(and should be overridable)

coral violet
onyx widget
#

*replaced with other vulns :P

#

any implicit liabilities can be exploited

#

anyway

stone jewel
coral violet
#

But actually, how would you guys load secrets if not via a configuration file?

onyx widget
#

to be clear, I do agree config file is generally better than putting everything in env vars

#

just don't think it's a silver bullet

coral violet
onyx widget
#

the most powerful tool for avoiding the vulnerability in the first place is having keen awareness of those liabilities

onyx widget
#

and always as a decision of the end-programmer, before it's delivered to the end-user, never as an implicit part of a toolchain or tech stack

stone jewel
#

I use the second one in my own personal hobby server

coral violet
onyx widget
#

should probably carry on discussion elsewhere

coral violet
#

Good idea

stone jewel
coral violet
#

Ping me in #programming-discussion zeroLike

inland blaze
#

155 messages dear god let this thread become a new channel already

analog forge
ancient marten
# onyx widget ie Odin was mostly developed for gamedev

Odin is actually meant to be general purpose, it's just that it ships with a bunch of libraries useful for gamedev. But gamedev is a very wide domain of programming(consisting of graphics, UI, systems, networking etc etc) so "a language for gamedev" isn't really possible without being general purpose

#

Bill is working on adding an http implementation to core

#

we may also see an sqlite module(though he doesn't plan on adding other databases since that would imply creating some kind of cross database abstraction)

ancient marten
#

Odin does generally try to nudge you towards a "data-oriented" style though(with stuff like ZII, soa, using etc). But data-oriented design isn't really specific to games either, It's basically the way to write really fast code(see Andrew Kelly's talk on applying data-oriented design in the Zig compiler)

#

I also personally think it looks beautiful compared to Zig(which is quite verbose)

subtle helm
ancient marten
#

You just solve the problem you have instead of creating more problems

subtle helm
#

Yeah I really like how pragmatic the language is. Frankly I would probably lean toward it over Zig except for two things. I really like having access to structs + functions, and Zigs C interopt is just so nice. I don't have to write any wrapper code, just a couple lines in the build system and import like normal.

subtle helm
#

Yes and no. Zigs solutions of them just being functions that use the dot operator I really like. So Vec2.add(v1,v2) and v1.add(v2) are equivalent

coral violet
#

zig is going to have more math types in the future so...

fierce sage
#

so nesting is really clean

subtle helm
subtle helm
coral violet
#

yes, before 1.0

ancient marten
#

methods do generally encourage a bit of over-organization imo. Should it be weapon.attack(monster) or monster.hitby(weapon)? Odin is opinionated on discouraging you from over-organizing your code. You just have perform_attack(monster, weapon) without it "belonging" to either type

coral violet
halcyon marten
#

Zig is ... not opinionated enough?

ancient marten
subtle helm
ancient marten
#

It's kinda interesting that Odin doesn't have a standard formatter given the design

#

only odin strip-semicolon

subtle helm
ancient marten
subtle helm
#

Not sure I follow. Zig focuses more on reusability?

subtle helm