kristoff_it has quit [Remote host closed the connection]
ltriant has quit [Ping timeout: 265 seconds]
ltriant has joined #zig
batok has quit [Remote host closed the connection]
<stratact>
Hmm, I don't get it. When doing that static size buffer approach for fs.Dir, resolvePosix() does the path correctly the first time especially when inserting a null byte at the end of the true string, but the second time around, it pads the front of the next resolved path with garbage which throws the tests off.
laaron has quit [Remote host closed the connection]
laaron has joined #zig
<THFKA4>
thanks fengb
<stratact>
error.NameTooLong is my worst enemy
jicksaw has quit [Quit: ZNC is kill]
jicksaw has joined #zig
laaron has quit [Remote host closed the connection]
<stratact>
andrewrk: I'm not sure why my tests keep failing with `NameTooLong` each time I try something, but it's beginning to drive me nuts because of how complicated issue #2885 is at a macro scale. I feel this one issue would solve probably +5 other issues on github at the same time if completed.
<stratact>
Either way, it feels like my work is a mess and I would (or should) start over from scratch again but I'm worried about bumping into those similar barriers.
<andrewrk>
what makes it complicated? perhaps you need to experiment with the freebsd API without editing std/ until you have a good idea of how it works?
<stratact>
It's complicated because I'm editing between 4 or 5 different modules in the standard library because the allocator is passed around a lot and I'm adjusting 1 or 2 functions in each of them.
<stratact>
So I've been jumping around a lot tweaking and testing
<stratact>
it really is interconnected with a bunch of other stuff.
<stratact>
and eventually hitting the system.mkdir() syscall...
<stratact>
in one of the tests
<andrewrk>
maybe you can try stashing all that work, with a fresh std/, and then experiment with using the freebsd APIs in a separate test file, where you make a competing implementation
<andrewrk>
once you feel it is working you can try swapping out the official std/ one with it
chemist69 has quit [Ping timeout: 276 seconds]
<scientes>
stratact, you should use git workspace
<andrewrk>
idk what that is
<scientes>
so you can have multiple branches open at the same time
<andrewrk>
scientes, not to 💩 on anyone's parade, but when someone is already struggling with complexity I think the last thing they need is another new thing to learn, that could potentially mess up
<scientes>
oh ok
<stratact>
I think starting over from scratch and making a competing implementation based on FreeBSD is a great idea, that way I can have more freedom to refactor and learn. I suppose I could learn other git workflows but that's not a high priority atm.
<andrewrk>
stratact, you will probably also benefit from whatever the freebsd equivalent of strace is
<stratact>
there is dtrace, iirc?
<andrewrk>
maybe truss?
<stratact>
That too
<scientes>
a fresh checkout is a great idea
<scientes>
and then use git diff to see what you have changed
<stratact>
indeed
<stratact>
I'm really good at refactoring and simplication but only if I understand the code well.
<stratact>
*simplification
<andrewrk>
scientes, never mind the @byteSwap thing. I typed out an entire proposal and then changed my mind
doesntgolf has quit [Read error: Connection reset by peer]
ltriant_ has joined #zig
ltriant has quit [Ping timeout: 240 seconds]
ltriant_ has quit [Ping timeout: 240 seconds]
_whitelogger has joined #zig
ltriant has joined #zig
ltriant has quit [Ping timeout: 240 seconds]
mahmudov has quit [Ping timeout: 240 seconds]
ltriant has joined #zig
<bgiannan>
So what's the best practice to deal with with error sets? I've been mostly relying on zig inferring them but it doesn't work on recursive functions. Should I manually gather all possible errors into a custom set? Use `catch` to throw custom errors instead of using `try` ?
ltriant_ has joined #zig
ltriant has quit [Ping timeout: 268 seconds]
ltriant_ has quit [Client Quit]
return0e has quit [Ping timeout: 250 seconds]
<mq32>
bgiannan: should be possible to just merge all possible error sets with the || operator
alexander92 has joined #zig
return0e has joined #zig
<stratact>
andrewrk: I made a BufTracker type that worked with std.fs.makeDir in FreeBSD
kristoff_it has joined #zig
<stratact>
It was really simple to implement too
<stratact>
I was somewhat inspired by seeing that `Buf` type in your compiler code although this buffer is statically sized.
kristoff_it has quit [Ping timeout: 265 seconds]
laaron has quit [Remote host closed the connection]
<mq32>
stratact, have you made the "hardcode test" already?
<mq32>
listing / of your system?
<stratact>
I haven't written any extra tests. But basically I just used my own written buffer tracker type to manage the assignment of bytes from other path strings directly to the static sized buffer and have know when to slice it when I need it. Such a simple implementation made my life much easier.
<stratact>
and perhaps can be used to simplify std.fs further
<stratact>
and hopefully make things more robust
mahmudov has joined #zig
lunamn has quit [Ping timeout: 240 seconds]
lunamn has joined #zig
alexander92 has joined #zig
_Vi has joined #zig
kuon has quit [Quit: WeeChat 2.5]
<_Vi>
"Precedence" section of documentation seems to have more operators than preceding "Table of Operators" section. Is it by design or the latter is yet to be completed?
slusenti has quit [Remote host closed the connection]
<_Vi>
Does casting from `undefined` to e.g. i32 freezes a value or leaves it as LLVM's `undef`/`poison`?
firefox317 has joined #zig
<firefox317>
I'm trying to solve the _DllMainCRTStartup issue. Should we provide the mingw implementation of _DllMainCRTStartup when using --library c?
<mq32>
firefox317, what does the function do?
<mq32>
calling constructors/initializing values?
<firefox317>
Jupp also calling DllMain
<firefox317>
Basically initializing values yes, right now we have a implementation of the function in start_lib.zig that does nothing
<mq32>
should be doable 100% in zig and that function can mimic the _DllMainCRTStartup function
firefox317 has quit [Remote host closed the connection]
firefox317 has joined #zig
<firefox317>
Yes I see, but if we are already using library c, why don't we just use the mingw implementation?
firefox317 has quit [Ping timeout: 260 seconds]
mahmudov has quit [Remote host closed the connection]
<Tetralux>
_Vi: undefined is a value, not a type, so you cannot cast from it.
<Tetralux>
It's 0xaa in safe modes, and unknown in release-fast IIRC.
<Tetralux>
It's just a special value.
<_Vi>
Tetralux, "undefined can be implicitly cast to any type"
<_Vi>
Tetralux, "Once this happens, it is no longer possible to detect that the value is undefined." Does it correspond to LLVM's `freeze` operation?
<andrewrk>
bgiannan, when inferred error sets don't work, it's time to specify the set explicitly. you can start with an empty set and you'll get errors telling you what is missing
<andrewrk>
_Vi, which operators?
<Tetralux>
_Vi: It's like comptime_int; but it will cast to _any_ value instead of just integer types.
<_Vi>
andrewrk, For example, array access operator []. Arrays are mentioned only twice in that table: for `++` and for `**`.
<andrewrk>
sounds like the table is incomplete
<_Vi>
[about undefined] For example, is it allowed to iterate on initially `undefined` value, expecting convergence to a known value? In Rust or C, using e.g. undefined `u8` is undefined behaviour even if for all 256 possible values it is OK.
<fengb>
It’s undefined behavior
<_Vi>
For example, taking undefined `u32` value, then doing right 1-bit shift 32 times. I should be 0 for any value. But for C in LLVM it is UB.
<fengb>
It’s LLVM undefined so the optimizer can do whatever it wants to
<andrewrk>
branching on an undefined value is undefined behavior. u8 can still be undefined.
<bgiannan>
andrewrk, right but shouldn't i always specify the errorset and only rely on inferring in particular cases?
<_Vi>
If `freeze` operation is applied on that cast, than this "poisoned" value turns into some unknown, but concrete bit pattern.
<andrewrk>
zig has no such freeze operation
<_Vi>
Then this phrase in documentation may be misleading: "undefined means the value could be anything, even something that is nonsense according to the type. ".
<andrewrk>
however some operations are defined to ignore the other operand in some cases. for example, `u32(x) >> 32` is comptime 0, even if x is undefined
<_Vi>
What about iterating `u32(x) >> 1` N number of times, where N at runtime happens to be 32?
<_Vi>
If `undefined` means unfrozen "poison" then it is not "some unknown value", but special thing, not representable by any bit pattern. It means LLVM may delete chunks of your code.
<_Vi>
Maybe Zig should expose special built-in operation like @freezeUndefined, turning undefined value into an arbitrary, but non-always-UB-inducing value.
<Tetralux>
All undefined actually is meant to be is "don't initialize this".
<Tetralux>
The fact that it's an actual value rather than just having semantic meaning is largely an implementation detail.
<andrewrk>
_Vi, there is no "freeze" so the result will continue to be an undefined value. (no undefined behavior though)
<andrewrk>
I think the use case for this is really advanced. The only reason you would do this over setting the value to some hard coded known value would be micro optimization
<_Vi>
andrewrk, How can it be undefined value, yet no UB for operations on it? As far as I understand, `int foo() { uint32_t x; return x & (~x); }` is UB in today's C. Is similar function UB in Zig?
<andrewrk>
C has a lot of unnecssary UB. Zig has it only where it makes sense
<_Vi>
andrewrk, Is it like with infinite loop without side effects? By the rules not UB, but de-facto UB?
<Tetralux>
In safe modes, you'd get `0xaa & (~0xaa)`
<_Vi>
Tetralux, I mean in `--release-speed`.
<_Vi>
*--release-fast
<Tetralux>
In release-fast, the variable is uninitialized and you'll get `uninit & ~uninit`.
<_Vi>
Isn't `uninit` going to be removed from LLVM in favour of `poison`?
<andrewrk>
_Vi, in zig this example translates to: fn foo() c_int { var x: u32 = undefined; return x & (~x); }. The function returns undefined, and that is allowed. This is well-defined. No branching on undefined occurs
<Tetralux>
When I say 'uninit', I mean, that it's uninitialized.
<Tetralux>
I'm not talking about LLVM special values here.
<andrewrk>
_Vi, zig the language does not depend on llvm. zig defines how this program behaves. However, yes, llvm will mark that as poison, but it's not UB unless branching on it occurs
<Tetralux>
Literally the same as C, if you did `var a: u32 = undefined; return a & ~a; `
<andrewrk>
or ptr deref, or other operations than can UB depending on operands
<andrewrk>
if C has UB there then it's not literally the same as C. please be careful when speaking authoritatively Tetralux
<_Vi>
It is example of function where insertion of `freeze` would make it always return 0. Documentation is not explicit enough for it. The only phrase that hints is "Using this value would be a bug.". But "the value could be anything, even something that is nonsense according to the type" acts in reverse and reinforces old school thinking that "it is probably something that was in that memory and register before our code gets executed".
<Tetralux>
andrewrk: Can we stop talking about undefined behavior in two different ways.
<andrewrk>
_Vi, I agree, and I will reword that before closing the issue
<Tetralux>
It's the same as C, unless I'm very much mistaken, because in both Zig and C the value will have an abitrary value, since it's uninitialized. But yes, you know what it's gonna do - it's not "undefined behavior" in a literal sense, even though C would call it that.
<andrewrk>
Tetralux, elaborate?
<Tetralux>
UB in C is "does whatever it wants" but calls things that that are not that.
<Tetralux>
Zig does not.
<Tetralux>
C calls the returning uninitialized values UB, but it's not.
<Tetralux>
Which language's UB you are referring to matters.
<Tetralux>
This is why I hate UB and using it to describe anything.
<companion_cube>
U can be "unspecified" or "undefined", right?
<andrewrk>
in this context UB means Undefined Behavior
<Tetralux>
^
<andrewrk>
Tetralux, UB means the same thing in Zig & C. C has UB in a lot of surprising places.
<companion_cube>
I mean, in C sometimes things are compiler dependent but not really UB, I thought
<companion_cube>
(please don't mind me)
<Tetralux>
You just gave a clarifying example before; C would call returning an uninit value UB, but Zig would only call it UB if you branched on it.
<Tetralux>
You literally said it yourself :)
Nazral has joined #zig
<Tetralux>
That makes the two different.
<andrewrk>
I have not verified in the spec that returning uninitialized locals in C is UB. But it would not surprise me
<Tetralux>
Yeah but insert whatever you want there.
<andrewrk>
_Vi's claim is that in C it is UB. Meaning actual undefined behavior. Not a different definition of the same words
<Tetralux>
My point is, my definition of UB requires branching.
<Tetralux>
because that's sane.
<andrewrk>
there is only one definition of UB across all languages
<andrewrk>
the question is, what counts as UB?
<Tetralux>
.. except that C poison's it by using it for more things than it should.
<Tetralux>
Which in practice, are not.
<Tetralux>
AFAIK anyway.
<Tetralux>
I'm honestly not sure it's helpful to even use UB to describe anything.
<Tetralux>
There's platform-specific behavior.
<Tetralux>
And that's about it, off the top of my head.
<Tetralux>
Likewise, `orelse unreachable` means "you might dereference null"
<Tetralux>
(which may not segfault btw).
<Tetralux>
So I'm lead to believe.
<_Vi>
Commented on #1947 with an example.
drasko has quit [Ping timeout: 276 seconds]
_Vi has quit [Ping timeout: 245 seconds]
halosghost has joined #zig
<mq32>
just a comment on the weirdness of "no overloads":
<mq32>
EndOfTheDay vs. EndOfADAy
<mq32>
*EndOfADay
<mq32>
(how not to do self-documenting code)
<Tetralux>
I'm not sure I understand.
<mq32>
Both functions perform the same job (for a given date value, compute the end of that day)
<mq32>
one takes (int day, int month, int year)
<mq32>
the other one takes (DayTime)
<fengb>
That's heresy
<fengb>
Everyone knows it's year, month, day
<companion_cube>
^
<companion_cube>
yes please
<companion_cube>
rfc3339 ftz
<companion_cube>
ftw
<Tetralux>
First, yeah - absolutely do year-month-day order of params.
<Tetralux>
But yes
<mq32>
Tetralux: this is real-world example. not my code, i just stumbled up this in the documentation of a lib
<Tetralux>
Definitely should not have "ADay" vs "TheDay" in code xD
<mq32>
also, as "some day" there was introduction of overloads, this happend:
<mq32>
ADay(int year, int dayOfYear)
<fengb>
It should try to reorder month/day/year intelligently, like how PHP stdlib tries to reorder arguments
<Tetralux>
mq32: This clearly doesn't seem good xD
<mq32>
tell that Borland/Embarcadero :D
<Tetralux>
I'm not sure what you could do without overloading there.
<fengb>
"Day" is actually very ambiguous when it comes to date :(
<Tetralux>
Is it though?
<Tetralux>
Considering that it literally in the date format?
<fengb>
Day of week, day of month, day of year
<fengb>
Yes but context can subtly change it dramatically
<Tetralux>
I mean, you mean day of year.
<companion_cube>
in this format it's day of month, isn't it?
<Tetralux>
Or yeah
<fengb>
I'd hope so... but
<Tetralux>
I ain't awake yet lol
<companion_cube>
it's additive increments
<Tetralux>
Day = day of month.
<fengb>
I wish there's a better term than "day" when it comes to YYYY-MM-DD
<Tetralux>
But you might actually want the day of the year.
<fengb>
Or rather, less ambiguous
<companion_cube>
then remove the month
<companion_cube>
otherwise there's redundant, possibly contradictory, information
<Tetralux>
You wouldn't have both in the structure
<Tetralux>
But
<fengb>
Sometimes I wish we could fix real language
<Tetralux>
You might want always one or always the other, or the day of month, but occassionally want to compute the doy.
<fengb>
Because this is a pain point in English, and not just programming
<Tetralux>
date.dayOfYear(); :)
<Tetralux>
date.dayOfMonth();
waleee-cl has joined #zig
<Tetralux>
date.dayOfWeek();
<fengb>
Sorry about the tangent :P
* Tetralux
grins
<Tetralux>
yearDay(), monthDay(), weekDay()
<fengb>
There's also day/night
<Tetralux>
That one you'll need to give an example for :)
<fengb>
The zone is super important when talking about the future
_Vi has joined #zig
<fengb>
You can get away with it talking about the past... but then you lose a bit of semantic meaning
<Tetralux>
I cannot help it if people change the timezone out of under me.
<fengb>
Yes you can, use a TZ aware library
<Tetralux>
I deal with ISO days, minutes, seconds, etc.
<Tetralux>
xD
<Tetralux>
Or rather I'd like to.
<Tetralux>
fengb: To quote Tom Scott :p
<mq32>
> Except for Morocco, where in the middle of summer, DST is suspended for a month during Ramadan (depending on which year it is).
<mq32>
what kind of hell is this?! :D
<fengb>
Also, storing offsets is also wrong because TZs change offsets
<fengb>
Human time is just a hard problem
<Tetralux>
Why is why I have no wish to deal with human time xD
<fengb>
We could get away with it if we just kill all humans :/
<Tetralux>
Which is*
<Tetralux>
No
<Tetralux>
Just make UTC universally used.
<Tetralux>
Oh, your in Australia? That means you get up at 8pm.
<Tetralux>
In the UK? That means you get up at 10AM.
<fengb>
Why does Australia have 8 timezones? :/
<fengb>
I thought the US was bad
laaron has quit [Remote host closed the connection]
<alexander92>
it doesn't
<halosghost>
Tetralux: note that that still doesn't solve all problems with calendars
<alexander92>
does it
<halosghost>
Tetralux: namely, people use different calendars
<Tetralux>
halosghost: I'd use ISO calendars xD
<halosghost>
what ISO calendar?
<Tetralux>
Whatever they are.
<halosghost>
that RFC, ISO standard, POSIX, etc. all implicitly assume Gregorian
<Tetralux>
All months are 28 days would be a good start.
<halosghost>
(technically, POSIX isn't implicit, but it's only documented in the giant spec)
<halosghost>
Tetralux: that would mess up everything
<fengb>
Islamic calendar is used for a few things, but I don't think necessarily day-to-day
<mq32>
13 months, each month has 28 days, 2 "start of the year" days without having a weekday assigned...
<halosghost>
but the point is, there are reasonably easy ways of storing dates such that you don't actually have to assume a calendar
<fengb>
Similar with the Chinese lunar calendar
<halosghost>
mq32: that's roughly the international fixed calendar, yeah
<Tetralux>
halosghost: Sounds good.
<halosghost>
personally, there's one I prefer much more than those
<Tetralux>
Name it :D
<fengb>
So detach days from years? That'd make programming easier but hurt human perception
<halosghost>
but, again, it doesn't matter; the ideal should be to allow people to use whatever calendar they want (so long as it's reproducible), and to have your datetime format respect it (just as datetime formats can reasonably respect timezones easily now)
<fengb>
Let's just change the Earth's orbit/rotation so they're perfectly aligned
<halosghost>
fengb: the way to do it is to pick a lingua franca that all calendars can be converted to/from easily (much like what UTC does for timezones)
<mq32>
fengb: nice. i like simple and pragmatic solutions to complex problems!
<fengb>
halosghost: Almost everyone is on the gregorian calendar atm so it's not a big problem
<halosghost>
fengb: in particular, most calendar folk use a fixed day number system (think UNIX epoch time, but counting integral days instead of integral seconds) with an epoch that everyone can agree upon (usually, people use Gregorian 1 January 1)
<halosghost>
fengb: that is not true
<fengb>
But gregorian is a pain to program for so... >_>
<halosghost>
fengb: and is an unfortunate myth perpetuated by our industry
<halosghost>
plus, the Gregorian leap rule is incredibly poor, and if we want to keep using things like GPS (and have clocks read the same time), we're going to have to reform it
<Tetralux>
Certainly, my inclination is that it things should be defined to an evenly divisable number of seconds.
<halosghost>
so, instead of putting all our eggs in one basket (that's already full of holes), we could instead just make it so that things actually are flexible enough to allow reform, mobility, and cross-talk
<Tetralux>
Sounds sane to me.
<Tetralux>
The work of converting between TZs should not be part of a date calcuation, that much I know.
<halosghost>
the easiest sane storage format then for a date is to just store the FDN Rata Die (the fixed day number using Gregorian 1 January 1 as the epoch)
<Tetralux>
That assumes calendar....
<halosghost>
converting from that to gregorian is pretty easy, and great work has been done to allow converting between that and many other calendars
<fengb>
TZ needs to be a part of date. Otherwise we have to agree on a new definition of "start of day"
<halosghost>
Tetralux: in the same way that UTC “assumes GMT”
<companion_cube>
there's tons of RFCs on that…
<halosghost>
Tetralux: it just gives everyone an easy and consistent target for conversion
<halosghost>
Tetralux: and, it's already the standard in calendrical circles
<Tetralux>
halosghost: Which is why I'm inclined towards it.
<halosghost>
companion_cube: oh?
<halosghost>
I'm not aware of any
<Tetralux>
But I'd rather no assumptions were being taken here.
<companion_cube>
I mean, RFC3339, store dates with that
<companion_cube>
and then the unix APIs, is all
<halosghost>
companion_cube: are you talking about what I'm talking about or about packaging TZ in the time format?
<companion_cube>
the latter
<companion_cube>
sorry
<halosghost>
no worries
<companion_cube>
was on a call, I'm probably out of context
<halosghost>
Tetralux: if you want a much better calendar than the IFC, look up Symmetry454
<halosghost>
Tetralux: the person who invented it also includes the arithmetic to convert freely between Gregorian and Sym454 (via FDN Rata Die) royalty-free and public-domain
<halosghost>
Tetralux: to give you a taste of what needs to be done
<halosghost>
(I'm also prototyping a library to make conversion between calendar dates much easier)
marijnfs has joined #zig
<fengb>
RFC3339 only captures offsets, which isn't the same as zones
<companion_cube>
hmmmmmmmm
<companion_cube>
ok then I'm lost :3
<companion_cube>
are there timezones that are not offsets?
<Tetralux>
There are 1/4, 1/8 double-BST etc.
<fengb>
A timezone can have multiple offsets
<fengb>
Daylight savings time is the prime example
<Tetralux>
1/8, double-BST*
<Tetralux>
UK had 2xBST througout WWII IIRC.
<companion_cube>
all I know is that gmtime has that info :D
<companion_cube>
(the DST)
<Tetralux>
And some countries lost half a year at, at least one point in history.
<Tetralux>
Dec 31 -> Mar 21st, or whatever it was.
<companion_cube>
:DDDDDDDDDDD damn
<fengb>
Yeah we work with it with zones like America/New_York
<Tetralux>
.. which I always hate because UTC is never an option :")
<Tetralux>
The fact that I cannot pick UTC as my wall clock in Linux is atrocious.
<Tetralux>
Also yeah, probably should only use calendars for displaying dates to a user...
<fengb>
I fixed an offset problem by shifting Arizona local time (user) into New York local time (financial markets)
<fengb>
It sucks... but it's needed
<Tetralux>
How many of you would prefer all times are epoch timestamps? :)
<companion_cube>
I'd like all times to have an offset specified, at least
<halosghost>
let me go grab my time format string :P
<fengb>
The offset was the problem there. Arizona doesn't have DST so the times stopped correlating during summer
<Tetralux>
>:)
<halosghost>
I have one that I always use
<fengb>
We assumed consistent offsets and it broke Arizona
<Tetralux>
I want, exactly one, method of storage and quick computation, that is universal. Forever.
<halosghost>
"%H.%M (%Z) | %A, Gregorian %d %B %Y"
<fengb>
It probably broke for foreign countries too... but that wasn't as important >_>
<halosghost>
roughly, that's the string I use with strftime() ^
<Tetralux>
halosghost: So, "12:55 GMT", or "_ Gregorian 21 02 2009" ?
<Tetralux>
( I forget what %A and %B is. )
<halosghost>
how it currently renders: 10.46 (CDT) | Thursday, Gregorian 19 September 2019
<Tetralux>
Ah-ha!
<Tetralux>
I'd include seconds, but yes, otherwise I like both of those.
<Tetralux>
10:46:25 (CDT)
<halosghost>
I explicitly don't include seconds because I don't refresh my status bar every second
<halosghost>
(nor on my watch)
<halosghost>
(nor on my phone)
<Tetralux>
I do everywhere ;p
<halosghost>
otherwise, I'd likely include seconds as well
<Tetralux>
Well - where I can :angry:
<halosghost>
Tetralux: I don't really need to know seconds, and it just takes more power
<halosghost>
🤷
<Tetralux>
It takes more power to scroll the IRC window xD
<halosghost>
Tetralux: as for interchange format: two member struct: { FDN_Rata_Die, UTC_seconds }
<Tetralux>
What's the first one?
<halosghost>
FDN Rata Die is the fixed day number starting from Gregorian 1 January 1
<Tetralux>
Okay - so day-wise epoch then :)
<halosghost>
correct, “Rata Die” refers to using Gregorian 1 January 1 as the epoch
<halosghost>
Tetralux: or, for that matter, u512 nanos
<halosghost>
s/nano/micro/
<halosghost>
oh, you're assuming the start of the day is 0 in seconds and nanos
<Tetralux>
Exactly.
<Tetralux>
Because that's sane.
<halosghost>
then seconds doesn't need to be u32
<halosghost>
u16 is even overkill
<Tetralux>
Which is why you just have nanos instead.
<halosghost>
u64 is massively overkill for nanos then
<Tetralux>
Well - 1e9 - whatever size that is :P
<halosghost>
also, why nano and not micro?
<halosghost>
hell, let's just do yocto
<Tetralux>
Or attos :p
<halosghost>
yocto is the smallest
<Tetralux>
I picked nanos because that's the smallest unit of measurement on every system I've measured time on.
<fengb>
nano is smaller than micro
<Tetralux>
fengb: Yes it is.
<Tetralux>
nano, micro, milli, unit :)
<halosghost>
if you want a format that lasts forever, don't bind yourself to a system
<Tetralux>
I am however open to using smaller units.
<Tetralux>
Hey - I'd pick attos if reasonable.
<fengb>
Nothing lasts forever
<halosghost>
u97 is more than enough to store the yoctoseconds of a day
<fengb>
We'll be on a new galactic standard soon™
<Tetralux>
So long as I know the power of ten and can do it quickly and losslessly.
<fengb>
Our time is too earthcentric
<halosghost>
anywho, if y'all are actually putting together a datetime format, let me know if you want to make it actually portable
<halosghost>
:)
<companion_cube>
😅
<Tetralux>
I like portable :)
<companion_cube>
datetime is one of these rabbit holes
<fengb>
I've come to realize that time is subtly about 3 different domains
<fengb>
And we don't even realize we're talking about them differently
<Tetralux>
Shoot.
<Tetralux>
Surprise me.
<fengb>
Next Tuesday at 12
<fengb>
That could mean, exactly on UTC
<fengb>
On my local time
<fengb>
or a recurring thing that shifts depending on other contexts
<fengb>
Or it means relative to the person I'm talking to
<Tetralux>
Yeah, the timezone is implicit when you say it.
<fengb>
There's another aspect that I remember thinking about
<fengb>
Someone was building a temporal database with 2 dimensions of time... but I needed to introduce a 3rd dimension for some reason
<fengb>
I don't remember why but it really hurt my brain
<fengb>
Accounting is a good example of having an extra dimension of time
<companion_cube>
and: appointments are fixed, but alarms are always local ;)
<fengb>
When you book money, you need it booked. But sometimes that booking is wrong, so you need to fix it in the past while simultaenously not affecting the current values
<fengb>
Guh, it's too early for me to think about this
<firefox317>
stratact: Regarding the question you asked on your PR, andrewrk means this: // comment <newline> if (builtin.single_threaded) return error.SkipZigTest; <newline> //comment <newline> if (std.os.freebsd.is_the_target) return error.SkipZigTest;
<stratact>
Gotcha, thanks.
meheleventyone has joined #zig
firefox317 has quit [Remote host closed the connection]
firefox317 has joined #zig
laaron has joined #zig
laaron has quit [Client Quit]
laaron has joined #zig
laaron has quit [Client Quit]
laaron has joined #zig
<andrewrk>
llvm 9 released
<andrewrk>
let's do this
<dimenus>
are you going to benchmark 8 vs 9 at all?
<andrewrk>
nope. are you?
<dimenus>
no, i was just curious. work got much busier in the past couple weeks so i haven't spent much time on zig lately :(
meheleventyone has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
_Vi has quit [Ping timeout: 245 seconds]
alexander92 has quit [Ping timeout: 240 seconds]
<stratact>
Phew, got that FreeBSD event hang out of the way, hopefully I can get my main PR merged in time for 0.5.0 🤞
<stratact>
Although, even though I went through hardship, solving that issue was fun. 😌
<andrewrk>
cheers stratact
<andrewrk>
dimenus, I'll do a quick bench just after merging llvm9 branch, since I have 2 checkouts of zig source
<andrewrk>
stratact, also - I am currently installing FreeBSD on an old laptop
<stratact>
Ah, that's a good idea.
<dimenus>
i wonder if anyone is running zig on a pi4
<stratact>
andrewrk: Hmm, I think for testing Zig, I'd recommend 12-STABLE rather than 12-RELEASE, because the former not only gets the latest bug fixes at the certain snapshot, but they also update llvm 6 to 8.0.1.
<firefox317>
Nice llvm 9, riscv support. I'm gonna buy a FPGA board soon and put a riscv core on it and program it using Zig :)
<stratact>
FireFox317: that sounds amazing
<firefox317>
I mean program code in Zig that runs on the riscv core xD
<fengb>
FPGAs are flexible enough to flash into RISCV?
<fengb>
s/flash/whatever-the-right-verb-is
<andrewrk>
stratact, thanks!
<mq32>
fengb, other way round
<mq32>
you can just put an RISC-V core into an FPGA and run that
<mq32>
called "configure"
<fengb>
Sure, I've only fiddled with FPGAs that had minimal configure capabilities. Never thought it'd be able to switch to a modern CPU
<firefox317>
Well, a FPGA is programmable hardware, so you can basically program any digital device on it
<mq32>
yeah what FireFox317 said
Tetralux has joined #zig
<mq32>
you can do simple logic or run a system with risc-v and AVR core in it
<mq32>
most cheap FPGAs (50$-100$) are already really powerful
<fengb>
Hmm
* mq32
still wants to implement his own CPU on an FPGA
<mq32>
but i'm too lazy and busy to do so
<fengb>
I've only done rudimentary programming with FPGAs, like raw gates and such. I didn't expect millions of transistors to fit into it :P
<mq32>
hehe
<mq32>
the FPGA i have has 50kLUT
<mq32>
each LUT can store up to 32 values
<mq32>
also risc-v cores aren't "millions of transistors"
<firefox317>
Yeah FPGA are getting bigger really fast
<andrewrk>
I caught a regression in rc4 in time to fix before the release
<andrewrk>
windows build: in progress. linux build: in progress. freebsd build: stalled, having freebsd OS installation trouble. asking for help in #freebsd. macos: about to start
DixiE76 has joined #zig
_Vi has joined #zig
wootehfoot has quit [Quit: Leaving]
wootehfoot has joined #zig
Akuli has quit [Quit: Leaving]
DixiE76 has quit [Remote host closed the connection]
<Tetralux>
mq32: You got any resources for getting into programming an FPGA?
<mq32>
whoo
<mq32>
good question
<mq32>
"just hack shit together" and read some random stuff online is my way of life
<mq32>
the first question you want to answer is: "do i want to do verilog or vhdl"
<mq32>
which is kinda weird, because you *could* intermix those languages, but you are not allowed until you pay a lot of money to the makers of the FPGA IDE makers
doesntgolf has joined #zig
halosghost has quit [Quit: WeeChat 2.6]
<THFKA4>
what's the best way to interop with C++? make a shim layer in C first?
<fengb>
Yeah, there's some example shims around clang and llvm
firefox317 has quit [Remote host closed the connection]
<THFKA4>
great, thanks again!
meheleventyone has joined #zig
<_Vi>
Why not allow `{ 4 }` / `fn z() i32 { 4 }` instead of `lbl: { break 4; }` / `fn z() i32 { return 4; }`? Is it a fixed design decision or subject to change later?
<mq32>
_Vi, implicit return would be implicit control flow and does not fit zigs style of "no hidden control flow"
<_Vi>
How design decisions happen in Zig language in general? Is there an RFC process?
<_Vi>
Lack of semicolon does not look like a hidden control flow.
<mq32>
random people write proposals on github and andrewrk is making a "approved" or "declined" mark after $time
<mq32>
yeah, true. it looks like syntax error
<mq32>
also, it wouldn't fit "one obvious way to do things" as well, as then we would have two ways to return
<andrewrk>
it's mostly just me making all the decisions, consulting a few trusted people, and having an open mind to "random" proposals
<mq32>
btw, i think that's a great process for language development!
<mq32>
having one master mind who gets inspiration, but has a bigger plan which may even be too large to be written down
<fengb>
[B]DFL
<_Vi>
Such process may be not very scalable and "bus factor" is not good... On the other hand, the final result would be more cohesive.
<andrewrk>
you can always make a community fork if I go rogue ;)
<_Vi>
Community fork => design by committee.
<stratact>
I think having a more cohesive result is the best of all worlds.
<fengb>
At some point, the Zig foundation will techalnicly own the language right? :P
<_Vi>
Are there plans for making `what_label_name_to_invent_here: { ...; break 'what_label_name_to_invent_here ...;}` nicer? Or is there standard name for label? I see `blk` multiple times in the documentation. Can it be considered a "code style" to use this particular label name for this?
<mq32>
i also think that the label syntax is kinda clunky, but i haven't had an idea how to make it more smooth
<andrewrk>
fengb, yes that's the plan
<_Vi>
Such syntax is viable when block is large and/or block value is not at the end of it.
<andrewrk>
this question is common enough I think I should answer it into the FAQ and link to it
<andrewrk>
regarding block expressions
<_Vi>
Maybe language evolution and policy making can also be a FAQ entry?
<fengb>
Split break into breakblock and breakloop :P
<andrewrk>
that's not a bad idea... I hadn't actually considered that one
<andrewrk>
lbreak bbreak
<mq32>
i would propose "blockreturn" instead of break
<andrewrk>
`break` in `switch` is currently ambiguous if you haven't read the docs
<_Vi>
Quick idea (without much thinking): 1. Use `break` only for loops, maybe with label; 2. For labeled blocks, use `return :label value;`; 3. Allow omitting `;` at the end of blocks to make non-void unlabeled blocks.
<mq32>
i like point 2, this has a good semantic read to it
<andrewrk>
we had (3) a long time ago and removed it
<mq32>
blk: { … return :blk 10; }
<fengb>
Add a <- operator
<mq32>
reads like "return to scope :blk"
batok has joined #zig
<_Vi>
Special label name meaning innermost block like `return :_ 5;` or `break :_ 5;`.
<_Vi>
Maybe without lack-of-semicolon-means-result thing, `return` should be shortened to `ret`?
<mq32>
nah, i don't think all this shorting is leading anywhere exceept for unreadable code
<_Vi>
Other topic: will there be any stability commitment after Zig 1.0.0?
<_Vi>
Turning non-block switch arm into a block (to insert printf logging) and back should not be that heavyweight...
<_Vi>
Yet another topic: How to I print things for debugging from comptime{} blocks?
<mq32>
there's a compiler builtin that prints out messages or does compile errors
<mq32>
@compileLog and @compileError
<_Vi>
OK.
<_Vi>
"error: found compile log statement". What is difference between @compileLog and @compileError ?
<andrewrk>
@compileLog prints to stderr before the compile errors
<_Vi>
Are `comptime{}` blocks supposed to be used to generate external files? For example, iterate over struct and generate external schema file based on it. What about the reverse: are `comptime` blocks supposed to read external files and generate code based on them?
<andrewrk>
if you need to generate .zig code, it's suggested to handle that at the build system layer. for the reverse, you can @embedFile and then iterate over the bytes at comptime. it depends on your use case whether or not I would recommend this
<andrewrk>
let's talk about stability commitment later, I have a lot going on at the moment
porky11 has quit [Quit: Leaving]
<mq32>
@embedFile is the dream for everyone who has to embed files *grin*
<_Vi>
If @embedFile result is only used in comptime, but not in runtime, will it be excluded from target object code?
<andrewrk>
that feature is planned but it requires comptime garbage collection, which is not currently implemented
<andrewrk>
well, it should get excluded by the linker, but objects will still unnecessarily have the payload
<andrewrk>
hmm I think that should probably not look outside package path. that's a recipe for system dependencies leaking into projects
<mq32>
yeah, maybe add a set of allowed paths for embedFile
<fengb>
But who's to stop someone from adding '/'?
<andrewrk>
that's fine. I just don't want accidental deps happening
<_Vi>
fengb, That would still be more explicit, especially if only root project allowed to set allowed paths, not deps.
<_Vi>
Adding new `Dummy: noreturn,` variant to `union(enum)` increases its size. Is it supposed to happen?
<andrewrk>
should be a compile error, noreturn is not a valid union field type
<_Vi>
Why?
<_Vi>
It just means that variant is 'erased' from the tagged union.
<andrewrk>
are you perhaps looking for `void`?
<_Vi>
No.
<andrewrk>
what is expected behavior?
<mq32>
huh? _Vi what do you want to achieve?
wootehfoot has quit [Read error: Connection reset by peer]
<_Vi>
Currently just playing around with type system, looking how close void and noreturn follow Unit type and Zero type.
<andrewrk>
if it's not a valid tag then it shouldn't be one of the union fields
<_Vi>
Maybe sometimes it's easier to exclude variant by making its type `noreturn` (from generated code or whatever) than to actually remove the variant.
<companion_cube>
that's an interesting point, though, `void` should have size 0, and `noreturn` should make the case impossible
<companion_cube>
(pretty sure rust is able to turn `Result<T,!>` into `T`)
<andrewrk>
_Vi, I don't buy that as a real use case
<companion_cube>
what if you have a generic type, but one of the generic parameters isn't used at all?
<_Vi>
"Short circuiting" structs into non-existance by adding a `noreturn` field is also from the same bag of tricks. But it does not work, neither in Zig nor in Rust.
<_Vi>
(because of partial initialisation)
<andrewrk>
if we can come up with a real use case - using generics for example - then alright let's do the unit/zero type thing
<_Vi>
There can be generic tagged union that you expect to be zero-sized most of the time. But for some corner cases it is actually non-zero-sized (e.g. there is indeed information to remember).
<_Vi>
All sorts of "strange, nobody would write code that way" things arise when using code generation.
<andrewrk>
zig language is designed to be source code, not output code
<andrewrk>
I understand there are reasonable use cases for the latter. but they're not primary
<andrewrk>
for a tagged union, it's really a question of where to put the compile error. is it at the declaration of the type? or at field access?
<companion_cube>
(also it should remove the tag from exhaustive `switch`)
<_Vi>
andrewrk, Maybe at attempt of creation of value of such variant (except of from using noreturn function).
<_Vi>
Although I think `noreturn` variants or struct fields is not an error (just tricky corner case), there still seems to be a bug about them: https://github.com/ziglang/zig/issues/3255.
<_Vi>
"not getting" why noreturn is a reasonable type is a bit like "not getting" why number zero is a reasonable number in mathematics...
<_Vi>
Why code after calling `noreturn` function is a compile-time error? This gives Golang vibes...
<companion_cube>
you mean, dead code?
<_Vi>
This also can force codegens to actually remove lines of code instead of just cascadingly "neutralizing" them.
<_Vi>
companion_cube, Yes. Can this error be disabled for a block of code?
<companion_cube>
idk
meheleventyone has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
lunamn_ has joined #zig
brodeuralexis has joined #zig
lunamn has quit [Ping timeout: 245 seconds]
brodeuralexis has quit [Remote host closed the connection]
brodeuralexis has joined #zig
Pwipwi has joined #zig
<Pwipwi>
hello, does anyone know how to replicate __attribute__((constructor)) in a shared library ?
<Pwipwi>
I'm trying to write a node addon with napi
<Pwipwi>
and I'm stuck at registering my module
<_Vi>
`error: unions must have 1 or more fields` - Why? How do I create `noreturn`-equivalent tagged union?
<_Vi>
Is something like assert_eq(a, b), so that I immediately know the value I need to insert, not just the line number?
<waleee-cl>
std.testing.expect / std.testing.expectEqual? (staring at linked_list.zig from std right now)
<_Vi>
`error: type 'noreturn' cannot be optional` => why not `?noreturn` == `void` for codegen?
<_Vi>
Looks like `noreturn` is a "second class citizen" in the land of Zig types...
<waleee-cl>
oh, it was priority_queue.zig
<brodeuralexis>
Pwipwi, what about calling your __attribute__((constructor)) function before returning from the function registered with NAPI_MODULE. I think __attribute__((destructor)) could also be implemented with napi_add_env_cleanup_hook.
<Tetralux>
_Vi: noreturn is first class; more to the point, in what world does ?noreturn make any sense?
<_Vi>
Tetralux, As usual, for `?T` where T happens to be noreturn when instantiated from user code.
<Tetralux>
I mean, if it's noreturn, it will never return anything; so how does it make sense to either be "this will never return anything" or "will return something"
<Pwipwi>
I can call a function from toplevel ?
<Tetralux>
If it's optional, it must return a value.
<Tetralux>
Furthermore, noreturn is not a value.
<_Vi>
Tetralux, Obviously such optional will be always `null`.
<Tetralux>
So it can't be an optional.
<_Vi>
Tetralux, `noreturn` is a type with 0 possible values.
<Tetralux>
Indeed, so it can't be optional, because it's either false, or (true, value)
<_Vi>
Tetralux, Optional adds one value to the list: `null`. `&noreturn` therefore has 1 possible value, like `void`.
<Tetralux>
Optional is (bool, T) not (null | T)
<Tetralux>
You cannot take the address of a noreturn?
<_Vi>
Tetralux, Optional pointer is not (bool, T).
<Tetralux>
You have a *noreturn? xD
<_Vi>
Pointer to noreturn is also noreturn-equivalent (i.e. a type with no values).
<brodeuralexis>
Should’nt it be a compile time error to use (but not declare) a runtime variable of type `noreturn` ?
<_Vi>
brodeuralexis, Should be OK, but only in "unreachable code".
Pwipwi has quit [Remote host closed the connection]
<brodeuralexis>
From what I understand, `noreturn` should behave like Rust’s `enum Void {}`.
<_Vi>
brodeuralexis, Yes. But currently it is much more restricted in Zig compared to `!` in Rust.
<_Vi>
That can be problematic for generic or codegenerated code.
<Tetralux>
What's an example of this?
<companion_cube>
I posted a rust playground link above
<companion_cube>
err, godbolt
<Tetralux>
I mean in Zig.
<companion_cube>
well, should be similar
<Tetralux>
What's an example of Zig code you can't write because of this?
<_Vi>
Tetralux, Example of what? Of optional noreturn? Of declaring / using noreturn variable?
<brodeuralexis>
What would `List(noreturn)` do ? What about `allocator.create(noreturn)` ?
<_Vi>
brodeuralexis, `List(noreturn)` probably `void`-equivalent. It can only be empty.
<_Vi>
(Looking up what is `allocator.create`)
<_Vi>
brodeuralexis, Is `allocator.create` like a malloc?
<Tetralux>
It allocates a value of type T
<brodeuralexis>
It’s the interface for allocating memory `std.mem.Allocator`.
<_Vi>
In Rust, for memory purposes `void` analogue and `noreturn` analogue are considered equivalent.
<brodeuralexis>
But Zig is not Rust.
<_Vi>
What `allocator.create(void)` does?
<brodeuralexis>
`allocator.create(T)` allocates `sizeof(T)` memory (using malloc, or mmap, another allocator)...
<_Vi>
What does it do with size-0 allocations? Assuming it hands out 0-sized pointers which are all equivalent to each other.
<_Vi>
Memory allocation for storing result of function that will never return may be skipped just like allocation of `void`.
<brodeuralexis>
Right now: `if (@sizeOf(T) == 0) return &(T{});`. A pointer to data that can never be read or written.
<brodeuralexis>
Having `noreturn` be more powerful than it already is would make the language a bit weird.
<brodeuralexis>
The only use case for `noreturn` that I have found is low-level programming where you are on a `freestanding` platform and `main` will never finish.
<brodeuralexis>
If you want to specialize a generic for an empty type, why not do so for `void` ? In that sense, I could specialize a `Map([]const u8, void)` to behave like a `Set([]const u8)`.
<_Vi>
brodeuralexis, It is similar how in Rust there were `fn neverreturn() -> ! { ... }` from the beginning, but now that `!` gets promoted to fully-fledged zero type usable in all contexts.
<_Vi>
brodeuralexis, `noreturn` can be optimisation material if it affects memory layout of unions.
qazo_ has quit [Read error: Connection reset by peer]
<brodeuralexis>
That I understand, it is like Haskell’s `Void` and TypeScript’s `never` type. What gains would its presence as a fully fledged type bring to Zig ?
qazo has joined #zig
<_Vi>
brodeuralexis, Probably some additional abstraction abilities, acting as "neutralizer" to other types. Removal of special casings in generic code. Marking code paths as impossible from type system (without explicit branching in comptime blocks).
<_Vi>
Basically the same as "why `void` is a type`, but going further into the land of abstractions.
<brodeuralexis>
So while Zig’s `void` will act as unit, `noreturn` should act as a bottom type ?
<_Vi>
brodeuralexis, Yes.
<brodeuralexis>
From Wikipedia: The bottom type is frequently used for the following purposes:
<brodeuralexis>
1. To signal that a function or computation diverges
<brodeuralexis>
That is the purpose of `noreturn` as a return type.
<brodeuralexis>
2. As an indication of error
<brodeuralexis>
That is the `!void` return type.
<brodeuralexis>
Or `error{…}` return type if only an error can be returned from the function.
<telemach>
is @fieldParentPtr still the way to do interfaces in Zig? Can't find any updates in relevant issues, except mention of std.meta.trait, but I can't figure out how exactly to use it in this role.
<telemach>
also many months ago i've seen a link how to replace interfaces in zig with some kind inversion of the concept, but i struggle to remember details and find the link
<andrewrk>
first 2 are compilation performance, second 2 are runtime perf of std lib hash functions. we don't really have a good set of runtime performance benchmarks yet
<telemach>
did anyone rolled up own interface solution willing to share?
<fengb>
Looks like compilation is 0.1% slower :P
<telemach>
there are some caveats with fieldParentPtr which trick me frequently, i'm thinking about trying to avoid it for now
<andrewrk>
fengb, yeah I think that's within the error bars if I just rerun the same benchmark
<fengb>
Looks like debug mode is faster by ~3-10% and release-fast is unaffected
<fengb>
Oh LLVM posted about Rust LTO. Would that apply to Zig as well?
<andrewrk>
currently zig wouldn't benefit from LTO because it puts everything into 1 object file
brodeuralexis has joined #zig
<_Vi>
"everything into 1 object file" -> Including C code built with `zig cc`?
<mikdusan>
there was a post about combining clang and rust lto. they ran into an issue where lto didn't cross the 2 boundries because clang had some kind of (target?) attribution that disqualified it
<_Vi>
Does cross-language LTO between C and Zig work?