ChanServ changed the topic of #zig to: zig programming language | ziglang.org | be excellent to each other | channel logs: https://irclog.whitequark.org/zig/
<hryx>
I just tried to compile something with `zig build-exe` and got "unreachable" and SIGABRT. Is that an internal compiler error I should report somehow?
<MajorLag>
compiler asserts are always bugs, but are you sure it wasn't an unreachable in comptime code? Issues can be reported github: https://github.com/zig-lang/zig/issues
<hryx>
I have no expressions with the `comptime` keyword, but I'm not sure
<andrewrk>
I think it's a bug
<MajorLag>
the standard library does, but if you ran into one it's probably still a big
<MajorLag>
*bug
<andrewrk>
zig_unreachable() in the c++ code prints "unreachable" and then aborts
<hryx>
sounds like what I saw
<hryx>
I can open an issue with a link to a gist if that's the best way to report
<andrewrk>
that would be appreciated
<hryx>
I think I've narrowed it down to a pub fn defined inside an enum type
<GitHub29>
zig/master 1c41f1c Andrew Kelley: better error reporting for missing libc on windows...
<andrewrk>
let me know if that doesn't solve the problem
<MajorLag>
I don't think it will, but I'll give it a try when it finishes building. Here's my commandline: zig build-exe test.zig --msvc-lib-dir E:\Experimental\VC\BuildTools\lib\x64\ --kernel32-lib-dir E:\Experimental\VC\BuildTools\umlib\x64\ --libc-lib-dir E:\Experimental\VC\BuildTools\ucrtlib\x64\ && test.exe
<MajorLag>
process monitor appears to confirm that all libraries were found, but it still exits 1
<andrewrk>
I'll try running this on windows
<MajorLag>
looks like it writes the object files just before exiting.
<andrewrk>
no error message?
<MajorLag>
nope
<MajorLag>
my only clue that it fails is not running the exe after
<MajorLag>
checking errorlevel confirms it exits 1
<hryx>
Here are those compiler issues (I actually stumbled on a compiler segfault as well):
<hryx>
@MajorLag if I understand, my code would be invalid anyway (dereferencing something which is not a pointer in the line you posted) but I assume the compiler should error instead of crash
<MajorLag>
You're correct, it should. I thought for a minute you were misinterpreting a program segfault as a compiler issue, but I can confirm it does crash the compiler
<hryx>
Cool cool. Related, if I remove the * the compiler complains: "error: unable to infer expression type"
<hryx>
pointing to the `switch` keyword
<hryx>
Curious what I'm doing wrong there
<andrewrk>
there's an issue for this somewhere. fix it by casting one of the values to a type
<GitHub109>
zig/master 25dff91 Andrew Kelley: fix windows build broken by previous commit...
<andrewrk>
MajorLag, I'm trying to reproduce your issue
<MajorLag>
sorry I can't make it easier. You'd need to not have VS installed as far as I can tell.
<andrewrk>
I think get_windows_sdk is succeeding for you
<andrewrk>
when it should be failing because sdk->version10.length is 0
<MajorLag>
when I pass it all the paths, it doesn't look like it's looking for the SDK registry entries, which is what I'd expect.
<andrewrk>
it's also looking for --libc-include-dir and not finding it, and so then calling get_windows_sdk, which is succeeding, but then version10.len is 0
<MajorLag>
providing --libc-include-dir doesn't seem to change anything in process monitor
<relatingdata>
there was a major improvement to atomic locking that was talked about at the brisbane sunday coders club I think its was william from redhat, but my memory might not be quiet accurate!
<andrewrk>
I found the paper by Maged Michael
relatingdata has quit [Quit: Page closed]
tiehuis has joined #zig
<andrewrk>
ugh, this paper wants you to stuff 2 usizes and a u2 into a usize
<andrewrk>
this doesn't solve the problem at all
<tiehuis>
pretty sure i've solved all the float printing issues in release modes now
<andrewrk>
wow
<tiehuis>
just needed a single float-mode change in hpNormalize in errol
<andrewrk>
I have a windows laptop in front of me, want me to look into the appveyor failure?
<andrewrk>
or was that it?
<tiehuis>
that'd be helpful, thanks
<tiehuis>
i was in the middle of setting up a windows vm but build tools are slow to install
<tiehuis>
i believe the issue is different for the windows failure, but may as well wait for appveyor to finish this current build to confirm
<andrewrk>
oh wow it's in compiler-rt
<andrewrk>
line 45 of udivmod.zig
<tiehuis>
that is unexpected
<andrewrk>
from line 325 of errol/index.zig
<andrewrk>
const lf = u64((low / pow19...
<andrewrk>
val is 1.5231400000000000e+29
<andrewrk>
which is one of the test cases
<andrewrk>
looking at this compiler-rt code, it's quite puzzling, because we're in an if statement that checked that d[low] == 0, and then we divide by it - so it's like we know we're dividing by zero ? weird
<andrewrk>
let me double check compiler-rt from llvm
<andrewrk>
yeah, same thing
<tiehuis>
looks seemingly impossible to hit that
<tiehuis>
DoubleInt
<andrewrk>
it's because the errol code does a u128 divided by a u128
<Braedon>
Wow I just found an inverse square algorithm that has an accuracy of 7.023769248702945e-10. For the record doom has 1.886557159257603e-6 for the same set of numbers
<Braedon>
And it only runs 8% slower
xkern has joined #zig
qazo has quit [Ping timeout: 264 seconds]
Braedon has quit [Ping timeout: 260 seconds]
qazo has joined #zig
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
qazo has quit [Read error: Connection reset by peer]
<alexnask>
Thank god for translate-c :P
xkern has quit [Quit: Leaving.]
noonien has joined #zig
davr0s has joined #zig
return0e has joined #zig
xkern has joined #zig
xkern has quit [Quit: Leaving.]
cenomla has joined #zig
steveno_ has joined #zig
cenomla has quit [Quit: cenomla]
davr0s has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
<Dodo>
where Once will only..iterate once, Repeat repeats forever, and Take takes the first n items
btbytes has joined #zig
<alexnask>
@Dodo, Once looks ok, although you could have a consumed: bool + item: T instead of an item: ?T if you want to be able to make it resetable at some point
<alexnask>
Take looks good
<alexnask>
I don't see why repeat stores item as ?T instead of T
<alexnask>
But apart from that, looks fine
<Dodo>
oh, uhm
<Dodo>
let me fix that
<Dodo>
mh, what function should be nice to have as well?
<Dodo>
plus, if you now make you're own Iterator, you should be able to call all those functions
<alexnask>
Right, I thought of doing it that way the other day we were discussing about it but I wanted to directly return the &Iterator (which is not possible)
<alexnask>
This is fine though, you just get the .it field when needed :)
<Dodo>
yeah hahaha
<alexnask>
Have you thought about how you are going to handle bidirectional iterators btw?
<Dodo>
bidirectional?
<Dodo>
mhh
<Dodo>
maybe another function just like .next()
<Dodo>
but .next_back()
<Dodo>
and have a .rev() function on Iterator or something?
<Dodo>
or have a similar idea like Iterator, but then with DoubleEnded Iterator,
<alexnask>
Right, you could have an optional prevFn etc.
davr0s has joined #zig
<Dodo>
and have all structs have another field, .it_rev maybe?
<alexnask>
I think that's cleaner
<Dodo>
but omg how large is the file going to be?
<alexnask>
Evvey double ended/bidirectional iterator is an iterator though
<Dodo>
yeahhh
<Dodo>
do we have some kind of inheritance?
<alexnask>
Nope, zig just has plain structs
<alexnask>
You can fake it like we faked interfaces
<alexnask>
So I think you could do some thing where all iterators that are bidirectional only have a bidirectional iterator field
<alexnask>
But that field can either be casted directly to an Iterator or have a method that turns it into an Iterator
<Dodo>
mhh
<alexnask>
Basically, if you have a 'const A = struct { field1: usize};'
<alexnask>
and 'const B = struct { field1: usize, field2: []u8, };
<alexnask>
Every &B can be turned into an &A
<andrewrk>
not true
<andrewrk>
you'll need to have A be a field of B or vice versa
<alexnask>
really?
<alexnask>
Sure, I was going to say it's better to be explicit
<andrewrk>
zig reserves the right to re-order struct fields
<alexnask>
Aaah, right
<andrewrk>
and add secret fields for debugging purposes
<andrewrk>
I'm planning on having debug mode purposefully re-order fields so that one does not accidentally rely on this behavior
<Dodo>
can we enforce that a type has a method at compile time?
<alexnask>
Yes, I can see how C people would fall into that
<alexnask>
@Dodo I don't think so
<andrewrk>
Dodo, you can call it. if it doesn't exist, you'll get a compile error
<andrewrk>
it's planned for @reflect to tell you about member functions of structs
<andrewrk>
that's not implemented yet
<Dodo>
so in Iterator, there is this function 'next_fn' , and on each struct we say something like ' .it = Iter {.next_fn = next}'
<alexnask>
@andrewrk I was actually about to get started on @reflect
<andrewrk>
oh neat
<Dodo>
what if we also add a 'next_back_fn',
<alexnask>
Although I guess it's going to take me a long time to finish
<Dodo>
does that have to be filled in for all types that have an Iter field?
<alexnask>
(Or rather, the @reify part)
<Dodo>
or can you just leave it empty?
<alexnask>
You can make it nullable
<alexnask>
And fill it in with null in structs that don't provide it
<alexnask>
But
<Dodo>
but that costs something at runtime?..
<alexnask>
I would suggest you make a new DoubleEndedIterator
<alexnask>
@Dodo You can also use test blocks instead of a main function if you the package is intended to be a library :)
<Dodo>
mh yeah
<andrewrk>
LLVM supports packed and C ABI for structs. so zig would be doing something on top of that
<Dodo>
how does importhing files work?
<alexnask>
Ok, good to know, I've never targetted LLVM before, I usually just dump C :P
<Dodo>
becouse DoubleEndedIterator needs Iterator, but some structs in Iterator.zig also need DoubleEndedIterator
<Dodo>
*importing
<alexnask>
I don't think cyclical imports are an issue but I could be wrong
<andrewrk>
top level declarations are order independent and we have lazy evaluation
<Dodo>
how do I import everything from a file?
<andrewrk>
so we have deterministic builds, and as long as there is no actual circular dependency, such as a struct embedded in itself, everything is fine
<Dodo>
but then all the functions and structs must be prefixed with 'namespace' ?
Ichorio has joined #zig
<alexnask>
Or you can 'use @import("...")'
<andrewrk>
correct
btbytes has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
btbytes has joined #zig
<andrewrk>
consider that what would previously be your "namespace" in C, you can make an actual namespace in zig. so for example if you're opengl, and all your functions are prefixed with gl, such as glSwapBuffer
<Dodo>
so you just could call swapBuffer() for example?
<andrewrk>
yes, with alexnask's example above
<andrewrk>
this comes with an inherent penalty on compilation speed, and the code reader's ability to discover where a symbol comes from
<andrewrk>
code reader being a human
<Dodo>
so in main.zig I would say 'use @import("Iterator.zig");' ?
<alexnask>
Yup, then all pub symbols are available in the global namespace
<alexnask>
Or w/e we're supposed to call it
<Dodo>
all pub symbols
<Dodo>
guess I didn't make them public...
<alexnask>
Time to copy paste a bunch of "pub" :P
<andrewrk>
:%s/^fn\>/pub /g
<andrewrk>
done
<Dodo>
do returned structs also need to be pub?
<alexnask>
you mean as in 'pub fn foo() type { return struct { ... }; }'
<alexnask>
You only need to pub any fn or variable you want to expose through @import
<alexnask>
The pub is not an attribute of the struct, it's just the visibility of the symbol
<Dodo>
oh yeah
<Dodo>
wohoo it builds again
<alexnask>
:D
<Dodo>
mh, DoubleEndedIterator can have a field like this 'const Self = Iterator(T)', right?
<alexnask>
sure, using 'Self' is pretty misleading though, I would expect Self == DoubleEndedIterator(T)
<Dodo>
fair enough
jjido has joined #zig
<Dodo>
okey this is verry verbose assert(zipped.next() == Tuple(usize, usize) {.t1 = 6, .t2 = 0})
<Dodo>
build-in tuples would be greate ^^
jjido has quit [Client Quit]
jjido has joined #zig
cenomla has quit [Quit: cenomla]
<andrewrk>
I've decided on removing var args and adding built in tuples
<Dodo>
\o/
<Dodo>
how do I assert on something that is ?T, to test if it's some value?
<SimonNa>
Instead of templated functions with variable arguments, one would then have one compile-time type variable that can then be instantiated with any length and types? That sounds clean then
<Dodo>
so like assert(maybe == ?10) or whatever
<andrewrk>
SimonNa, the length and types would be compile time known and the values of each thing would be runtime known
<SimonNa>
yeah, I assume it would instantiate a function for every different tuple
<SimonNa>
surely, in each instantiated function, the exact type of the tuple is then known (number of entries, fixed type for each entry)
<alexnask>
Yes
<alexnask>
All this is known with varargs atm too
<alexnask>
@andrewrk Would you be opposed with @reflect being renamed to @typeInfo?
<andrewrk>
alexnask, sounds fine to me. at the end of the day the name of the function is trivial to change and independent from the hard problem of implementing it
<alexnask>
Good, @typeInfo it is, I think it's clearer than @reflect, @reflect sounds like it should work on any definition
<MajorLag>
oh good, you've already fixed the comtime shifting bug. that'll save me a bit of hassle.
<andrewrk>
MajorLag, trying to stay awake at work @_@
<Dodo>
error: no member named 'next_back' in struct 'Iterator(usize)'
<Dodo>
ugh, guess my current idea doesnt quite work
<andrewrk>
Dodo, the use case you're working on sounds interesting, but I think there are a few other use cases I'm focusing on first in the roadmap
<andrewrk>
so you might be working against the grain a little bit
<Dodo>
ah yeah
<Dodo>
well, I'm really not familiar with Zig yet, and this seemed a challenging thing to do
<andrewrk>
you know? like maybe we go ahead and support some kind of trait or interface in 0.4.0, and then what you're doing has a clear answer
<Dodo>
so Im trying to understand how it all works and such
<andrewrk>
fair enough
<Dodo>
and I've never implemented Iterators from scratch, so that's also something I wanted to do
<Dodo>
but trait/interface like support would be really cool!
<andrewrk>
yeah. I just want to make sure that it does not overcomplicated the language
<andrewrk>
simplicity is kinda the only thing we have going vs rust
<Dodo>
in a way interfaces could make things easier, also for things like equality testing
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
steveno_ has quit [Remote host closed the connection]
<MajorLag>
One thing about doing interfaces the way zig does now: it is obvious how it works. I think I like that more than I dislike the extra verbosity.
<alexnask>
The idiomatic way to make interfaces requires that the definition of the implementation type includes a field of the interface type
<alexnask>
This is a downside imho, but it can be worked around as is (with some more metaprogramming)
<alexnask>
(Basically, the interface here is a pair of pointers, one to the implementation object and one to a automatically comptime-generated vtable)
<Dodo>
but here's the thing, handwritten vtables and metaprogramming might be more clear,
<Dodo>
but it's also hard if you've never done it, like me
<alexnask>
I know, I'm not saying people should be doing it as is :P
<alexnask>
Ideally, you would just have a vtable_gen call that generates a vtable from the description (tuples of name, function type)
<alexnask>
Then your interface type is a pointer to that vtable type
<alexnask>
+ whatever way you chose to store your objects (or just a pointer)
<alexnask>
That way of doing this allows you both to write new types with no interface field that work seamlessly with existing interfaces
<alexnask>
And to write new interfaces that work seamlessly with existing types
<Dodo>
but doing it by hand maybe makes you think more on how to do things, so thats a good thing I guess?
<alexnask>
Sure, you still write your interface by hand, you just let the compiler make a vtable for every type of object that uses your interface ;)
<alexnask>
Anyway, it's a design decision for sure, I'm just saying the way I've seen interfaces defined in zig is not unique and you can actually get some extra advantages doing it other ways
<MajorLag>
Well, let's lay out the issues we're trying to solve in the current implemetnation. From my perspective, the only one that's been an issue is that sometimes I make a copy of an interface instead of taking a pointer to it. In my own code I now prefix interface members with _ and have a interfaceName() fn return a pointer to it. I suppose having to name the interface component when passing it could also be counted as an issue, but I don't th
<MajorLag>
nk it is a big one: `square_actor.actor().addAction(repeat_action.action());`. What else?
<alexnask>
you should probably do 'const Iter = Iterator(T);' then define an 'it: Iter,' field
<alexnask>
@MajorLag Well for one implementing your interfaces this way would completely remove the need to grab a field from your implementation type
<alexnask>
Instead, you would initialize an interface object with 'Interface.init(whatever_value_implements_my_interface)'
<alexnask>
Basically, an interface type would be a pointer to a vtable + whatever storage policy you decide on for your objects
<Dodo>
what does this '@reify' (feature??) do?
<alexnask>
For example, you could have a small buffer in your interface type and copy objects in there, or store them on the heap if they are bigger than the buffer
<alexnask>
In this example, I store a usize I get from @ptrToInt
<alexnask>
@Dodo @reify would allow you to describe a type in a struct (constructed at comptime) and get an actual type back
<Dodo>
describe a type?
<alexnask>
@typeInfo/@reflect (currently writing that) would return that description struct from a type
<MajorLag>
I don't really see how `Iterator(usize).from(iter)` is better than `iter.iterator()` or even the current standard `iter.iterator` though.
<alexnask>
@Dodo take a look at that issue, it explains it pretty well
<alexnask>
@MajorLag it's not about the syntax, the key point is that the implementation type is completely detached from the interface
<alexnask>
RepeatIterator(T) does not need to know about Iterator(T)
<alexnask>
You could take a package written by another person that provides a struct with a 'fn next() usize'
<alexnask>
And that struct could be passed to Iterator(usize).init
<alexnask>
fn next(&Self) usize **
<Dodo>
one thing I wondered is, keeping a 'it: Iterator(sometype)' is some overhead, right?
<alexnask>
In every implementation type you mean?
<Dodo>
well yeah
<alexnask>
Yes, it is some overhead although I wouldn't worry about it
<Dodo>
now each struct has to have it
<alexnask>
What you could do is store an it: &Iterator(sometype) in every struct
<alexnask>
And initialize it with a pointer to a comptime Iterator(sometype)
<alexnask>
That should make the compiler generate a vtable in the binary, then you keep the reference to that static vtable at runtime instead of packing the whole vtable in every implementation type
<Dodo>
this is somewhat magic to be honestly :3
<alexnask>
I'm not 100% it would work but you can try it, the change is pretty trevial
<alexnask>
every it: Iterator(...) becomes it: &Iterator(...)
<alexnask>
and every .it = Iterator(...) { ... } becomes .it = &comptime Iterator(...) { ... }
<alexnask>
even better, it: &const Iterator(...)
<alexnask>
@Dodo This is basically what C++ does for virtual methods
<Dodo>
\Zig\itertools\src\main.zig:93:22: error: type '&&const Iterator(usize)' does not support field access <--- changing 'it: Iter' to 'it: &const Iter'
<alexnask>
I assume this happens someplace you take a pointer to an it field then call a function on it?
<MajorLag>
is Iterator() returning a type, as its naming convention suggests?
<alexnask>
Yes, it returns a vtable type in Dodo's case
<Dodo>
var once = &Once(usize).init(10).it; <-- thats where I create it
<MajorLag>
You can't take a pointer to a type. What you end up with is a type that is a pointer to the type. `const Type = usize; const PType = &Type;` => &Type == &usize
<alexnask>
it is of type '&const Iterator(usize)'
<alexnask>
Woops
<MajorLag>
This ambiguity is one of the things meant to be addressed in pointer reform
<alexnask>
@MajorLag That's what I was trying to do with my suggestion, &const Iterator(usize) is supposed to be "const pointer to the iterator(usize) vtable" type
<alexnask>
Not a pointer to the iterator(usize) type, if that makes sense
<MajorLag>
So you mean for .it to hold a type? Not be an instance of a type?
<alexnask>
no, .it is supposed to be an instance of type 'const pointer to Iterator(usize)'
<MajorLag>
Makes sense, but you need to point it at an instance then.
<alexnask>
Right
<alexnask>
Can you not initialize an Iterator(T) at comptime then initialize .it to be a pointer to that?