alias this and initialisation
can anybody tell me why struct S { int x; alias x this; } void test() { S s; s = 8; // this works S s = 8 // but this does not? }
m32mscoff with lld-link causes SEH errors
Hi, I have a simple program with just one line (below). I've compiled on Windows using dmd -ms32coff app.d and have had LINKCMD set to lld-link, but get the following errors. Is lld-link only for 64-bit compiles (-m64 is the only one that gives no errors) lld-link: error: /safeseh: app.obj is not compatible with SEH lld-link: error: /safeseh: ti_Ag_2714_4a7.obj is not compatible with SEH lld-link: error: /safeseh: stdio_4_58e.obj is not compatible with SEH lld-link: error: /safeseh: stdio_1_180.obj is not compatible with SEH lld-link: error: /safeseh: exception_2baa_5b5.obj is not compatible with SEH lld-link: error: /safeseh: deh_win32_256e_60b.obj is not compatible with SEH lld-link: error: /safeseh: deh_win32_2577_653.obj is not compatible with SEH lld-link: error: /safeseh: lifetime_25bb_4e0.obj is not compatible with SEH lld-link: error: /safeseh: lifetime_25a5_482.obj is not compatible with SEH lld-link: error: /safeseh: dmain2_2597_47b.obj is not compatible with SEH lld-link: error: /safeseh: deh_win32_2571_3b9.obj is not compatible with SEH lld-link: error: /safeseh: object_cf_6f6.obj is not compatible with SEH lld-link: error: /safeseh: object_10_583.obj is not compatible with SEH lld-link: error: /safeseh: ti_Ag_2712_42f.obj is not compatible with SEH lld-link: error: /safeseh: object_266_6bb.obj is not compatible with SEH lld-link: error: /safeseh: object_7_32e.obj is not compatible with SEH lld-link: error: /safeseh: ti_Ag_270e_435.obj is not compatible with SEH lld-link: error: /safeseh: ti_Ag_270f_436.obj is not compatible with SEH lld-link: error: /safeseh: object_a_58c.obj is not compatible with SEH lld-link: error: /safeseh: stdio_10_cfb.obj is not compatible with SEH app.d: import std.stdio; void main() { writeln("Edit source/app.d to start your project."); }
Re: How to flatten N-dimensional array?
On 5/24/20 2:37 AM, Pavel Shkadzko wrote: On Saturday, 23 May 2020 at 19:59:30 UTC, Ali Çehreli wrote: On 5/23/20 11:15 AM, Pavel Shkadzko wrote:> I have tried to implement a simple flatten function for multidimensional [...] Thank you, I was lacking practical examples for templates with "if" constructs, ehh. Template constraints are great but 'static if' can be more useful as it allows custom error messages: auto makeNdim(size_t N)(size_t length) { static if (N == 1) { auto result = iota(value, value + length).array; value += length; return result; } else static if (N > 1) { return iota(N).map!(n => makeNdim!(N - 1)(length)).array; } else { static assert(false, "N cannot be 0."); } } Ali
Re: Static assert triggered in struct constructor that shouldn't be called
On Sunday, 24 May 2020 at 21:43:34 UTC, H. S. Teoh wrote: On Sun, May 24, 2020 at 09:34:53PM +, jmh530 via Digitalmars-d-learn wrote: The following code results in the static assert in the constructor being triggered, even though I would have thought no constructor would have been called. I know that there is an easy fix for this (move the static if outside the constructor), but it still seems like it doesn't make sense. [...] The problem is that static assert triggers when the function is compiled (not when it's called), and since your ctor is not a template function, it will always be compiled. Hence the static assert will always trigger. T Thanks. Makes sense.
Re: Static assert triggered in struct constructor that shouldn't be called
On Sunday, 24 May 2020 at 21:34:53 UTC, jmh530 wrote: The following code results in the static assert in the constructor being triggered, even though I would have thought no constructor would have been called. static assert is triggered when the code is *compiled*, whether it is actually run or not. So as long s the function exists, its static asserts must all pass before it even gets to the runtime decision of if it is actually called or no.
Re: Static assert triggered in struct constructor that shouldn't be called
On Sun, May 24, 2020 at 09:34:53PM +, jmh530 via Digitalmars-d-learn wrote: > The following code results in the static assert in the constructor > being triggered, even though I would have thought no constructor would > have been called. I know that there is an easy fix for this (move the > static if outside the constructor), but it still seems like it doesn't > make sense. [...] The problem is that static assert triggers when the function is compiled (not when it's called), and since your ctor is not a template function, it will always be compiled. Hence the static assert will always trigger. T -- The trouble with TCP jokes is that it's like hearing the same joke over and over.
Static assert triggered in struct constructor that shouldn't be called
The following code results in the static assert in the constructor being triggered, even though I would have thought no constructor would have been called. I know that there is an easy fix for this (move the static if outside the constructor), but it still seems like it doesn't make sense. enum Foo { A, B, } struct Bar(Foo foo) { static if (foo == Foo.A) { float x = 0.5; long y = 1; } else static if (foo == Foo.B) { int p = 1; } this(long exp, float x) { static if (foo == Foo.A) { this.y = exp; this.x = x; } else { static assert(0, "Not implemented"); } } } void main() { Bar!(Foo.B) x; }
Re: RtlAdjustPrivilege and NtRaiseHardError
"doesn't work" isn't very helpful. Are you seeing compiler errors? Linker errors? Runtime errors? Please describe your problem. Solved my problem alone : wrong signatures with functions ;) and this reply isn't very helpful. what is right signature? you go to forum to ask help. but wish you help to other readers, those will have the ame problems?
Re: RtlAdjustPrivilege and NtRaiseHardError
On Saturday, 23 May 2020 at 01:33:13 UTC, Mike Parker wrote: On Friday, 22 May 2020 at 19:19:19 UTC, Arsium wrote: Just I tried to launch those functions from win32 api and seems doesn't work "doesn't work" isn't very helpful. Are you seeing compiler errors? Linker errors? Runtime errors? Please describe your problem. Solved my problem alone : wrong signatures with functions ;)
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 15:24:14 UTC, 9il wrote: On Sunday, 24 May 2020 at 14:17:33 UTC, Pavel Shkadzko wrote: [...] BTW, the code example above doesn't compiles. OT: Instead of [...] you can generate the same common D array using Mir: auto a = [2, 2, 4].iota!int(1).ndarray; I posted in a rush. There should be "auto arrSlice = a.sliced;" and "writeln(a.getShape);".
Re: How to get the pointer of "this" ?
On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: Hi all, I have a class like this. class Button : Control { ... HWND createButton(){ ... SetWindowSubclass(this.mHandle, SUBCLASSPROC(&btnWndProc), UINT_PTR(subClsID), cast(DWORD_PTR) this); } } But compiler says that - "Error: 'this' is not an lvalue and cannot be modified" I've seen many cpp code which uses pointer to 'this' as the last parameter in SetWindowSubclass(). Is there something wrong with my approach ? I think your issue might be elsewhere because casting this should be fine and it should not complain about that in your given code. At least you should be able to pass this to another function or even cast it. Please show the full code and the full error which gives you the stacktrace of where it's called and from where.
Re: Variable "i" can not be read at compile time
On 24.05.20 19:13, data pulverizer wrote: Thank you very much. I though that if I used a `static foreach` loop D would attempt to run the calculation `bench()` at compile time rather than at run time but it doesn't which is good. So `static foreach` allows you to index at compile time and if its scope runs at run time it is run time and if at compile time it is compile time evaluated? `static foreach` gets unrolled at compile time. It doesn't affect how the body is handled. It's like copy-pasting the loop body n times in the source code. For example, this: int x = 0; static foreach (i; 0 .. 3) { x += f(i); } is the same this: int x = 0; x += f(0); x += f(1); x += f(2); It doesn't affect how `f` is being run. They're ordinary run-time calls either way. To evaluate the `f` calls during compilation you can use `enum` to trigger CTFE: int x = 0; enum f0 = f(0); /* CTFE */ x += f0; enum f1 = f(1); /* CTFE */ x += f1; enum f2 = f(2); /* CTFE */ x += f2; or with `static foreach`: int x = 0; static foreach (i; 0 .. 3) {{ enum e = f(i); x += e; }} Notice the extra set of braces. It's just adding a scope. Without that, the different `e`s would clash with each other.
Re: Variable "i" can not be read at compile time
On Sunday, 24 May 2020 at 17:13:23 UTC, data pulverizer wrote: On Sunday, 24 May 2020 at 16:57:54 UTC, ag0aep6g wrote: On 24.05.20 18:34, data pulverizer wrote: Since `kernel` is a `Tuple`, you can only access it with compile-time constant indices. But your loop variable `i` is not a compile-time constant, it's being calculated at run time. What's more, it depends on `results.length` which is also not a compile-time constant. But `results.length` is the same as `kernels.length`. And being the length of a `Tuple`, that one is a compile-time constant. So you can rewrite your loop as a `static foreach` (which is evaluated during compile-time) using `kernels.length` instead of `results.length`: static foreach (i; 1 .. kernels.length) { results[i] = bench(kernels[i], n, verbose); } Thank you very much. I though that if I used a `static foreach` loop D would attempt to run the calculation `bench()` at compile time rather than at run time but it doesn't which is good. So `static foreach` allows you to index at compile time and if its scope runs at run time it is run time and if at compile time it is compile time evaluated? You can see static foreach as unrolling a compile-time loop to a set of runtime-expressions. Ex. static foreach (i; 0 .. 10) { writeln(i); } Actually just becomes writeln(0); writeln(1); writeln(2); writeln(3); writeln(4); writeln(5); writeln(6); writeln(7); writeln(8); writeln(9); - It creates no scope, whatsoever either. However doing static foreach () {{ ... }} Will create a scope per iteration.
Re: Variable "i" can not be read at compile time
On Sunday, 24 May 2020 at 16:57:54 UTC, ag0aep6g wrote: On 24.05.20 18:34, data pulverizer wrote: Since `kernel` is a `Tuple`, you can only access it with compile-time constant indices. But your loop variable `i` is not a compile-time constant, it's being calculated at run time. What's more, it depends on `results.length` which is also not a compile-time constant. But `results.length` is the same as `kernels.length`. And being the length of a `Tuple`, that one is a compile-time constant. So you can rewrite your loop as a `static foreach` (which is evaluated during compile-time) using `kernels.length` instead of `results.length`: static foreach (i; 1 .. kernels.length) { results[i] = bench(kernels[i], n, verbose); } Thank you very much. I though that if I used a `static foreach` loop D would attempt to run the calculation `bench()` at compile time rather than at run time but it doesn't which is good. So `static foreach` allows you to index at compile time and if its scope runs at run time it is run time and if at compile time it is compile time evaluated?
How to get the pointer of "this" ?
Hi all, I have a class like this. class Button : Control { ... HWND createButton(){ ... SetWindowSubclass(this.mHandle, SUBCLASSPROC(&btnWndProc), UINT_PTR(subClsID), cast(DWORD_PTR) this); } } But compiler says that - "Error: 'this' is not an lvalue and cannot be modified" I've seen many cpp code which uses pointer to 'this' as the last parameter in SetWindowSubclass(). Is there something wrong with my approach ?
Re: Variable "i" can not be read at compile time
On 24.05.20 18:34, data pulverizer wrote: I'm getting the error: ``` Error: variable i cannot be read at compile time Error: template instance script.runKernelBenchmarks!(Tuple!(DotProduct!float, Gaussian!float, Polynomial!float, Exponential!float, Log!float, Cauchy!float, Power!float, Wave!float, Sigmoid!float)) error instantiating ``` When I run ... ``` ... auto runKernelBenchmarks(KS)(KS kernels, long[] n, bool verbose = true) { auto tmp = bench(kernels[0], n, verbose); alias R = typeof(tmp); R[] results = new R[kernels.length]; results[0] = tmp; for(size_t i = 1; i < results.length; ++i) { results[i] = bench(kernels[i], n, verbose); } return results; } void main() { alias T = float; auto kernels = tuple(DotProduct!(T)(), Gaussian!(T)(1), Polynomial!(T)(2.5f, 1), Exponential!(T)(1), Log!(T)(3), Cauchy!(T)(1), Power!(T)(2.5f), Wave!(T)(1), Sigmoid!(T)(1, 1)); string[] kernelNames = ["DotProduct", "Gaussian", "Polynomial", "Exponential", "Log", "Cauchy", "Power", "Wave", "Sigmoid"]; long[] n = [100L, 500L, 1000L]; auto results = runKernelBenchmarks(kernels, n); writeln("Results: ", results); } ``` Since `kernel` is a `Tuple`, you can only access it with compile-time constant indices. But your loop variable `i` is not a compile-time constant, it's being calculated at run time. What's more, it depends on `results.length` which is also not a compile-time constant. But `results.length` is the same as `kernels.length`. And being the length of a `Tuple`, that one is a compile-time constant. So you can rewrite your loop as a `static foreach` (which is evaluated during compile-time) using `kernels.length` instead of `results.length`: static foreach (i; 1 .. kernels.length) { results[i] = bench(kernels[i], n, verbose); }
Variable "i" can not be read at compile time
Hi all, I'm getting the error: ``` Error: variable i cannot be read at compile time Error: template instance script.runKernelBenchmarks!(Tuple!(DotProduct!float, Gaussian!float, Polynomial!float, Exponential!float, Log!float, Cauchy!float, Power!float, Wave!float, Sigmoid!float)) error instantiating ``` When I run ... ``` ... auto runKernelBenchmarks(KS)(KS kernels, long[] n, bool verbose = true) { auto tmp = bench(kernels[0], n, verbose); alias R = typeof(tmp); R[] results = new R[kernels.length]; results[0] = tmp; for(size_t i = 1; i < results.length; ++i) { results[i] = bench(kernels[i], n, verbose); } return results; } void main() { alias T = float; auto kernels = tuple(DotProduct!(T)(), Gaussian!(T)(1), Polynomial!(T)(2.5f, 1), Exponential!(T)(1), Log!(T)(3), Cauchy!(T)(1), Power!(T)(2.5f),Wave!(T)(1), Sigmoid!(T)(1, 1)); string[] kernelNames = ["DotProduct", "Gaussian", "Polynomial", "Exponential", "Log", "Cauchy", "Power", "Wave", "Sigmoid"]; long[] n = [100L, 500L, 1000L]; auto results = runKernelBenchmarks(kernels, n); writeln("Results: ", results); } ``` Thanks
Re: Using Vibe.d for not HTTP
On Sunday, 24 May 2020 at 16:14:58 UTC, Russel Winder wrote: On Sun, 2020-05-24 at 17:01 +0100, Russel Winder wrote: […] connection.read(buffer, IOMode.once); What an idiot I am, this call returns the read count, which makes it fine. Progress now being made. I had a look. Documentation could be better. I think the other call does not return it, because it always reads until the buffer is filled.
Re: Using Vibe.d for not HTTP
On Sun, 2020-05-24 at 17:01 +0100, Russel Winder wrote: > […] > connection.read(buffer, IOMode.once); > What an idiot I am, this call returns the read count, which makes it fine. Progress now being made. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Using Vibe.d for not HTTP
On Sun, 2020-05-24 at 12:26 +, bauss via Digitalmars-d-learn wrote: […] Thanks for responding, much appreciated. > void handleConnections(TCPConnection connection) { > ... > } I guess I was looking for an example of what to put in this function! > auto buf = new ubyte[amount]; > > connection.read(temp); The documentation on read is sadly lacking :-( https://vibed.org/api/vibe.core.net/TCPConnection.read It seems to block pending filling all the spaces in the buffer. Not really very useful. I tried: connection.read(buffer, IOMode.once); but there seems no report on how many bytes were read, you have to guess by parsing the buffer and making assumptions. Unless I am missing something, which I really hope I am. > connection.write(buf); Not quite at that stage yet! […] -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:17:33 UTC, Pavel Shkadzko wrote: I am confused by the return value of Mir shape. Consider the following example. /// import std.stdio; import std.conv; import std.array: array; import std.range: chunks; import mir.ndslice; int[] getShape(T : int)(T obj, int[] dims = null) { return dims; } // return arr shape int[] getShape(T)(T obj, int[] dims = null) { dims ~= obj.length.to!int; return getShape!(typeof(obj[0]))(obj[0], dims); } void main() { int[] arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; int[][][] a = arr.chunks(4).array.chunks(2).array; writeln(arr); writeln(arr.shape); auto arrSlice = arr.sliced; writeln(arrSlice); writeln(arrSlice.shape); } /// [[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]] [2, 2, 4] <-- correct shape [[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]] [2] <-- which shape is that? I would expect sliced to create a Slice with the same dims. Well, sliced returns a shell over the array, but why does it return its own shape instead of the shape of the array it provides view into? This makes it even more confusing once you print both representations. What's the rationale here? BTW, the code example above doesn't compiles. OT: Instead of int[] arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; int[][][] a = arr.chunks(4).array.chunks(2).array; you can generate the same common D array using Mir: auto a = [2, 2, 4].iota!int(1).ndarray;
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:35:33 UTC, jmh530 wrote: On Sunday, 24 May 2020 at 14:21:26 UTC, Pavel Shkadzko wrote: [snip] Sorry for the typo. It should be "auto arrSlice = a.sliced;" Try using fuse /+dub.sdl: dependency "mir-algorithm" version="*" +/ import std.stdio; import std.conv; import std.array: array; import std.range: chunks; import mir.ndslice; int[] getShape(T : int)(T obj, int[] dims = null) { return dims; } // return arr shape int[] getShape(T)(T obj, int[] dims = null) { dims ~= obj.length.to!int; return getShape!(typeof(obj[0]))(obj[0], dims); } void main() { int[] arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; int[][][] a = arr.chunks(4).array.chunks(2).array; int err; writeln(arr); writeln(a.shape(err)); auto aSlice = a.fuse; writeln(aSlice); writeln(aSlice.shape); } Yes, this works. It doesn't explain why sliced behaves like this though. Also, isn't sliced the default way of converting D arrays to Mir arrays? Above all arr.fuse.field flattens the array. So, fuse works as D join if combined with field but as slice allocator is used on a D array...
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:17:33 UTC, Pavel Shkadzko wrote: I am confused by the return value of Mir shape. Consider the following example. [...] `sliced` returns a view on the array data, a 1-dimensional slice composed of common D arrays. Try to use `fuse` instead of `sliced`.
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:21:26 UTC, Pavel Shkadzko wrote: On Sunday, 24 May 2020 at 14:17:33 UTC, Pavel Shkadzko wrote: I am confused by the return value of Mir shape. Consider the following example. [...] Sorry for the typo. It should be "auto arrSlice = a.sliced;" And another typo "writeln(arr.getShape);", too rushy.
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:21:26 UTC, Pavel Shkadzko wrote: [snip] Sorry for the typo. It should be "auto arrSlice = a.sliced;" Try using fuse /+dub.sdl: dependency "mir-algorithm" version="*" +/ import std.stdio; import std.conv; import std.array: array; import std.range: chunks; import mir.ndslice; int[] getShape(T : int)(T obj, int[] dims = null) { return dims; } // return arr shape int[] getShape(T)(T obj, int[] dims = null) { dims ~= obj.length.to!int; return getShape!(typeof(obj[0]))(obj[0], dims); } void main() { int[] arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; int[][][] a = arr.chunks(4).array.chunks(2).array; int err; writeln(arr); writeln(a.shape(err)); auto aSlice = a.fuse; writeln(aSlice); writeln(aSlice.shape); }
Re: Mir Slice.shape is not consistent with the actual array shape
On Sunday, 24 May 2020 at 14:17:33 UTC, Pavel Shkadzko wrote: I am confused by the return value of Mir shape. Consider the following example. [...] Sorry for the typo. It should be "auto arrSlice = a.sliced;"
Mir Slice.shape is not consistent with the actual array shape
I am confused by the return value of Mir shape. Consider the following example. /// import std.stdio; import std.conv; import std.array: array; import std.range: chunks; import mir.ndslice; int[] getShape(T : int)(T obj, int[] dims = null) { return dims; } // return arr shape int[] getShape(T)(T obj, int[] dims = null) { dims ~= obj.length.to!int; return getShape!(typeof(obj[0]))(obj[0], dims); } void main() { int[] arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; int[][][] a = arr.chunks(4).array.chunks(2).array; writeln(arr); writeln(arr.shape); auto arrSlice = arr.sliced; writeln(arrSlice); writeln(arrSlice.shape); } /// [[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]] [2, 2, 4] <-- correct shape [[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]] [2] <-- which shape is that? I would expect sliced to create a Slice with the same dims. Well, sliced returns a shell over the array, but why does it return its own shape instead of the shape of the array it provides view into? This makes it even more confusing once you print both representations. What's the rationale here?
Re: Distinguish between a null array and an empty array
On 24.05.20 14:29, bauss wrote: Dang, that sucks there is no proper way and I would say that's a big flaw of D. Because what I need it for is for some data serialization but if the value is an empty array then it should be present and if it's null then it should not be present. Since null is used to say "ignore this" in the data serialization. You can use std.typecons.Nullable (or a similar wrapper) to add an extra "ignore this" value to a type.
Re: Distinguish between a null array and an empty array
On 24.05.20 14:12, bauss wrote: Is there a way to do that? Since the following are both true: int[] a = null; int[] b = []; assert(a is null); assert(!a.length); assert(b is null); assert(!b.length); What I would like is to tell that b is an empty array and a is a null array. No way. `null` and `[]` are the same thing for arrays. (Ulike `""` for strings which has a non-null `.ptr`.) You can distinguish `null` from other (non-null, non-`[]`) empty arrays. For example: int[] b = [1, 2, 3]; b = b[0 .. 0]; assert(b !is null); assert(!b.length);
Re: Distinguish between a null array and an empty array
On Sunday, May 24, 2020 6:12:31 AM MDT bauss via Digitalmars-d-learn wrote: > Is there a way to do that? > > Since the following are both true: > > int[] a = null; > int[] b = []; > > assert(a is null); > assert(!a.length); > > assert(b is null); > assert(!b.length); > > What I would like is to tell that b is an empty array and a is a > null array. There really is no difference between null and []. The compiler will use the exact same value for both, since it makes no sense to allocate anything for an empty array. If you want an array that's empty but non-null, then you'll have to create a non-empty array and then slice it or set its length to 0 so that it actually has a value for its ptr property other than null. Regardless, == will never differentiate between a null and empty array, because it's going to compare the lengths of the arrays and then compare the individual elements if the lengths are the same. And with a length of 0, there's no reason to ever check the elements, so the ptr value is irrelevant. If you want to check whether an array is actually null, then you need to use the is operator or check the ptr property explicitly. And of course, the normal warnings apply that trying to differentiate between null and empty arrays in D is almost certainly something that you shouldn't be doing. You can do it if you're _very_ careful, but it's almost always a terrible idea. As dumb as it arguably is, wrapping the array in a Nullable would be _far_ less error-prone if you need to differentiate between an array that's empty and not having a value. - Jonathan M Davis
Re: Using Vibe.d for not HTTP
On Sunday, 24 May 2020 at 08:10:33 UTC, Russel Winder wrote: Hi, Clearly Vibe.d is mostly for people doing HTTP and HTTPS stuff. Yet it claims to be able to support TCP and UDP working with other protocols. However, all the serious examples are HTTP/HTTPS related. All the TCP and UDP examples are basically trivial and thus useless to me for learning. I am hoping I have just missed the page/example that does something more than just echo for a TCP server. If I haven't, is ther an example somewhere people know of that I can look at? My problem is that I am not sure how to do a read/write system that is not just echo using the "connection.write(connection)" trick. Here is a quick example that I took from some old code I had: I cannot guarantee that it works as it was written for an older version of vibe about 3 years ago. I have not structured it either and just put all snippets together here. listeners = [listenTCP(port, &handleConnections, ip)]; or listeners = listenTCP(port, &handleConnections); void handleConnections(TCPConnection connection) { ... } auto buf = new ubyte[amount]; connection.read(temp); connection.write(buf); Then of course you need to handle all that in the way your server/client operates. How you implement it is of course just in similar fashion to general socket servers. You read N bytes until you have received all bytes for the specific packet. Then you can write your packets back afterwards. Someone can correct me if I am wrong but I believe you can yield from the handlers in vibe.d So if you haven't received all data yet you can yield between each call to read until all bytes have been received. I will admit I have not used sockets in vibe.d for a very long time though.
Re: Distinguish between a null array and an empty array
On Sunday, 24 May 2020 at 12:26:42 UTC, ag0aep6g wrote: On 24.05.20 14:12, bauss wrote: Is there a way to do that? Since the following are both true: int[] a = null; int[] b = []; assert(a is null); assert(!a.length); assert(b is null); assert(!b.length); What I would like is to tell that b is an empty array and a is a null array. No way. `null` and `[]` are the same thing for arrays. (Ulike `""` for strings which has a non-null `.ptr`.) You can distinguish `null` from other (non-null, non-`[]`) empty arrays. For example: int[] b = [1, 2, 3]; b = b[0 .. 0]; assert(b !is null); assert(!b.length); Dang, that sucks there is no proper way and I would say that's a big flaw of D. Because what I need it for is for some data serialization but if the value is an empty array then it should be present and if it's null then it should not be present. Since null is used to say "ignore this" in the data serialization. Oh well.
Re: opEquals @safe is ignored
On Sunday, May 24, 2020 2:57:28 AM MDT Luis via Digitalmars-d-learn wrote: > Lets take this example code (https://run.dlang.io/is/Vkpx9j) : > > ´´´D > import std; > > void main() > { > } > > class ExampleC > { >int x; >this (int x) @safe >{ > this.x = x; >} > >override bool opEquals(Object o) const @trusted >{ > if (ExampleC rhs = cast(ExampleC)o) { >return this.x == rhs.x; > } > return false; >} > } > > @safe unittest > { > auto c = new ExampleC(1); > assert(c != new ExampleC(23)); > } > ´´´ > > dmd ignores @trusted or @safe on opEquals, throwing this error : > > onlineapp.d(27): Error: @safe function > onlineapp.__unittest_L24_C7 cannot call @system function > object.opEquals > > An override @system or @trusted function can't be @safe, or I it > a bug ? > > Also, how will this be affected by DIP1028 ? The core problem is that Object does not have attributes on any of its functions - including opEquals. And in the case of opEquals, the problem is one layer worse, because == gets lowered to the free function opEquals which in turn calls opEquals on the class reference itself (after doing additional checks like that the reference isn't null and that you're not comparing a reference to itself), and that free function has no attributes. In fact, the only reason that using == on const objects works is because of a hack in druntime that casts away const (which means that it's technically possible and even downright trivial to break the type system by mutating a const class object within opEquals). And really, the only fix for this is to remove opEquals, opCmp, toHash, and toString from Object, since no matter which set of attributes you pick, there will be problems. With the addition of templates, it's no longer necessary for any of those functions to even be on Object, and it really doesn't make sense for them to be there, but they've been there since long before templates or attributes were added to the language. It was decided years ago that those functions should be removed from Object, but _how_ to do it with minimal code breakage is a thorny problem, and it hasn't really been a priority. The currently proposed solution (which has a work-in-progress DIP IIRC) is to introduce a new root class to the language below Object which has _nothing_ on it (the current name for that root class being ProtoObject). Object would then continue to be the default base class of any class, but it would then be derived from ProtoObject, and best practice at that point would really be to explicitly derive your class from ProtoObject (with Object being left in place pretty much just to avoid breaking existing code). However, the DIP for ProtoObject has yet to be fully sorted out, and it definitely hasn't been accepted yet, so it can't yet fix the problem. So, for now, you're basically forced to use @trusted when comparing class references in @safe code. It's annoying, but because Object's opEquals is @system, we're kind of stuck at the moment. - Jonathan M Davis
Re: Distinguish between a null array and an empty array
On Sunday, 24 May 2020 at 12:12:31 UTC, bauss wrote: Is there a way to do that? Since the following are both true: int[] a = null; int[] b = []; assert(a is null); assert(!a.length); assert(b is null); assert(!b.length); What I would like is to tell that b is an empty array and a is a null array. I'm aware that D is special in that they're equal here BUT in my use-case I must absolutely handle them differently.
Distinguish between a null array and an empty array
Is there a way to do that? Since the following are both true: int[] a = null; int[] b = []; assert(a is null); assert(!a.length); assert(b is null); assert(!b.length); What I would like is to tell that b is an empty array and a is a null array.
Re: How to flatten N-dimensional array?
On Sunday, 24 May 2020 at 11:21:00 UTC, 9il wrote: On Saturday, 23 May 2020 at 18:15:32 UTC, Pavel Shkadzko wrote: [...] If the common nd-array isn't jugged (a parallelotop), you can use fuse function. -- /+dub.sdl: dependency "mir-algorithm" version="~>3.8.12" +/ import std.stdio: writeln; import mir.ndslice; void main() { auto arr = [[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], [[10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], [[20, 21, 22, 23, 24], [25, 26, 27, 28, 29]]]; auto flatten = arr.fuse.field; static assert(is(typeof(flatten) == int[])); assert(flatten == 30.iota); } -- It performs exactly one allocation. Yep, I know about Mir fuse. I was more wondering about the absence of flatten in Phobos. But on dlang forum some people claimed that when it comes to anything multidimensional, use Mir.
Re: How to flatten N-dimensional array?
On Saturday, 23 May 2020 at 18:15:32 UTC, Pavel Shkadzko wrote: I have tried to implement a simple flatten function for multidimensional arrays with recursive templates but got stuck. Then I googled a little and stumped into complex https://rosettacode.org/wiki/Flatten_a_list#D implementation which requires your arrays to be either TreeList or Algebraic. That is, it does not work out-of-the-box on something like int[][][]. I'd like to clarify a couple of questions first. How come Phobos doesn't have "flatten" function for arrays? Is there an implementation of flatten that works out-of-the-box on N-dim arrays outside of Phobos? Excluding "flattened" from mir.ndslice since it works on Slices. If the common nd-array isn't jugged (a parallelotop), you can use fuse function. -- /+dub.sdl: dependency "mir-algorithm" version="~>3.8.12" +/ import std.stdio: writeln; import mir.ndslice; void main() { auto arr = [[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], [[10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], [[20, 21, 22, 23, 24], [25, 26, 27, 28, 29]]]; auto flatten = arr.fuse.field; static assert(is(typeof(flatten) == int[])); assert(flatten == 30.iota); } -- It performs exactly one allocation.
Re: opEquals @safe is ignored
On Sunday, 24 May 2020 at 08:57:28 UTC, Luis wrote: dmd ignores @trusted or @safe on opEquals, throwing this error : onlineapp.d(27): Error: @safe function onlineapp.__unittest_L24_C7 cannot call @system function object.opEquals An override @system or @trusted function can't be @safe, or I it a bug ? Also, how will this be affected by DIP1028 ? Looking at the output, it's actually druntime's opEquals that can't be called. That's the global function that ensure opEquals is called on both sides of the comparison, and it's not @safe. This makes classes even worse to use in D than, and I'm not sure how to properly handle this. If we make it @trusted, suddenly I can call @system opEquals from @safe functions without issue. Root cause is, classes in D all inherit from Object, which has some defaults that aren't always what you want. It seems DIP1028 will make your code automatically compile, along with this: class C { override bool opEquals(Object o) @system { *cast(int*)123456 = 3; return true; } } @safe void mySafeFunction() { assert(new C() == new C()); } -- Simen
Re: How to flatten N-dimensional array?
On Saturday, 23 May 2020 at 19:59:30 UTC, Ali Çehreli wrote: On 5/23/20 11:15 AM, Pavel Shkadzko wrote:> I have tried to implement a simple flatten function for multidimensional [...] Thank you, I was lacking practical examples for templates with "if" constructs, ehh.
opEquals @safe is ignored
Lets take this example code (https://run.dlang.io/is/Vkpx9j) : ´´´D import std; void main() { } class ExampleC { int x; this (int x) @safe { this.x = x; } override bool opEquals(Object o) const @trusted { if (ExampleC rhs = cast(ExampleC)o) { return this.x == rhs.x; } return false; } } @safe unittest { auto c = new ExampleC(1); assert(c != new ExampleC(23)); } ´´´ dmd ignores @trusted or @safe on opEquals, throwing this error : onlineapp.d(27): Error: @safe function onlineapp.__unittest_L24_C7 cannot call @system function object.opEquals An override @system or @trusted function can't be @safe, or I it a bug ? Also, how will this be affected by DIP1028 ?
Using Vibe.d for not HTTP
Hi, Clearly Vibe.d is mostly for people doing HTTP and HTTPS stuff. Yet it claims to be able to support TCP and UDP working with other protocols. However, all the serious examples are HTTP/HTTPS related. All the TCP and UDP examples are basically trivial and thus useless to me for learning. I am hoping I have just missed the page/example that does something more than just echo for a TCP server. If I haven't, is ther an example somewhere people know of that I can look at? My problem is that I am not sure how to do a read/write system that is not just echo using the "connection.write(connection)" trick. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Learning Vibe.d
On Sat, 2020-05-23 at 20:52 +, Steven Schveighoffer via Digitalmars-d- learn wrote: […] > > It’s a recent problem with vibe-core. I’ve had to switch back to > version 1.8.1. > > https://github.com/vibe-d/vibe-core/issues/205 Really good to know this is a genuine problem and not just me doing something wrong! :-) For my purposes switching to using SIGKILL rather than SIGTERM in my tests seems to work with 1.9.1, so I'll go with that till 1.9.2 or 1.10.0 produces a fix rather than revert to 1.8.1. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Asserting that a base constructor is always called
On Sunday, May 24, 2020 12:38:46 AM MDT Tim via Digitalmars-d-learn wrote: > Oh right. I mean it makes sense but I got confused when super() > is valid syntax. Why would you need to call the super constructor > when it's called automatically? 1. If you wanted to run any code before calling the base class constructor. e.g. depending on the arguments to the derived class constructor, you could call one base constructor, or you could call a different base class constructor. You could even have the base class constructor call a virtual function, and what that virtual function did depended on something you had set in the derived class prior to calling the base class constructor (since unlike C++, it's safe to call virtual functions from within constructors). 2. If the base class constructor is not a default constructor, then you have to explicitly call it, because it has to be passed arguments. - Jonathan M Davis
Re: Asserting that a base constructor is always called
On Sunday, 24 May 2020 at 06:38:46 UTC, Tim wrote: Oh right. I mean it makes sense but I got confused when super() is valid syntax. Why would you need to call the super constructor when it's called automatically? A base class with a constructor that has no args will automatically get called at the start of a child class if it is not explicitly called. You can call it yourself anywhere in an always executed branch of the constructor. As for why, if you wanted to do some logging before the base constructor was called. You need to call the base class's constructor explicitly when it has arguments and there is no default constructor in the base class. This must be done in an always executed branch. This must be called or the compiler will issue an error.