Re: Concatenating compile time sequences
On Sat, Mar 02, 2019 at 02:16:22AM +, Victor Porton via Digitalmars-d-learn wrote: > I try to split a compile time sequence of types and names into a > sequence consisting of two-element subsequences (each of type and > name). > > That is, I want to transform: > > (int, "x", float, "y", double, "z") > > into > > (AliasSeq!(int, "x"), AliasSeq!(float, "y"), AliasSeq!(double, "z")) Keep in mind that sequences produced by AliasSeq are auto-expanding, meaning the above construct will automatically flatten into a flat AliasSeq!(int, "x", float, "y", double, "z"). If that's not what you want, you need to wrap your subsequences in a separate, non-eponymous template. > I am trying like this: > > private alias enum processFields() = AliasSeq!(); I'm not sure what "alias enum" is supposed to mean; is that a typo? Surely you mean just "alias"? > private alias enum processFields(T, name, Fields...) = > AliasSeq!(AliasSeq!(T, name), processFields!(Fields)); This line doesn't do what you think it does, because of auto-expansion. It's essentially exactly the same thing as: private alias processFields(T, name, Fields...) = AliasSeq!(T, name, processFields!(Fields)); i.e., the nested AliasSeq has no effect. > But the above would (as I understand) make AliasSeq! returned by the > recursively called processFields an element of the parent sequence > rather than its tail subsequence as it should. If you want anything that retains a nested structure, you cannot use AliasSeq because of auto-expansion. You need to define your own, non-eponymous template container, e.g.: template MySeq(T...) { alias data = T; } alias processFields(T, name, Fields...) = AliasSeq!(MySeq!(T, name), MySeq!(processFields!(Fields))); The MySeq!(...) "protect" their contents from flattening into the outer list, while the outer AliasSeq causes individual MySeq!(...)'s to be promoted to the top level sequence rather than producing a tree-like structure. Note that to access the data inside a MySeq, you'll have to use .data, for example: alias fields = processFields!(int, "x", float, "y"); alias type0 = fields[0].data[0]; // int string name0 = fields[0].data[1]; // "x" alias type1 = fields[1].data[0]; // float string name1 = fields[1].data[1]; // "y" Hope this helps. T -- Windows: the ultimate triumph of marketing over technology. -- Adrian von Bidder
Re: How to cast arrays?
On Saturday, 2 March 2019 at 02:14:01 UTC, Murilo wrote: How do I cast a ubyte[] into uint[]? It keeps raising an error, I have read the documentation saying there are restrictions for that concerning the length of the arrays. By the way here is how: void foo(){ ubyte[] x = [1,2]; auto y = (cast(int*) )[0..2]; writeln(y); } Matheus.
Re: How to cast arrays?
On Saturday, 2 March 2019 at 02:14:01 UTC, Murilo wrote: How do I cast a ubyte[] into uint[]? It keeps raising an error, I have read the documentation saying there are restrictions for that concerning the length of the arrays. https://dlang.org/spec/expression.html#cast_expressions "Casting a dynamic array to another dynamic array is done only if the array lengths multiplied by the element sizes match. The cast is done as a type paint, with the array length adjusted to match any change in element size. If there's not a match, a runtime error is generated." Matheus.
Re: How to cast arrays?
On Sat, Mar 02, 2019 at 02:14:01AM +, Murilo via Digitalmars-d-learn wrote: > How do I cast a ubyte[] into uint[]? It keeps raising an error, I have > read the documentation saying there are restrictions for that > concerning the length of the arrays. That depends on what you're trying to accomplish. Are you trying to *reinterpret* the ubytes as uints? I.e., every 4 ubytes will be interpreted as 1 uint? If so, cast(uint[]) is your ticket. And obviously it will require that the .length of the ubyte[] must be a multiple of uint.sizeof, since otherwise the last element would be malformed. And there will probably be alignment issues as well. However, if you're trying to *transcribe* ubyte values into uint, i.e., promote each ubyte value to uint, then what you want is NOT a cast, but a transcription, i.e., copy ubytes into uint with integer promotion. There are various ways of doing this; an obvious one is: ubyte[] bytes = ...; uint[] ints = bytes.map!(b => cast(uint) b).array; T -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald Knuth
Concatenating compile time sequences
I try to split a compile time sequence of types and names into a sequence consisting of two-element subsequences (each of type and name). That is, I want to transform: (int, "x", float, "y", double, "z") into (AliasSeq!(int, "x"), AliasSeq!(float, "y"), AliasSeq!(double, "z")) I am trying like this: private alias enum processFields() = AliasSeq!(); private alias enum processFields(T, name, Fields...) = AliasSeq!(AliasSeq!(T, name), processFields!(Fields)); But the above would (as I understand) make AliasSeq! returned by the recursively called processFields an element of the parent sequence rather than its tail subsequence as it should. Please help to fix the above code. I want namely a recursive implementation like the above, because I am going to generalize it for some more complex cases.
How to cast arrays?
How do I cast a ubyte[] into uint[]? It keeps raising an error, I have read the documentation saying there are restrictions for that concerning the length of the arrays.
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote: On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote: On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote: I've installed D compiler, and when i try to run a D script with filename without an extension/file type named: program via: ./program I'm getting and error: vaidas@SATELLITE-L855:~/Desktop$ ./program Error: module `program` is in file './program.d' which cannot be read import path[0] = . import path[1] = /snap/dmd/49/bin/../import/druntime import path[2] = /snap/dmd/49/bin/../import/phobos Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", "-I."] Now, when I rename my scirpt file : program To: program.d and execute it by: ./program.d I no longer have an error. Is this an intended behaviour? In such questions it's important to show your shebang since that's what runs your script. Given your symptoms I guess you're using the following: #!/bin/env rdmd And indeed rdmd won't call your script if it doesn't have the proper extension. Try using this instead: #!/bin/dmd -run The shebang I used: #!/usr/bin/env rdmd I was visiting Dlang Tour and that's where I've got an example of shebang usage, directly from there: https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd The shebang you suggested actually works perfectly: #!/bin/dmd -run "And indeed rdmd won't call your script if it doesn't have the proper extension." Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd Instead of the one you mentioned, that is fool proof. (#!/bin/dmd -run) Is that an error/mistake in Dlang Tour guide? Frankly using rdmd is closer to being fool-proof, you just haven't hit the corner cases yet :) I'd either get used to having scripts with a .d extension or make an alias or a quick wrapper in shell and call it "program": #!/bin/sh exec rdmd /path/to/program.d "$@" It's not exactly a mistake, it's just not that important to most people I guess. And as your program grows you're likely to take the habit to compile it and work with the binary directly anyway.
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote: On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote: "And indeed rdmd won't call your script if it doesn't have the proper extension." Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd Instead of the one you mentioned, that is fool proof. (#!/bin/dmd -run) Is that an error/mistake in Dlang Tour guide? You may want to change that too: #!/bin/dmd -i -run DMD doesn't automatically compile imported files (at least not until -i came along), rdmd existed to solve that problem... I don't know what value it brings with the -i switch existing. All systems I know only accept one argument in shebang so sadly it's not that simple :)
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote: On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote: On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote: [...] In such questions it's important to show your shebang since that's what runs your script. Given your symptoms I guess you're using the following: #!/bin/env rdmd And indeed rdmd won't call your script if it doesn't have the proper extension. Try using this instead: #!/bin/dmd -run The shebang I used: #!/usr/bin/env rdmd I was visiting Dlang Tour and that's where I've got an example of shebang usage, directly from there: https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd The shebang you suggested actually works perfectly: #!/bin/dmd -run "And indeed rdmd won't call your script if it doesn't have the proper extension." Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd Instead of the one you mentioned, that is fool proof. (#!/bin/dmd -run) Is that an error/mistake in Dlang Tour guide? Well, because it isn't fool proof either ;-) It won't work once you start using more files as you would then need the -i flag , but unfortunately most systems don't support more than one shebang argument. I think it's simply a missing feature of rdmd to accept files without an extension as D programs (though of course the tour could be improved to be more explanatory here too).
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 16:45:38 UTC, Seb wrote: On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote: I don't know what value it brings with the -i switch existing. Almost none, except that it's twice as slow as DMD because it needs to run DMD twice to learn about all the dependencies. It's only useful for a few small things now: - '-e': evaluate d code with all modules automatically imported (though now that there's std.experimental.all this value is gone too) - makefile deps generation - shebang line (as arguments can't be part of the shebang line) (The list is not complete) I forgot one big reason why rdmd is still nice: caching. It does save the generated dependency file list and checks all modification time stamps, s.t. if nothing has changed, it'll run a cached build
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote: I don't know what value it brings with the -i switch existing. Almost none, except that it's twice as slow as DMD because it needs to run DMD twice to learn about all the dependencies. It's only useful for a few small things now: - '-e': evaluate d code with all modules automatically imported (though now that there's std.experimental.all this value is gone too) - makefile deps generation - shebang line (as arguments can't be part of the shebang line) (The list is not complete)
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote: "And indeed rdmd won't call your script if it doesn't have the proper extension." Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd Instead of the one you mentioned, that is fool proof. (#!/bin/dmd -run) Is that an error/mistake in Dlang Tour guide? You may want to change that too: #!/bin/dmd -i -run DMD doesn't automatically compile imported files (at least not until -i came along), rdmd existed to solve that problem... I don't know what value it brings with the -i switch existing.
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote: On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote: I've installed D compiler, and when i try to run a D script with filename without an extension/file type named: program via: ./program I'm getting and error: vaidas@SATELLITE-L855:~/Desktop$ ./program Error: module `program` is in file './program.d' which cannot be read import path[0] = . import path[1] = /snap/dmd/49/bin/../import/druntime import path[2] = /snap/dmd/49/bin/../import/phobos Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", "-I."] Now, when I rename my scirpt file : program To: program.d and execute it by: ./program.d I no longer have an error. Is this an intended behaviour? In such questions it's important to show your shebang since that's what runs your script. Given your symptoms I guess you're using the following: #!/bin/env rdmd And indeed rdmd won't call your script if it doesn't have the proper extension. Try using this instead: #!/bin/dmd -run The shebang I used: #!/usr/bin/env rdmd I was visiting Dlang Tour and that's where I've got an example of shebang usage, directly from there: https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd The shebang you suggested actually works perfectly: #!/bin/dmd -run "And indeed rdmd won't call your script if it doesn't have the proper extension." Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd Instead of the one you mentioned, that is fool proof. (#!/bin/dmd -run) Is that an error/mistake in Dlang Tour guide?
Re: How to attach function attributes to delegate type?
On Wednesday, 27 February 2019 at 20:45:33 UTC, Alex wrote: On Wednesday, 27 February 2019 at 20:03:15 UTC, Q. Schroll wrote: For any type constructors like const, I can use ConstOf!T to get `T` with const attached. For a delegate/function type DG, e.g. int delegate(int), how can I get the @safe version of that type, i.e. int delegate(int) @safe? I tried alias SafeOf(DG) = DG @safe; but it didn't compile. The case is not @safe-specific; it's the same for all function attributes. At https://p0nce.github.io/d-idioms/ there is a demonstration for @nogc: ´´´ import std.traits; // Casts @nogc out of a function or delegate type. auto assumeNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.nogc; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; } ´´´ Didn't try this for other cases, however... When I need particular attributes, such as for a comparator, but also need to pass in a function as a template argument, one approach I've started to adopt is to only call this function from within a wrapper that has all the properties I want. For example: import std.stdio; class MyThing(T, alias LessF) { // This wrapper defines the conditions for a valid LessF. @safe @nogc private static bool less(in T t1, in T t2) { return LessF(t1, t2); } } void main() { MyThing!(int, (a, b) => a < b) a; // Compiles fine! MyThing!(int, (a, b) { writeln("Not @nogc!"); // Compiler error! return a < b; }) b; } The error looks like this, which is fairly readable too. onlineapp.d(6): Error: `@nogc` function `onlineapp.main.MyThing!(int, (a, b) { writeln("Not @nogc!"); return a < b; } ).MyThing.less` cannot call non-@nogc function
Re: My template tuple code does not compile
On Wednesday, 27 February 2019 at 22:45:03 UTC, Victor Porton wrote: I rewrote it again: https://github.com/vporton/struct-params-dlang/blob/f50f7e5919f90b1d06bf0cc08e3055548aad1797/source/struct_params.d But it does not work :-( What is my error? source/struct_params.d(43,60): Error: function expected before `()`, not `()` of type `()` source/struct_params.d(44,43): Error: undefined identifier `fieldsWithDefaults` source/struct_params.d(56,11): Error: template instance `struct_params.ProviderParamsCode!("S", int, "x", float, "y")` error instantiating source/struct_params.d(82,5): Error: mixin `struct_params.__unittest_L81_C1.ProviderParams!("S", int, "x", float, "y")` error instantiating You seem to have misunderstood how staticMap works. It operates on a compile-time list of values, and only takes a single set of parameters: staticMap!(fn, item0, item1, item...), not staticMap!fn(item0, item1, item...). In addition, Types.length.iota will create a run-time range of values, not a compile-time AliasSeq of values. For this, you can use std.meta.aliasSeqOf: staticMap!(regularField, aliasSeqOf!(Types.length.iota)). Next, join expects a range, not an AliasSeq. In other words, staticMap!(...).join('\n') will fail to compile - staticMap!(...) will need to be turned into a range of some sort. We can do this the same way we'd turn any list of values into a range - by putting brackets around it. Just like [1,2,3] is a valid array, so is [staticMap!(...)], supposing the elements have some common type. But wait - there's more! You're using __traits(identifier, Types[i]). As pointed out in https://forum.dlang.org/post/smgsgycpgvtagfsdx...@forum.dlang.org, this will fail for built-in types, as they don't have an identifier. You can get their names, as well as the name of any other type with Types[i].stringof. Lastly, you have not imported std.typecons, so your use of Nullable will fail. So, that's the issues that cause it to not compile. There are issues also in the code that isn't instantiated, i.e. callFunctionWithParamsStruct and callMemberFunctionWithParamsStruct. Since these aren't used, they don't cause compile failure yet. The main issue here is exactly the same as above: a conflation of run-time and compile-time responsibilities, this time when using map. Since map is a run-time function, it can't do compile-time things like __traits(getMember) - you'll need to use staticMap for that. However, there's a much easier solution: auto callFunctionWithParamsStruct(alias f, S)(S s) { return f(s.tupleof); } The same thing can be done for callMemberFunctionWithParamsStruct. Now, I will note that no checking is done that parameter names and field names match, so void fun(int numberOfBeans, string nameOfCat) can easily be called with struct S { int temperatureOfPudding; string declarationOfIndependence; }, but I will assume that's because you haven't gotten around to it yet. -- Simen
Re: Executing a D script without an [extension in the filename] leads to an error
On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote: I've installed D compiler, and when i try to run a D script with filename without an extension/file type named: program via: ./program I'm getting and error: vaidas@SATELLITE-L855:~/Desktop$ ./program Error: module `program` is in file './program.d' which cannot be read import path[0] = . import path[1] = /snap/dmd/49/bin/../import/druntime import path[2] = /snap/dmd/49/bin/../import/phobos Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", "-I."] Now, when I rename my scirpt file : program To: program.d and execute it by: ./program.d I no longer have an error. Is this an intended behaviour? In such questions it's important to show your shebang since that's what runs your script. Given your symptoms I guess you're using the following: #!/bin/env rdmd And indeed rdmd won't call your script if it doesn't have the proper extension. Try using this instead: #!/bin/dmd -run
Executing a D script without an [extension in the filename] leads to an error
I've installed D compiler, and when i try to run a D script with filename without an extension/file type named: program via: ./program I'm getting and error: vaidas@SATELLITE-L855:~/Desktop$ ./program Error: module `program` is in file './program.d' which cannot be read import path[0] = . import path[1] = /snap/dmd/49/bin/../import/druntime import path[2] = /snap/dmd/49/bin/../import/phobos Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", "-I."] Now, when I rename my scirpt file : program To: program.d and execute it by: ./program.d I no longer have an error. Is this an intended behaviour?