Re: Bug in D!!!
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta wrote: On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips wrote: I've love being able to inherit and override generic functions in C#. Unfortunately C# doesn't use templates and I hit so many other issues where Generics just suck. I don't think it is appropriate to dismiss the need for the compiler to generate a virtual function for every instantiated T, after all, the compiler can't know you have a finite known set of T unless you tell it. But lets assume we've told the compiler that it is compiling all the source code and it does not need to compile for future linking. First the compiler will need to make sure all virtual functions can be generated for the derived classes. In this case the compiler must note the template function and validate all derived classes include it. That was easy. Next up each instantiation of the function needs a new v-table entry in all derived classes. Current compiler implementation will compile each module independently of each other; so this feature could be specified to work within the same module or new semantics can be written up of how the compiler modifies already compiled modules and those which reference the compiled modules (the object sizes would be changing due to the v-table modifications) With those three simple changes to the language I think that this feature will work for every T. Specifying that there will be no further linkage is the same as making T finite. T must be finite. C# uses generics/IR/CLR so it can do things at run time that is effectively compile time for D. By simply extending the grammar slightly in an intuitive way, we can get the explicit finite case, which is easy: foo(T in [A,B,C])() and possibly for your case foo(T in )() would work or foo(T in )() the `in` keyword makes sense here and is not used nor ambiguous, I believe. While I agree that `in` does make sense for the semantics involved, it is already used to do a failable key lookup (return pointer to value or null if not present) into an associative array [1] and input contracts. It wouldn't be ambiguous AFAICT, but having a keyword mean three different things depending on context would make the language even more complex (to read). Yes, but they are independent, are they not? Maybe not. foo(T in Typelist)() in, as used here is not a input contract and completely independent. I suppose for arrays it could be ambiguous. The contexts being independent of each other doesn't change that we would still be overloading the same keyword with three vastly different meanings. Two is already bad enough imho (and if I had a good idea with what to replace the "in" for AA's I'd propose removing that meaning). Why? Don't you realize that the contexts matters and it's what separates the meaning? In truly unambiguous contexts, it shouldn't matter. It may require one to decipher the context, which takes time, but there is nothing inherently wrong with it and we are limited to how many symbols we use(unfortunately we are generally stuck with the querty keyboard design, else we could use symbols out the ying yang and make things much clearer, but even mathematics, which is a near perfect language, "overloads" symbols meanings). You have to do this sort of thing when you limit the number of keywords you use. Again, ultimately it doesn't matter. A symbol is just a symbol. For me, as long as the context is clear, I don't see what kind of harm it can cause. You say it is bad, but you don't give the reasons why it is bad. If you like to think of `in` has having only one definition then the question is why? You are limiting yourself. The natural languages are abound with such multi-definitions. Usually in an ambiguous way and it can cause a lot of problems, but for computer languages, it can't(else we couldn't actually compile the programs). Context sensitive grammars are provably more expressive than context free. https://en.wikipedia.org/wiki/Context-sensitive_grammar Again, I'm not necessarily arguing for them, just saying that one shouldn't avoid them just to avoid them. For me, and this is just me, I do not find it ambiguous. I don't find different meanings ambiguous unless the context overlaps. Perceived ambiguity is not ambiguity, it's just ignorance... which can be overcome through learning. Hell, D has many cases where there are perceived ambiguities... as do most things. It's not about ambiguity for me, it's about readability. The more significantly different meanings you overload some keyword - or symbol, for that matter - with, the harder it becomes to read. I don't think that is true. Everything is hard to read
Re: 24-bit int
On Saturday, 2 September 2017 at 03:29:20 UTC, EntangledQuanta wrote: On Saturday, 2 September 2017 at 02:49:41 UTC, Ilya Yaroshenko wrote: On Friday, 1 September 2017 at 19:39:14 UTC, EntangledQuanta wrote: Is there a way to create a 24-bit int? One that for all practical purposes acts as such? This is for 24-bit stuff like audio. It would respect endianness, allow for arrays int24[] that work properly, etc. Hi, Probably you are looking for bitpack ndslice topology: http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html#.bitpack sizediff_t[] data; // creates a packed signed integer slice with max allowed value equal to `2^^24 - 1`. auto packs = data[].sliced.bitpack!24; packs has the same API as D arrays Package is Mir Algorithm http://code.dlang.org/packages/mir-algorithm Best, Ilya Thanks. Seems useful. Just added `bytegroup` topology. Released in v0.6.12 (will be available in DUB after few minutes.) http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html#bytegroup It is faster for your task then `bitpack`. Best regards, Ilya
Re: Bug in D!!!
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta wrote: On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips wrote: I've love being able to inherit and override generic functions in C#. Unfortunately C# doesn't use templates and I hit so many other issues where Generics just suck. I don't think it is appropriate to dismiss the need for the compiler to generate a virtual function for every instantiated T, after all, the compiler can't know you have a finite known set of T unless you tell it. But lets assume we've told the compiler that it is compiling all the source code and it does not need to compile for future linking. First the compiler will need to make sure all virtual functions can be generated for the derived classes. In this case the compiler must note the template function and validate all derived classes include it. That was easy. Next up each instantiation of the function needs a new v-table entry in all derived classes. Current compiler implementation will compile each module independently of each other; so this feature could be specified to work within the same module or new semantics can be written up of how the compiler modifies already compiled modules and those which reference the compiled modules (the object sizes would be changing due to the v-table modifications) With those three simple changes to the language I think that this feature will work for every T. Specifying that there will be no further linkage is the same as making T finite. T must be finite. C# uses generics/IR/CLR so it can do things at run time that is effectively compile time for D. By simply extending the grammar slightly in an intuitive way, we can get the explicit finite case, which is easy: foo(T in [A,B,C])() and possibly for your case foo(T in )() would work or foo(T in )() the `in` keyword makes sense here and is not used nor ambiguous, I believe. While I agree that `in` does make sense for the semantics involved, it is already used to do a failable key lookup (return pointer to value or null if not present) into an associative array [1] and input contracts. It wouldn't be ambiguous AFAICT, but having a keyword mean three different things depending on context would make the language even more complex (to read). Yes, but they are independent, are they not? Maybe not. foo(T in Typelist)() in, as used here is not a input contract and completely independent. I suppose for arrays it could be ambiguous. The contexts being independent of each other doesn't change that we would still be overloading the same keyword with three vastly different meanings. Two is already bad enough imho (and if I had a good idea with what to replace the "in" for AA's I'd propose removing that meaning). For me, and this is just me, I do not find it ambiguous. I don't find different meanings ambiguous unless the context overlaps. Perceived ambiguity is not ambiguity, it's just ignorance... which can be overcome through learning. Hell, D has many cases where there are perceived ambiguities... as do most things. It's not about ambiguity for me, it's about readability. The more significantly different meanings you overload some keyword - or symbol, for that matter - with, the harder it becomes to read. But in any case, I could care less about the exact syntax. It's just a suggestion that makes the most logical sense with regard to the standard usage of in. If it is truly unambiguous then it can be used. Well, yes, as I wrote, I think it is unambiguous (and can thus be used), I just think it shouldn't be used. Another alternative is foo(T of Typelist) which, AFAIK, of is not used in D and even most programming languages. Another could be foo(T -> Typelist) or even foo(T from Typelist) I would much rather see it as a generalization of existing template specialization syntax [1], which this is t.b.h. just a superset of (current syntax allows limiting to exactly one, you propose limiting to 'n'): --- foo(T: char) // Existing syntax: Limit T to the single type `char` foo(T: (A, B, C)) // New syntax: Limit T to one of A, B, or C --- Strictly speaking, this is exactly what template specialization is for, it's just that the current one only supports a single type instead of a set of types. Looking at the grammar rules, upgrading it like this is a fairly small change, so the cost there should be minimal. or whatever. Doesn't really matter. They all mean the same to me once the definition has been written in stone. Could use `foo(T eifjasldj Typelist)` for all I care. That's okay, but it does matter to me. The import thing for me is that such a simple syntax exists rather than the "complex syntax's" that have already been given(which are ultimately syntax's as ever
Re: std.algorithm.joiner unexpected behavior
Let me clarify, what I was going to create was a small utility, analogous to Perl <> operator, taking a list of file names and allowing forward iteration as it would be single stream of text lines. It would take no time to write the range from scratch, but what are all the phobos primitives for then? So it looks like this: auto catFiles(string[] args) { File[] files=args.map!(a => File(a)).array; if(files.empty) files~=stdin; return joiner(files.map!(a => a.byLine)); } but unfortunately it does not work. It seems, everybody agreed the problem is likely in the line buffer reused, however, replacing .byLine() with .byLineCopy() yields same result. Also, neither .byLine() nor .byLineCopy() return ForwardRange, just InputRange, so no .save() is probably called on them. And last, the utility is supposed to be fast, so using .byLineCopy() is very undesirable. Transient ranges may be uneasy to handle, but they allow to retain status of D as "better C" suitable for system programming. Using unsolicited internal copies is more typical for high-level scripting languages, and is one of the reasons of slower execution and high memory consumption. In short, I agree with your arguments, but still believe this is a bug, probably in joiner rather than in .byLine(). I'm going to take look at the code and will tell if find anything. Thank you for the discussion.
Re: 24-bit int
On Friday, 1 September 2017 at 19:39:14 UTC, EntangledQuanta wrote: Is there a way to create a 24-bit int? One that for all practical purposes acts as such? This is for 24-bit stuff like audio. It would respect endianness, allow for arrays int24[] that work properly, etc. If you need to perform math on integer audio, I strongly suggest to use int32 for this purpose to avoid performance degradation, then convert back to int24 when you're finished. Probably going to add such feature into my PCM library.
Re: Help required on Array appender
On Saturday, 2 September 2017 at 22:39:33 UTC, Nicholas Wilson wrote: On Saturday, 2 September 2017 at 21:11:17 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: [...] Hi, [...] Hi, Was able to resolve the above issue, but again getting the same for other lines such as below when i tried to add the appender. auto CleanDirlst = appender([]); CleanDirlst ~= PVStore[1][i].to!string.split(","); Error: cannot implicitly convert expression appender([]) of type Appender!(void[]) to string[]. You want `Appender!(string[])` Hi, Thank you very much, was able to resolve the issue.
Re: string to character code hex string
On 09/02/2017 11:02 AM, lithium iodate wrote: > On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote: >> You're right but I think there is no intention of interpreting the >> result as UTF-8. "f62026" is just to be used as "f62026", which can be >> converted byte-by-byte back to "ö…". That's how understand the >> requirement anyway. >> >> Ali > > That is not possible, because you cannot know whether "f620" and "26" or > "f6" and "2026" (or any other combination) should form a code point > each. Additional padding to constant width (8 hex chars) is needed. Ok, I see that I made a mistake but I still don't think the conversion is one way. If we can convert byte-by-byte, we should be able to convert back byte-by-byte, right? What I failed to ensure was to iterate by code units. The following is able to get the same string back: import std.stdio; import std.string; import std.algorithm; import std.range; import std.utf; import std.conv; auto toHex(R)(R input) { // As Moritz Maxeiner says, this format is expensive return input.byCodeUnit.map!(c => format!"%02x"(c)).joiner; } int hexValue(C)(C c) { switch (c) { case '0': .. case '9': return c - '0'; case 'a': .. case 'f': return c - 'a' + 10; default: assert(false); } } auto fromHex(R, Dst = char)(R input) { return input.chunks(2).map!((ch) { auto high = ch.front.hexValue * 16; ch.popFront(); return high + ch.front.hexValue; }).map!(value => cast(Dst)value); } void main() { assert("AAA".toHex.fromHex.equal("AAA")); assert("ö…".toHex.fromHex.equal("ö…".byCodeUnit)); // Alternative check: assert("ö…".toHex.fromHex.text.equal("ö…")); } Ali
Re: Bug in D!!!
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips wrote: I've love being able to inherit and override generic functions in C#. Unfortunately C# doesn't use templates and I hit so many other issues where Generics just suck. I don't think it is appropriate to dismiss the need for the compiler to generate a virtual function for every instantiated T, after all, the compiler can't know you have a finite known set of T unless you tell it. But lets assume we've told the compiler that it is compiling all the source code and it does not need to compile for future linking. First the compiler will need to make sure all virtual functions can be generated for the derived classes. In this case the compiler must note the template function and validate all derived classes include it. That was easy. Next up each instantiation of the function needs a new v-table entry in all derived classes. Current compiler implementation will compile each module independently of each other; so this feature could be specified to work within the same module or new semantics can be written up of how the compiler modifies already compiled modules and those which reference the compiled modules (the object sizes would be changing due to the v-table modifications) With those three simple changes to the language I think that this feature will work for every T. Specifying that there will be no further linkage is the same as making T finite. T must be finite. C# uses generics/IR/CLR so it can do things at run time that is effectively compile time for D. By simply extending the grammar slightly in an intuitive way, we can get the explicit finite case, which is easy: foo(T in [A,B,C])() and possibly for your case foo(T in )() would work or foo(T in )() the `in` keyword makes sense here and is not used nor ambiguous, I believe. While I agree that `in` does make sense for the semantics involved, it is already used to do a failable key lookup (return pointer to value or null if not present) into an associative array [1] and input contracts. It wouldn't be ambiguous AFAICT, but having a keyword mean three different things depending on context would make the language even more complex (to read). Yes, but they are independent, are they not? Maybe not. foo(T in Typelist)() in, as used here is not a input contract and completely independent. I suppose for arrays it could be ambiguous. For me, and this is just me, I do not find it ambiguous. I don't find different meanings ambiguous unless the context overlaps. Perceived ambiguity is not ambiguity, it's just ignorance... which can be overcome through learning. Hell, D has many cases where there are perceived ambiguities... as do most things. But in any case, I could care less about the exact syntax. It's just a suggestion that makes the most logical sense with regard to the standard usage of in. If it is truly unambiguous then it can be used. Another alternative is foo(T of Typelist) which, AFAIK, of is not used in D and even most programming languages. Another could be foo(T -> Typelist) or even foo(T from Typelist) or whatever. Doesn't really matter. They all mean the same to me once the definition has been written in stone. Could use `foo(T eifjasldj Typelist)` for all I care. The import thing for me is that such a simple syntax exists rather than the "complex syntax's" that have already been given(which are ultimately syntax's as everything is at the end of the day). W.r.t. to the idea in general: I think something like that could be valuable to have in the language, but since this essentially amounts to syntactic sugar (AFAICT), but I'm not (yet) convinced that with `static foreach` being included it's worth the cost. Everything is syntactic sugar. So it isn't about if but how much. We are all coding in 0's and 1's whether we realize it or not. The point if syntax(or syntactic sugar) is to reduce the amount of 0's and 1's that we have to *effectively* code by grouping common patterns in to symbolic equivalents(by definition). This is all programming is. We define certain symbols to mean certain bit patterns, or generic bit matters(an if keyword/symbol is a generic bit pattern, a set of machine instructions(0's and 1's) and substitution placeholders that are eventually filled with 0's and 1's). No one can judge the usefulness of syntax until it has been created because what determines how useful something is is its use. But you can't use something if it doesn't exist. I think many fail to get that. The initial questions should be: Is there a gap in the language? (Yes in this case). Can the gap be filled? (this is a theoretical/mathematical question that has to be answered. Most people jump the gun here and make assumptions) Does the gap need t
Re: nested module problem
On Saturday, 2 September 2017 at 23:02:18 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 21:56:15 UTC, Jean-Louis Leroy wrote: [...] Hmmm I see...I was thinking of spinning the runtime part of my openmethods library into its own module (like here https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea... Why does it look like a bad idea (I don't see an immediate issue the module structure either way)? * in the module structure
Re: nested module problem
On Saturday, 2 September 2017 at 21:56:15 UTC, Jean-Louis Leroy wrote: [...] Hmmm I see...I was thinking of spinning the runtime part of my openmethods library into its own module (like here https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea... Why does it look like a bad idea (I don't see an immediate issue the module structure either way)?
Re: Help required on Array appender
On Saturday, 2 September 2017 at 21:11:17 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: [...] Hi, [...] Hi, Was able to resolve the above issue, but again getting the same for other lines such as below when i tried to add the appender. auto CleanDirlst = appender([]); CleanDirlst ~= PVStore[1][i].to!string.split(","); Error: cannot implicitly convert expression appender([]) of type Appender!(void[]) to string[]. You want `Appender!(string[])`
Re: nested module problem
On Saturday, 2 September 2017 at 21:42:59 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 21:24:19 UTC, Jean-Louis Leroy wrote: [...] Yes, these now both fail because you cannot have a module `foo` and a package `foo` at the same time (they share a namespace), I forgot about that. [...] (same as before, no issue here) [...] You created the 'foo' package by specifying `module foo.bar` in foo/bar.d. [...] AFAIK you can't; consider: -- baz.d --- import foo; in the same directory as foo.d. If foo/package.d exists (with `module foo` inside), what should baz.d import? foo.d or foo/package.d? The point being that we could have either used foo/package.d or foo.d for a package file, but not both (as that would allow ambiguity) and package.d was chosen. [1] https://dlang.org/spec/module.html#package-module Hmmm I see...I was thinking of spinning the runtime part of my openmethods library into its own module (like here https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea...
Re: nested module problem
On Saturday, 2 September 2017 at 21:24:19 UTC, Jean-Louis Leroy wrote: On Saturday, 2 September 2017 at 20:48:22 UTC, Moritz Maxeiner wrote: So the compiler wants you to import it by the name it has inferred for you (The fix being either specifying the module name in foo/bar.d as `module foo.bar`, or importing it as via `import bar;` in foo.d). [1] https://dlang.org/spec/module.html I thought of doing that, it merely changed the error. OK now I have: in foo.d: module foo; import foo.bar; in foo/bar.d: module foo.bar; $ dmd -c foo.d foo/bar.d foo/bar.d(1): Error: package name 'foo' conflicts with usage as a module name in file foo.d If I compile separately: jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo.d foo/bar.d(1): Error: package name 'foo' conflicts with usage as a module name in file foo.d Yes, these now both fail because you cannot have a module `foo` and a package `foo` at the same time (they share a namespace), I forgot about that. jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo/bar.d (same as before, no issue here) It believes that 'foo' is a package...because there is a 'foo' directory? You created the 'foo' package by specifying `module foo.bar` in foo/bar.d. I see that a workaround is to move foo.d to foo/package.d but I would like to avoid that. AFAIK you can't; consider: -- baz.d --- import foo; in the same directory as foo.d. If foo/package.d exists (with `module foo` inside), what should baz.d import? foo.d or foo/package.d? The point being that we could have either used foo/package.d or foo.d for a package file, but not both (as that would allow ambiguity) and package.d was chosen. [1] https://dlang.org/spec/module.html#package-module
Re: templated type reduction
On 09/02/2017 11:07 PM, EntangledQuanta wrote: struct X(T) { string type = T.stringof; T t; } [...] void* x = new X!int; (passed around the program) switch(x.type) { case "int" : break; } which is invalid yet perfectly valid! Is there any way to make this work legitly in D? Not with `void*`, I think. `void*` explicitly tells the compiler to forget anything it knows about the type. You could make a new type `struct XBase { string type; }` and use `XBase*` instead of `void*`. If you're going to `new` the instances anyway, classes could also help: class XBase { string type; } class X(T) : XBase { T t; } [...] note that it is really no different from struct X(T) { string type = "asdf"; T t; } in which we can do string type = (cast(X!int)x).type; // = asdf or string type = (cast(X!float)x).type; // = asdf but even this is a bit fishy. I think this is the best you can do with `void*`. Maybe add an assert in X that checks that the field `type` is always at the same offset (0). Heres some code that does the offset hack: struct X(T) { string type = T.stringof; T x; } int main(string[] args) { void* x = new X!int; int o = (X!float).type.offsetof; auto y = *cast(string*)(x + o); writeln(y); return 0; } I don't think `.offsetof` buys you anything over `(cast(X!int)x).type`. By the way, `void main()` is valid. You don't need to return 0 or declare `args` if you don't use them.
Re: nested module problem
On Saturday, 2 September 2017 at 20:48:22 UTC, Moritz Maxeiner wrote: So the compiler wants you to import it by the name it has inferred for you (The fix being either specifying the module name in foo/bar.d as `module foo.bar`, or importing it as via `import bar;` in foo.d). [1] https://dlang.org/spec/module.html I thought of doing that, it merely changed the error. OK now I have: in foo.d: module foo; import foo.bar; in foo/bar.d: module foo.bar; $ dmd -c foo.d foo/bar.d foo/bar.d(1): Error: package name 'foo' conflicts with usage as a module name in file foo.d If I compile separately: jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo.d foo/bar.d(1): Error: package name 'foo' conflicts with usage as a module name in file foo.d jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo/bar.d It believes that 'foo' is a package...because there is a 'foo' directory? I see that a workaround is to move foo.d to foo/package.d but I would like to avoid that.
Re: Bug in D!!!
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips wrote: I've love being able to inherit and override generic functions in C#. Unfortunately C# doesn't use templates and I hit so many other issues where Generics just suck. I don't think it is appropriate to dismiss the need for the compiler to generate a virtual function for every instantiated T, after all, the compiler can't know you have a finite known set of T unless you tell it. But lets assume we've told the compiler that it is compiling all the source code and it does not need to compile for future linking. First the compiler will need to make sure all virtual functions can be generated for the derived classes. In this case the compiler must note the template function and validate all derived classes include it. That was easy. Next up each instantiation of the function needs a new v-table entry in all derived classes. Current compiler implementation will compile each module independently of each other; so this feature could be specified to work within the same module or new semantics can be written up of how the compiler modifies already compiled modules and those which reference the compiled modules (the object sizes would be changing due to the v-table modifications) With those three simple changes to the language I think that this feature will work for every T. Specifying that there will be no further linkage is the same as making T finite. T must be finite. C# uses generics/IR/CLR so it can do things at run time that is effectively compile time for D. By simply extending the grammar slightly in an intuitive way, we can get the explicit finite case, which is easy: foo(T in [A,B,C])() and possibly for your case foo(T in )() would work or foo(T in )() the `in` keyword makes sense here and is not used nor ambiguous, I believe. While I agree that `in` does make sense for the semantics involved, it is already used to do a failable key lookup (return pointer to value or null if not present) into an associative array [1] and input contracts. It wouldn't be ambiguous AFAICT, but having a keyword mean three different things depending on context would make the language even more complex (to read). W.r.t. to the idea in general: I think something like that could be valuable to have in the language, but since this essentially amounts to syntactic sugar (AFAICT), but I'm not (yet) convinced that with `static foreach` being included it's worth the cost. [1] https://dlang.org/spec/expression.html#InExpression
Re: Help required on Array appender
On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: [...] Hi, [...] Hi, Was able to resolve the above issue, but again getting the same for other lines such as below when i tried to add the appender. auto CleanDirlst = appender([]); CleanDirlst ~= PVStore[1][i].to!string.split(","); Error: cannot implicitly convert expression appender([]) of type Appender!(void[]) to string[].
Re: templated type reduction
I should point out that I know it isn't safe in some cases(I already mentioned about the order mattering in some cases) but in that case a compiler error could be thrown. It's safe in some cases and I have the ability to create a safe case since I'm the designer of the code(e.g., put things in correct order).
templated type reduction
Suppose one had the need to template a something like struct X(T) { string type = T.stringof; T t; } But one needs to get the type to know how to interpret X!T but one only has a void* to a type X!T. That is, we know it is an "X" but we don't know the specific T. Now, this is easy as X!void or X!int or adding any specific but arbitrary type T, if the value we want is not dependent T... but in this case it is: void* x = new X!int; (passed around the program) switch(x.type) { case "int" : break; } which is invalid yet perfectly valid! Is there any way to make this work legitly in D? I could get the offset of the string then parse it, but that's a hack I'd rather not use and isn't really safe(change the order and it will break). note that it is really no different from struct X(T) { string type = "asdf"; T t; } in which we can do string type = (cast(X!int)x).type; // = asdf or string type = (cast(X!float)x).type; // = asdf but even this is a bit fishy. Heres some code that does the offset hack: struct X(T) { string type = T.stringof; T x; } int main(string[] args) { void* x = new X!int; int o = (X!float).type.offsetof; auto y = *cast(string*)(x + o); writeln(y); return 0; }
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 20:10:58 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 18:59:30 UTC, Vino.B wrote: [...] Cannot reproduce under Linux with dmd 2.076.0 (with commented out Windows-only check). I'll try to see what happens on Windows once I have a VM setup. [...] You changed the type of dFiles, which you return from cleanFiles, without changing the return type of cleanFiles. Change the return type of cleanFiles to the type the compiler error above tells you it should be (`Tuple!(string, string)[]` instead of `string[][]`), or let the compiler infer it via auto (`auto cleanFiles(...`). Hi, Thank you very much, was able to resolve the second code issue by changing the return type of the function.
Re: nested module problem
On Saturday, 2 September 2017 at 20:03:48 UTC, Jean-Louis Leroy wrote: So I have: jll@ORAC:~/dev/d/tests/modules$ tree . ├── foo │ └── bar.d └── foo.d foo.d contains: import foo.bar; bar.d is empty. This means bar.d's module name will be inferred by the compiler [1], which will ignore the path you put it under, yielding the module name "bar", not "foo.bar" (one of the issues of doing otherwise would be how the compiler should know at which path depth the inference should start - and any solution to that other than simply ignoring the path would be full of special cases): Modules have a one-to-one correspondence with source files. The module name is, by default, the file name with the path and extension stripped off, and can be set explicitly with the module declaration. Now I try compiling: jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d This looks like a compiler bug to me (accepts invalid), though I'm not certain. jll@ORAC:~/dev/d/tests/modules$ dmd -c foo/bar.d (No issue here, just an empty module being compiled separately) So far so good. Now I try it the way dub does it: jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d foo/bar.d foo.d(1): Error: module bar from file foo/bar.d must be imported with 'import bar;' What's up? This doesn't work, because of the inferred module name for foo/bar.d being "bar". So the compiler wants you to import it by the name it has inferred for you (The fix being either specifying the module name in foo/bar.d as `module foo.bar`, or importing it as via `import bar;` in foo.d). [1] https://dlang.org/spec/module.html
Re: Bug in D!!!
On Saturday, 2 September 2017 at 16:20:10 UTC, Jesse Phillips wrote: On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: Regardless of the implementation, the idea that we should throw the baby out with the bathwater is simply wrong. At least there are a few who get that. By looking in to it in a serious manner an event better solution might be found. Not looking at all results in no solutions and no progress. Problem is that you didn't define the problem. You showed some code the compiler rejected and expressed that the compiler needed to figure it out. You did change it to having the compiler instantiate specified types, but that isn't defining the problem. I think the problem is clearly defined, it's not my job to be a D compiler researcher and spell everything out for everyone else. Do I get paid for solving D's problems? You didn't like the code needed which would generate the functions and you hit a Visual D with the new static foreach. This sentence makes no sense. "hit a Visual D" what? Do you mean bug? If that is the case, how is that my fault? Amd I suppose to know off the bat that an access violation is caused by Visual D and not dmd when there is no info about the violation? Is it my fault that someone didn't code one of those tools good enough to express enough information for one to figure it out immediately? All of these are problems you could define, and you could have evaluated static foreach as a solution but instead stopped at problems with the tooling. Huh? I think you fail to understand the real problem. The problem has nothing to do with tooling and I never said it did. The static foreach "solution" came after the fact when SEVERAL people(ok, 2) said it was an impossible task to do. That is where all this mess started. I then came up with a solution which proved that it is possible to do on some level, that is a solution to a problem that was defined, else the solution wouldn't exist. You also don't appear to care about the complexity of the language. I expressed three required changes some of which may not play nicely with least surprise. You went straight to, we just need to define a syntax for that instead of expressing concern that the compiler will also need to handle errors to the use, such that the user understands that a feature they use is limited to very specific situations. Do you not understand that if a library solution exists then there is no real complexity added? It is called "lowering" by some. The compiler simply "rewrites" whatever new syntax is added in a form that the library solution realized. You are pretended, why?, that what I am proposed will somehow potentially affect every square micron of the D language and compiler, when it won't. Not all additions to a compiler are add *real* complexity. That is a failing of you and many on the D forums who resist change. Consider if you have a module defined interface, is that interface only available for use in that module? If not, how does a different model inherent the interface, does it need a different syntax. What does that have to do with this problem? We are not talking about interfaces. We are talking about something inside interfaces, so the problem about interfaces is irrelevant to this discussion because it applies to interfaces in general... interfaces that already exist and the problem exists regardless of what I There is a lot more to a feature then having a way to express your desires. If your going to stick to a stance that it must exist and aren't going to accept there are problems with the request why expect others to work through the request. No, your problem is your ego and your inability to interpret things outside of your own mental box. You should always keep in mind that you are interpreting someone elses mental wordage in your own way and it is not a perfect translation, in fact, we are lucky if 50% is interpreted properly. Now, if I do not have a right to express my desires, then at least state that, but I do have a right not to express any more than that. As far as motivating other people, that is isn't my job. I could care less actually. D is a hobby for me and I do it because I like the power D has, but D is the most frustrating language I have ever used. It's the most(hyperbole) buggy, most incomplete(good docs system: regardless of what the biased want to claim, tool, etc), most uninformative(errors that just toss the whole kitchen sink at you), etc. But I do have hope... which is the only reason I use it. Maybe I'm just an idiot and should go with the crowed, it would at least save me some frustration. C#, since you are familiar with it, you should know there is a huge difference. If D was like C# as far as the organizational structure(I do not mean MS, I mean the docs, library, etc) you would surely agree that D would most likely be the #1 language on this planet? C# has
Re: string to character code hex string
On Saturday, 2 September 2017 at 20:02:37 UTC, bitwise wrote: On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner wrote: In UTF8: --- utfmangle.d --- void fun_ༀ() {} pragma(msg, fun_ༀ.mangleof); --- --- $ dmd -c utfmangle.d _D6mangle7fun_ༀFZv --- Only universal character names for identifiers are allowed, though, as per [1] [1] https://dlang.org/spec/lex.html#identifiers What I intend to do is this though: void fun(string s)() {} pragma(msg, fun!"ༀ".mangleof); which gives: _D7mainMod21__T3funVAyaa3_e0bc80Z3funFNaNbNiNfZv where "e0bc80" is the 3 bytes of "ༀ". Interesting, I wasn't aware of that (though after thinking about it, it does make sense, as identifiers can only have visible characters in them, while a string could have things such as control characters inside), thanks! That behaviour is defined here [1], btw (the line `CharWidth Number _ HexDigits`). [1] https://dlang.org/spec/abi.html#Value
Re: string to character code hex string
On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner wrote: [...] Code will eventually look something like the following. The point is to be able to retrieve the exported function at runtime only by knowing what the template arg would have been. export extern(C) const(Reflection) dummy(string fqn)(){ ... } int main(string[] argv) { enum ARG = "AA"; auto hex = toAsciiHex(ARG); // original writeln(dummy!ARG.mangleof); // reconstructed at runtime auto remangled = dummy!"".mangleof; remangled = remangled.replaceFirst( "_D7mainMod17", "_D7mainMod" ~ (17 + hex.length).to!string); remangled = remangled.replaceFirst( "VAyaa0_", "VAyaa" ~ ARG.length.to!string ~ "_" ~ hex); writeln(remangled); return 0; }
Re: Web servers in D
On Saturday, 2 September 2017 at 20:18:17 UTC, bauss wrote: On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote: [...] Here is another template engine that can be used along with vibe. I actually made it for the same reason you don't wanna use vibe. Because I didn't like the template language and I was more familiar with razor templates from ASP.NET https://github.com/bausshf/Diamond To add onto this you can use mysql-native with vibe.d. https://github.com/mysql-d/mysql-native
Re: Web servers in D
On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote: What libraries are people using to run webservers other than vibe.d? Don't get me wrong I like the async-io aspect of vibe.d but I don't like the weird template language and the fact that it caters to mongo crowd. I think for D to a have good web story it needs to appeal to serious backend developers, not hipsters who go after fads (mongodb is a fad, jade/haml is a fad). I probably need to combine several libraries, but the features I'm looking for are: - Spawn an HTTP server listening on a port, and routing requests to functions/delegates, without hiding the details of the http request/response objects (headers, cookies, etc). - Support for websockets - Runs delegates in fibers/coroutines - Basic database connectivity (No "orm" needed; just raw sql). - When iterating the result set of a sql query, has the ability to automatically map each row against a struct, and throw if the structure does not match. - More generally, map any arbitrary object (such as json) to a struct. Something like Zewo/Reflection package for swift[0]. [0]: https://github.com/Zewo/Reflection I feel like Vibe.d satisfies my first 3 requirements, but for the rest I will probably have to look for something else. Here is another template engine that can be used along with vibe. I actually made it for the same reason you don't wanna use vibe. Because I didn't like the template language and I was more familiar with razor templates from ASP.NET https://github.com/bausshf/Diamond
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 18:59:30 UTC, Vino.B wrote: On Saturday, 2 September 2017 at 18:32:55 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote: On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote: [...] Line 25 happens because of `[a.name]`. You request a new array: the memory for this has to be allocated (the reason why the compiler says "may" is because sometimes, e.g. if the array literal itself contains only literals, the allocations needn't happen at runtime and no GC call is necessary). Since you don't actually use the array, get rid of it: [...] Hi, Thank you for your help and the DMD version that i am using is DMD 2.076.0 and yes I am on windows. Please post a compilable, minimal example including how that function gets called that yields you that compiler output. Hi, Please find the example code below, [...] Cannot reproduce under Linux with dmd 2.076.0 (with commented out Windows-only check). I'll try to see what happens on Windows once I have a VM setup. Another similar issue : I removed the [a.name] and the issue in line 25 has resolved, but for another function i am getting the same error string[][] cleanFiles(string FFs, string Step) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 20]]).array; -> Issue in this line if (Step == "run") dFiles.each!(a => a[0].remove); return dFiles; } if the replace the line in error as below then i am getting the error "Error: cannot implicitly convert expression dFiles of type Tuple!(string, string)[] to string[][]" auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])).array; You changed the type of dFiles, which you return from cleanFiles, without changing the return type of cleanFiles. Change the return type of cleanFiles to the type the compiler error above tells you it should be (`Tuple!(string, string)[]` instead of `string[][]`), or let the compiler infer it via auto (`auto cleanFiles(...`).
nested module problem
So I have: jll@ORAC:~/dev/d/tests/modules$ tree . ├── foo │ └── bar.d └── foo.d foo.d contains: import foo.bar; bar.d is empty. Now I try compiling: jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d jll@ORAC:~/dev/d/tests/modules$ dmd -c foo/bar.d So far so good. Now I try it the way dub does it: jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d foo/bar.d foo.d(1): Error: module bar from file foo/bar.d must be imported with 'import bar;' What's up?
Re: string to character code hex string
On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner wrote: In UTF8: --- utfmangle.d --- void fun_ༀ() {} pragma(msg, fun_ༀ.mangleof); --- --- $ dmd -c utfmangle.d _D6mangle7fun_ༀFZv --- Only universal character names for identifiers are allowed, though, as per [1] [1] https://dlang.org/spec/lex.html#identifiers What I intend to do is this though: void fun(string s)() {} pragma(msg, fun!"ༀ".mangleof); which gives: _D7mainMod21__T3funVAyaa3_e0bc80Z3funFNaNbNiNfZv where "e0bc80" is the 3 bytes of "ༀ". The function will be internal to my library. The only thing provided from outside will be the string template argument, which is meant to represent a fully qualified type name.
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 18:32:55 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote: On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote: [...] Line 25 happens because of `[a.name]`. You request a new array: the memory for this has to be allocated (the reason why the compiler says "may" is because sometimes, e.g. if the array literal itself contains only literals, the allocations needn't happen at runtime and no GC call is necessary). Since you don't actually use the array, get rid of it: [...] Hi, Thank you for your help and the DMD version that i am using is DMD 2.076.0 and yes I am on windows. Please post a compilable, minimal example including how that function gets called that yields you that compiler output. Hi, Please find the example code below, import std.stdio: File,writeln; import std.datetime.systime: Clock, days, SysTime; import std.file: SpanMode, dirEntries, exists, isFile, mkdir, remove; import std.typecons: tuple; import std.algorithm: filter, map, each; import std.array: array; void logClean (string[] Lglst, int LogAge) { if (!Lglst[0].exists) { mkdir(Lglst[0]); } auto ct1 = Clock.currTime(); auto st1 = ct1 + days(-LogAge); auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a => a.exists && a.isFile && a.timeCreated < st1).map!(a => tuple(a.name)).array; dFiles.each!(a => a[0].remove); } void main () { string[] LogDir = ["C:\\Users\\bheev1\\Desktop\\Current\\Script\\D\\Logs"]; int LogAge = 1; logClean(LogDir,LogAge); } Another similar issue : I removed the [a.name] and the issue in line 25 has resolved, but for another function i am getting the same error string[][] cleanFiles(string FFs, string Step) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 20]]).array; -> Issue in this line if (Step == "run") dFiles.each!(a => a[0].remove); return dFiles; } if the replace the line in error as below then i am getting the error "Error: cannot implicitly convert expression dFiles of type Tuple!(string, string)[] to string[][]" auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])).array;
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote: On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote: [...] Line 25 happens because of `[a.name]`. You request a new array: the memory for this has to be allocated (the reason why the compiler says "may" is because sometimes, e.g. if the array literal itself contains only literals, the allocations needn't happen at runtime and no GC call is necessary). Since you don't actually use the array, get rid of it: [...] Hi, Thank you for your help and the DMD version that i am using is DMD 2.076.0 and yes I am on windows. Please post a compilable, minimal example including how that function gets called that yields you that compiler output.
Re: string to character code hex string
On Saturday, 2 September 2017 at 18:07:51 UTC, bitwise wrote: On Saturday, 2 September 2017 at 17:45:30 UTC, Moritz Maxeiner wrote: If this (unnecessary waste) is of concern to you (and from the fact that you used ret.reserve I assume it is), then the easy fix is to use `sformat` instead of `format`: Yes, thanks. I'm going to go with a variation of your approach: private string toAsciiHex(string str) { import std.ascii : lowerHexDigits; import std.exception: assumeUnique; auto ret = new char[str.length * 2]; int i = 0; foreach(c; str) { ret[i++] = lowerHexDigits[(c >> 4) & 0xF]; ret[i++] = lowerHexDigits[c & 0xF]; } return ret.assumeUnique; } If you never need the individual character function, that's probably the best in terms of readability, though with a decent compiler, that and the two functions one should result in the same opcode (except for bitshift&bitmask swap). I'm not sure how the compiler would mangle UTF8, but I intend to use this on one specific function (actually the 100's of instantiations of it). In UTF8: --- utfmangle.d --- void fun_ༀ() {} pragma(msg, fun_ༀ.mangleof); --- --- $ dmd -c utfmangle.d _D6mangle7fun_ༀFZv --- Only universal character names for identifiers are allowed, though, as per [1] [1] https://dlang.org/spec/lex.html#identifiers
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner wrote: On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote: [...] Line 25 happens because of `[a.name]`. You request a new array: the memory for this has to be allocated (the reason why the compiler says "may" is because sometimes, e.g. if the array literal itself contains only literals, the allocations needn't happen at runtime and no GC call is necessary). Since you don't actually use the array, get rid of it: [...] Hi, Thank you for your help and the DMD version that i am using is DMD 2.076.0 and yes I am on windows. From, Vino.B
Re: string to character code hex string
On Saturday, 2 September 2017 at 17:45:30 UTC, Moritz Maxeiner wrote: If this (unnecessary waste) is of concern to you (and from the fact that you used ret.reserve I assume it is), then the easy fix is to use `sformat` instead of `format`: Yes, thanks. I'm going to go with a variation of your approach: private string toAsciiHex(string str) { import std.ascii : lowerHexDigits; import std.exception: assumeUnique; auto ret = new char[str.length * 2]; int i = 0; foreach(c; str) { ret[i++] = lowerHexDigits[(c >> 4) & 0xF]; ret[i++] = lowerHexDigits[c & 0xF]; } return ret.assumeUnique; } I'm not sure how the compiler would mangle UTF8, but I intend to use this on one specific function (actually the 100's of instantiations of it). It will predictably named though. Thanks!
Re: string to character code hex string
On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote: You're right but I think there is no intention of interpreting the result as UTF-8. "f62026" is just to be used as "f62026", which can be converted byte-by-byte back to "ö…". That's how understand the requirement anyway. Ali That is not possible, because you cannot know whether "f620" and "26" or "f6" and "2026" (or any other combination) should form a code point each. Additional padding to constant width (8 hex chars) is needed.
Re: Using closure causes GC allocation
On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote: Hi All, Request your help on how to solve the issue in the below code as when i execute the program with -vgc it state as below: NewTD.d(21): vgc: using closure causes GC allocation NewTD.d(25): vgc: array literal may cause GC allocation void logClean (string[] Lglst, int LogAge) { //Line 21 if (!Lglst[0].exists) { mkdir(Lglst[0]); } auto ct1 = Clock.currTime(); auto st1 = ct1 + days(-LogAge); auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a => a.exists && a.isFile && a.timeCreated < st1).map!(a =>[a.name]).array; // Line 25 dFiles.each!(f => f[0].remove); } Line 25 happens because of `[a.name]`. You request a new array: the memory for this has to be allocated (the reason why the compiler says "may" is because sometimes, e.g. if the array literal itself contains only literals, the allocations needn't happen at runtime and no GC call is necessary). Since you don't actually use the array, get rid of it: --- void logClean (string[] Lglst, int LogAge) { //Line 21 if (!Lglst[0].exists) { mkdir(Lglst[0]); } auto ct1 = Clock.currTime(); auto st1 = ct1 + days(-LogAge); auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a => a.exists && a.isFile && a.timeCreated < st1).array; // Line 25 dFiles.each!(f => f.remove); } --- I cannot reproduce the line 21 report, though. Since you use `timeCreated` I assume you're on Windows, but what's your D compiler, which D frontend version are you using, etc. (all the things needed to attempt to reproduce the error).
Re: string to character code hex string
On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote: You're right but I think there is no intention of interpreting the result as UTF-8. "f62026" is just to be used as "f62026", which can be converted byte-by-byte back to "ö…". That's how understand the requirement anyway. Ali My intention is compute the mangling of a D template function that takes a string as a template parameter without having the symbol available. I think that means that converting each byte of the string to hex and tacking it on would suffice.
Re: string to character code hex string
On Saturday, 2 September 2017 at 16:23:57 UTC, bitwise wrote: On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote: [...] This seems to work well enough. string toAsciiHex(string str) { import std.array : appender; auto ret = appender!string(null); ret.reserve(str.length * 2); foreach(c; str) ret.put(format!"%x"(c)); return ret.data; } Note: Each of those format calls is going to allocate a new string, followed by put copying that new string's content over into the appender, leaving you with \theta(str.length) tiny memory chunks that aren't used anymore for the GC to eventually collect. If this (unnecessary waste) is of concern to you (and from the fact that you used ret.reserve I assume it is), then the easy fix is to use `sformat` instead of `format`: --- string toHex(string str) { import std.format : sformat; import std.exception: assumeUnique; auto ret = new char[str.length * 2]; size_t len; foreach (c; str) { auto slice = sformat!"%x"(ret[len..$], c); //auto slice = toHex(ret[len..$], c); assert (slice.length <= 2); len += slice.length; } return ret[0..len].assumeUnique; } --- If you want to cut out the format import entirely, notice the `auto slice = toHex...` line, which can be implemented like this (always returns two chars): --- char[] toHex(char[] buf, char c) { import std.ascii : lowerHexDigits; assert (buf.length >= 2); buf[0] = lowerHexDigits[(c & 0xF0) >> 4]; buf[1] = lowerHexDigits[c & 0x0F]; return buf[0..2]; } ---
Using closure causes GC allocation
Hi All, Request your help on how to solve the issue in the below code as when i execute the program with -vgc it state as below: NewTD.d(21): vgc: using closure causes GC allocation NewTD.d(25): vgc: array literal may cause GC allocation void logClean (string[] Lglst, int LogAge) { //Line 21 if (!Lglst[0].exists) { mkdir(Lglst[0]); } auto ct1 = Clock.currTime(); auto st1 = ct1 + days(-LogAge); auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a => a.exists && a.isFile && a.timeCreated < st1).map!(a =>[a.name]).array; // Line 25 dFiles.each!(f => f[0].remove); } From, Vino.B
Re: string to character code hex string
On 09/02/2017 10:07 AM, lithium iodate wrote: >> Lazy version, which the user can easily generate a string from by >> appending .array: >> >> import std.stdio; >> >> auto hexString(R)(R input) { >> import std.conv : text; >> import std.string : format; >> import std.algorithm : map, joiner; >> return input.map!(c => format("%02x", c)).joiner; >> } >> >> void main() { >> writeln("AAA".hexString); >> } >> >> To generate string: >> >> import std.range : array; >> writeln("AAA".hexString.array); >> >> Ali > > Please correct my if i'm wrong, but it think this has issues regarding > unicode. > "ö…" becomes "f62026", which, interpreted as UTF-8, is a control > character ~ " &", so you either need to add padding or use ..byCodeUnit > so it becomes "c3b6e280a6" (correct UTF-8) instead. You're right but I think there is no intention of interpreting the result as UTF-8. "f62026" is just to be used as "f62026", which can be converted byte-by-byte back to "ö…". That's how understand the requirement anyway. Ali
Re: string to character code hex string
On Saturday, 2 September 2017 at 16:52:17 UTC, Ali Çehreli wrote: On 09/02/2017 09:23 AM, bitwise wrote: On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote: [...] This seems to work well enough. string toAsciiHex(string str) { import std.array : appender; auto ret = appender!string(null); ret.reserve(str.length * 2); foreach(c; str) ret.put(format!"%x"(c)); return ret.data; } Lazy version, which the user can easily generate a string from by appending .array: import std.stdio; auto hexString(R)(R input) { import std.conv : text; import std.string : format; import std.algorithm : map, joiner; return input.map!(c => format("%02x", c)).joiner; } void main() { writeln("AAA".hexString); } To generate string: import std.range : array; writeln("AAA".hexString.array); Ali Please correct my if i'm wrong, but it think this has issues regarding unicode. "ö…" becomes "f62026", which, interpreted as UTF-8, is a control character ~ " &", so you either need to add padding or use .byCodeUnit so it becomes "c3b6e280a6" (correct UTF-8) instead.
Re: string to character code hex string
On 09/02/2017 09:23 AM, bitwise wrote: On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote: [...] This seems to work well enough. string toAsciiHex(string str) { import std.array : appender; auto ret = appender!string(null); ret.reserve(str.length * 2); foreach(c; str) ret.put(format!"%x"(c)); return ret.data; } Lazy version, which the user can easily generate a string from by appending .array: import std.stdio; auto hexString(R)(R input) { import std.conv : text; import std.string : format; import std.algorithm : map, joiner; return input.map!(c => format("%02x", c)).joiner; } void main() { writeln("AAA".hexString); } To generate string: import std.range : array; writeln("AAA".hexString.array); Ali
Re: string to character code hex string
On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote: [...] This seems to work well enough. string toAsciiHex(string str) { import std.array : appender; auto ret = appender!string(null); ret.reserve(str.length * 2); foreach(c; str) ret.put(format!"%x"(c)); return ret.data; }
Re: Bug in D!!!
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta wrote: Regardless of the implementation, the idea that we should throw the baby out with the bathwater is simply wrong. At least there are a few who get that. By looking in to it in a serious manner an event better solution might be found. Not looking at all results in no solutions and no progress. Problem is that you didn't define the problem. You showed some code the compiler rejected and expressed that the compiler needed to figure it out. You did change it to having the compiler instantiate specified types, but that isn't defining the problem. You didn't like the code needed which would generate the functions and you hit a Visual D with the new static foreach. All of these are problems you could define, and you could have evaluated static foreach as a solution but instead stopped at problems with the tooling. You also don't appear to care about the complexity of the language. I expressed three required changes some of which may not play nicely with least surprise. You went straight to, we just need to define a syntax for that instead of expressing concern that the compiler will also need to handle errors to the use, such that the user understands that a feature they use is limited to very specific situations. Consider if you have a module defined interface, is that interface only available for use in that module? If not, how does a different model inherent the interface, does it need a different syntax. There is a lot more to a feature then having a way to express your desires. If your going to stick to a stance that it must exist and aren't going to accept there are problems with the request why expect others to work through the request.
string to character code hex string
I need to convert a string of characters to a string of their hex representations. "AAA" -> "414141" This seems like something that would be in the std lib, but I can't find it. Does it exist? Thanks
Re: Help required on Array appender
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: On Saturday, 2 September 2017 at 10:15:04 UTC, Vino.B wrote: Hi All, Can you please guide me how can i use array appender for the below piece of code string[][] cleanFiles (string FFs, string Step) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { if (Step == "dryrun") { Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } else if (Step == "run") { remove(d[0]); if (!d[0].exists) Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } } return Subdata; } From, Vino.B If you're wanting to use appender just make an appender and replace the ~= to calls to appender.put(data); if you're trying to make it faster, consider that Step could be a bool, your return type could be string[2][], the `if (!d[0].exists)` is redundant since `remove` will throw if it fails. That leaves you with string[2][] cleanFiles(string FFs, bool dryrun) { auto dFiles = dirEntries(FFs, SpanMode.shallow) .filter!(a => a.isFile) .map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 20]) .array; if (! dryrun) dFiles.each!(f => f[0].remove); } Hi, Thank you very much, and your idea help a lot, and the reason to use appender is for both faster and performance as my program use's many ~= function and found that using appender is the best way when compared with the ~= e.g;(MCresult.get ~= MCleanTaskData;) void mCleanFiles (string[] Dirlist, File logF, File logE, string Step) { try { string[][] MCtext; string[][] MCEresult; auto MCresult = taskPool.workerLocalStorage(MCtext); logF.writeln("Function \t : List of the File's which are not placed in correct Location and list those deleted"); logF.writeln("Dir. Scanned \t :", Dirlist); logF.writeln(""); logF.writefln("%-63s %.20s", "File Name", "CreationTime"); logF.writeln(""); foreach (string Fs; parallel(Dirlist[0 .. $], 1)) { auto FFs = Fs.strip; auto MCleanTask = task(&cleanFiles, FFs, Step); MCleanTask.executeInNewThread(); auto MCleanTaskData = MCleanTask.workForce; MCresult.get ~= MCleanTaskData; } foreach(i; MCresult.toRange) logF.writefln("%(%-(%-63s %)\n%)", i.sort!((a,b) => a[0] < b[0]).uniq); logF.writeln(""); } catch (Exception e) { logE.writeln(e.msg); } } From, Vino.B
Re: -betterC not working
On Friday, 1 September 2017 at 22:13:53 UTC, SrMordred wrote: On Wednesday, 30 August 2017 at 23:12:07 UTC, SrMordred wrote: On Wednesday, 30 August 2017 at 22:45:27 UTC, Adam D. Ruppe wrote: On Wednesday, 30 August 2017 at 22:18:07 UTC, SrMordred wrote: DMD64 D Compiler v2.075.1 -betterC as described recently is not yet released. https://dlang.org/changelog/2.076.0_pre.html is where it gets the new behavior, and that isn't scheduled for formal release until the end of the week. (it seriously bothers me that Walter has been advertising this so much when the little bit that is implemented isn't even released yet, and what is implemented is barely usable.) The betterC switch itself is not new, but it does virtually nothing until that latest prerelease compiler. ooops, little missed detail ;) At least its near. Hello again. Downloaded last version. //fail at my example, so its working as intended dmd -betterC source/app.d app.d //compiles. so problem with dub only dub run --config=application --arch=x86_64 --build=debug --compiler=dmd Running dub run with --verbose indicates that dub is actually running both the "dmd -g -c -betterC source/app.d -ofd_betterc.o" and the "dmd -ofd_betterc d_betterc.o -g" commands. Note that the second dmd call doesn't include the -betterC flag. Running the second dmd command manually with the -betterC flag does give the expected undefined reference errors.
Re: Help required on Array appender
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson wrote: If you're wanting to use appender just make an appender and replace the ~= to calls to appender.put(data); Just making Subdata an Appender!(string[][]) (or Appender!(Tuple!(string, string)[])) is enough since it already overloads the ~= operator. Performance aside, a small nitpick is that it's possible to write filter!isFile instead of filter!(a => a.isFile) since isFile only accepts one argument.
Re: Help required on Array appender
On Saturday, 2 September 2017 at 10:15:04 UTC, Vino.B wrote: Hi All, Can you please guide me how can i use array appender for the below piece of code string[][] cleanFiles (string FFs, string Step) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { if (Step == "dryrun") { Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } else if (Step == "run") { remove(d[0]); if (!d[0].exists) Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } } return Subdata; } From, Vino.B If you're wanting to use appender just make an appender and replace the ~= to calls to appender.put(data); if you're trying to make it faster, consider that Step could be a bool, your return type could be string[2][], the `if (!d[0].exists)` is redundant since `remove` will throw if it fails. That leaves you with string[2][] cleanFiles(string FFs, bool dryrun) { auto dFiles = dirEntries(FFs, SpanMode.shallow) .filter!(a => a.isFile) .map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 20]) .array; if (! dryrun) dFiles.each!(f => f[0].remove); }
Re: Web servers in D
On Saturday, 2 September 2017 at 09:26:27 UTC, Andrew Chapman wrote: On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote: [...] [...] Don't use these components :-) [...] Vibe.d does this - just don't use the automatic API generation feature if you don't like it. Note, you can get access to the request/response objects even if you do use the API generation by using an @before method. E.g. in an interface you may have something like this: There is built-in support for authentication in vibe.d: https://github.com/rejectedsoftware/vibe.d/tree/master/examples/web-auth
Problems with std.experimental.allocator
I realize these are not yet stable but I would like to know if I am doing something wrong or is it a lib bug. My first attempt was to do this: theAllocator = allocatorObject(Region!MmapAllocator(1024*MB)); If I got it right this doesn't work because it actually does this: 1. Create Region struct and allocate 1024MB from MMapAllocator 2. Wrap the struct in IAllocator by copying it because it has state 3. Destroy original struct which frees the memory 4. Now the struct copy points to released memory Am I right here? Next attempt was this: theAllocator = allocatorObject(Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB))); Since I give actual memory instead of the allocator to the Region it can not dealocate that memory so even the copy will still point to valid memory. After looking at what will the allocatorObject do in this case my conclusion is that it will take a "copyable" static if branch and create an instance of CAllocatorImpl which will have a "Region!() impl" field within itself but given Region!() struct is never copied into that field. Am I right here? If I am right about both are then these considered as lib bugs? I finally got it working with: auto newAlloc = Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)); theAllocator = allocatorObject(&newAlloc); Next I tried setting processAllocator instead of theAllocator by using: auto newAlloc = Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)); processAllocator = sharedAllocatorObject(&newAlloc); but that complained how it "cannot implicitly convert expression `pa` of type `Region!()*` to `shared(Region!()*)`" and since Region doesn't define its methods as shared does this mean one can not use Region as processAllocator? If that is so, what is the reason behind it?
Help required on Array appender
Hi All, Can you please guide me how can i use array appender for the below piece of code string[][] cleanFiles (string FFs, string Step) { auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { if (Step == "dryrun") { Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } else if (Step == "run") { remove(d[0]); if (!d[0].exists) Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } } return Subdata; } From, Vino.B
Re: 24-bit int
On Saturday, 2 September 2017 at 00:43:00 UTC, Nicholas Wilson wrote: On Friday, 1 September 2017 at 22:10:43 UTC, Biotronic wrote: struct int24 { ubyte[3] _payload; this(int x) { value = x; } ... } You may also want to put an align(1) on it so that you dont waste 25% of the allocated memory in an array of int24's The very first test in my code checks this: int24[3] a; assert(a.sizeof == 9); On the other hand, using Mir's well-tested code instead of something I hacked together in 10 minutes is probably a good idea. -- Biotronic
Re: Web servers in D
On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote: What libraries are people using to run webservers other than vibe.d? Don't get me wrong I like the async-io aspect of vibe.d but I don't like the weird template language and the fact that it caters to mongo crowd. I think for D to a have good web story it needs to appeal to serious backend developers, not hipsters who go after fads (mongodb is a fad, jade/haml is a fad). I probably need to combine several libraries, but the features I'm looking for are: - Spawn an HTTP server listening on a port, and routing requests to functions/delegates, without hiding the details of the http request/response objects (headers, cookies, etc). - Support for websockets - Runs delegates in fibers/coroutines - Basic database connectivity (No "orm" needed; just raw sql). - When iterating the result set of a sql query, has the ability to automatically map each row against a struct, and throw if the structure does not match. - More generally, map any arbitrary object (such as json) to a struct. Something like Zewo/Reflection package for swift[0]. [0]: https://github.com/Zewo/Reflection I feel like Vibe.d satisfies my first 3 requirements, but for the rest I will probably have to look for something else. Don't get me wrong I like the async-io aspect of vibe.d but I don't like the weird template language and the fact that it caters to mongo crowd. Don't use these components :-) - Spawn an HTTP server listening on a port, and routing requests to functions/delegates, without hiding the details of the http request/response objects (headers, cookies, etc). Vibe.d does this - just don't use the automatic API generation feature if you don't like it. Note, you can get access to the request/response objects even if you do use the API generation by using an @before method. E.g. in an interface you may have something like this: @method(HTTPMethod.POST) @before!getRequestInfo("requestInfo") @property Token login(LoginRequestMeta login, RequestInfo requestInfo); And then define your getRequestInfo method like this: static RequestInfo getRequestInfo(HTTPServerRequest req, HTTPServerResponse res) { RequestInfo requestInfo; requestInfo.headers = req.headers; requestInfo.ipAddress = req.clientAddress.toAddressString(); requestInfo.userAgent = requestInfo.headers.get("User-Agent", ""); return requestInfo; } In this case I've grabbed the ip address and user agent of the user, but you could also grab cookies etc. - When iterating the result set of a sql query, has the ability to automatically map each row against a struct, and throw if the structure does not match. You can do this with MySQL Native whilst using vibe.d. You might do something like this: Prepared prepared = prepare(this.conn, sql); prepared.setArgs(params); auto row = prepared.queryRow(); if (row.isNull()) { throw new Exception("Query returned an empty row"); } T item; try { row.toStruct!T(item); } catch(Exception e) { } Where T is your struct type that you're trying to convert the row to. As for the template language, you could try: http://code.dlang.org/packages/diamond https://github.com/repeatedly/mustache-d There are probably others.
Re: 24-bit int
On Saturday, 2 September 2017 at 07:20:07 UTC, kinke wrote: struct int24 { ubyte[3] _payload; } static assert(int24.sizeof == 3); static assert(int24.alignof == 1); Making absolute sense. ubytes don't need any specific alignment to be read efficiently. Yes, that does make sense. It doesn't make sense that I didn't realize it.
Re: 24-bit int
On Saturday, 2 September 2017 at 02:37:08 UTC, Mike Parker wrote: It's not a bug, but a feature. Data structure alignment is important for efficient reads, so several languages (D, C, C++, Ada, and more) will automatically pad structs so that they can maintain specific byte alignments. On a 32-bit system, 4-byte boundaries are the default. So a struct with 3 ubytes is going to be padded with an extra byte at the end. Telling the compiler to align on a 1-byte boundary (essentially disabling alignment) will save you space, but will will generally cost you cycles in accessing the data. struct int24 { ubyte[3] _payload; } static assert(int24.sizeof == 3); static assert(int24.alignof == 1); Making absolute sense. ubytes don't need any specific alignment to be read efficiently.