Re: Call to Runtime.unloadLibrary corrupts stdout and stderr
On 02/09/2017 10:38 PM, Markus Pursche wrote: Hi, I'm trying to hot reload a DLL while the program is running to allow for rapid iteration in a game engine I am working on. I started reading up on how DLLs work between D code here: https://wiki.dlang.org/Win32_DLLs_in_D#D_code_calling_D_code_in_DLLs I followed that example, however when I try to do the following I crash: 1. Load DLL 2. Unload DLL 3. Load DLL again The problem I am getting is a Bad File Descriptor exception right after step 2, on my very next writeln to be exact. Here is the exception I am getting: http://imgur.com/a/b9XBm I spent a couple of hours trying to debug it, googling all sorts of combinations of "dlang unloadlibrary bad file descriptor", until I got the idea to try "dlang freelibrary bad file descriptor" and found this old bug report from 2004: http://forum.dlang.org/post/cg5hpf$kpv$1...@digitaldaemon.com This sounds absolutely spot on to the problems I am having. I tried to save stdout and reset it after unloading my library but I still crashed on the next writeln, does anyone have an idea for a workaround on this? I'm hoping that someone like Walter or Andrei will see this and decide that it's time for this 2004 issue to finally die. :P *sigh* 2018H1 plan I am listing shared library support. Even better still, I will argue it as the ONLY language/druntime feature we need in it! Seriously, this is the biggest thing holding back D atm.
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
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: C `restrict` keyword in D
On Sunday, 3 September 2017 at 03:04:58 UTC, Uknown wrote: [...] void foo(ref RCArray!int arr, ref int val) @safe { { auto copy = arr; //arr's (and copy's) reference counts are both 2 arr = RCArray!int([]); // There is another owner, so arr // forgets about the old payload } // Last owner of the array ('copy') gets destroyed and happily // frees the payload. val = 3; // Oops. } Here, adding `restrict` to foo's parameters like so : void foo(restrict ref RCArray!int arr, restrict ref int val) would make the compiler statically enforce the fact that neither references are pointing to the same data. This would cause an error in main, since arr[0] is from the same block of memory as arr. How does the compiler know which member of RCArray!int to check for pointing to the same memory chunk as val?
C `restrict` keyword in D
In C, the `restrict` keyword implies that 2 or more pointer arguments in a function call do not point to the same data. This allows for some additional optimizations which were not possible before, finally making C as fast as Fortran. e.g. This is the new definition for memcpy in C99 void* memcpy(void *restrict dst, const void *restrict src, size_t n); `dst` and `src` should never point to the same block of memory, and this is enforced by the programmer. In D, it makes sense to add a similar functionality, that extends beyond just performance optimizations. It could potentially be used to better guarantee @safety of some code. e.g. (from discussions about ref counting in D) : void main() @safe { auto arr = RCArray!int([0]); foo(arr, arr[0]); } void foo(ref RCArray!int arr, ref int val) @safe { { auto copy = arr; //arr's (and copy's) reference counts are both 2 arr = RCArray!int([]); // There is another owner, so arr // forgets about the old payload } // Last owner of the array ('copy') gets destroyed and happily // frees the payload. val = 3; // Oops. } Here, adding `restrict` to foo's parameters like so : void foo(restrict ref RCArray!int arr, restrict ref int val) would make the compiler statically enforce the fact that neither references are pointing to the same data. This would cause an error in main, since arr[0] is from the same block of memory as arr. The same would apply for pointers. I just hope to have a nice discussion on this topic here. Thanks! Read more about `restrict` here : http://en.cppreference.com/w/c/language/restrict
Re: C++ / Why Iterators Got It All Wrong
On Sunday, 3 September 2017 at 02:08:20 UTC, Ilya Yaroshenko wrote: On Tuesday, 29 August 2017 at 12:50:08 UTC, Robert M. Münch wrote: Maybe of interest: https://www.think-cell.com/en/career/talks/iterators/#1 I haven't read everything, so not sure if it worth to take a look. Iterators has no proper alternative when one need to implement generic tensor library like Mir Algorithm [1]. Out of curiosity: Could you elaborate on what the issues are with using a range based API internally (if it's performance, the "why")?
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
Re: C++ / Why Iterators Got It All Wrong
On Tuesday, 29 August 2017 at 12:50:08 UTC, Robert M. Münch wrote: Maybe of interest: https://www.think-cell.com/en/career/talks/iterators/#1 I haven't read everything, so not sure if it worth to take a look. Iterators has no proper alternative when one need to implement generic tensor library like Mir Algorithm [1]. User level API is ndslice [4] (D n-dimensional random access range) , can be combined with Phobos. In the same time library uses low level unbounded random access iterator [2] representation to implement 90% of topology logic. This approach allows to maintain few times smaller, simpler and less error-prone code comparing with std.range. The best example it `bitwise` functions implementation in Phobos and Mir Algorithm. Iterators are very good for type composition when one need its own D range that can not be constructed using existing mir.ndslice.topology / std.range API. [1] https://github.com/libmir/mir-algorithm [2] http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html [3] http://docs.algorithm.dlang.io/latest/mir_ndslice_iterator.html [4] http://docs.algorithm.dlang.io/latest/mir_ndslice_slice.html#Slice Best Regards, Ilya
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: Open Methods: From C++ to D
On Saturday, 2 September 2017 at 21:16:50 UTC, Jean-Louis Leroy wrote: On Saturday, 2 September 2017 at 20:55:13 UTC, EntangledQuanta wrote: This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used? Yes I meant that. The README.md says "Every module that declares methods or define implementations must include the following line". Ah yes the ddoc. I should update it. Also I think I should allow the mixin to silently do nothing in this case. Good catch. You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think. Alas it won't work. Method registration is done via static ctors and they have to run - all of them - before updateMethods can do its work. In simple, one-module programs updateMethods in a static ctor will work, but in general it won't. hmm, surely there is a mechanism which can be used? Possibly hooking in to druntime or some other hack? Not that it's a big deal but if you could get off the dependencies then it would be a sort of "compiler solution". Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D). Neither the methods nor their overrides enjoy special privileges. Unless the override (i.e. the thing preceded by @method) is a static member function? But I don't think so. Currently my code just scans the direct member of the module in which mixin(registerMethods) is called. Although I could change that, thus giving privileged access to some overrides. Could be useful for 1-methods. But anyway, probably there's something you don't notice...hmmm...can you share that code? In D, encapsulation is voided at the module level. So private members are public to the module. struct S { private int x; } void foo(S s) { writeln(s.x); } works. If foo is declared outside the module it will fail. It's like friend in C++ but automatic and per module. Pretty nice but that is about as far as it goes in D. My code was pretty simple. I couldn't share it all because it's too large, but I simply replaced a single member with an open method. It had a few lines of code. One was accessing a protected member, which I changed to private... all compiled. Then I remembered about D's encapsulation rules for the module. So that nullified my issues that I though openmethods might have. So, I think, in fact, this might be a pretty good solution to many problems. It allows extensibility without tying the methods to the classes directly. I'm still imagine encapsulation will be an issue for larger designs since the openmethods won't be defined in the same module, but I haven't used them enough to know what kinda faults will creep up yet. I haven't used openmethods enough to really see their power but hopefully with this solution I can ;) Thanks!
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
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
Call to Runtime.unloadLibrary corrupts stdout and stderr
Hi, I'm trying to hot reload a DLL while the program is running to allow for rapid iteration in a game engine I am working on. I started reading up on how DLLs work between D code here: https://wiki.dlang.org/Win32_DLLs_in_D#D_code_calling_D_code_in_DLLs I followed that example, however when I try to do the following I crash: 1. Load DLL 2. Unload DLL 3. Load DLL again The problem I am getting is a Bad File Descriptor exception right after step 2, on my very next writeln to be exact. Here is the exception I am getting: http://imgur.com/a/b9XBm I spent a couple of hours trying to debug it, googling all sorts of combinations of "dlang unloadlibrary bad file descriptor", until I got the idea to try "dlang freelibrary bad file descriptor" and found this old bug report from 2004: http://forum.dlang.org/post/cg5hpf$kpv$1...@digitaldaemon.com This sounds absolutely spot on to the problems I am having. I tried to save stdout and reset it after unloading my library but I still crashed on the next writeln, does anyone have an idea for a workaround on this? I'm hoping that someone like Walter or Andrei will see this and decide that it's time for this 2004 issue to finally die. :P
Re: C++ / Why Iterators Got It All Wrong
On Saturday, 2 September 2017 at 20:17:40 UTC, Robert M. Münch wrote: On 2017-08-31 07:13:55 +, drug said: Interesting. How is it comparable with iterators and ranges ideas? Well, see: http://www.rebol.com/docs/core23/rebolcore-6.html#section-6 Thanks for your post about Rebol, I didn't know it before. After reading through the series chaper, though, AFAICT Rebol series *are* iterators (begin+end), just with really nice, functional (read: LISP) syntax?
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: Open Methods: From C++ to D
On Saturday, 2 September 2017 at 20:55:13 UTC, EntangledQuanta wrote: This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used? Yes I meant that. The README.md says "Every module that declares methods or define implementations must include the following line". Ah yes the ddoc. I should update it. Also I think I should allow the mixin to silently do nothing in this case. Good catch. You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think. Alas it won't work. Method registration is done via static ctors and they have to run - all of them - before updateMethods can do its work. In simple, one-module programs updateMethods in a static ctor will work, but in general it won't. Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D). Neither the methods nor their overrides enjoy special privileges. Unless the override (i.e. the thing preceded by @method) is a static member function? But I don't think so. Currently my code just scans the direct member of the module in which mixin(registerMethods) is called. Although I could change that, thus giving privileged access to some overrides. Could be useful for 1-methods. But anyway, probably there's something you don't notice...hmmm...can you share that code? Thanks for the feedback.
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: Open Methods: From C++ to D
On Saturday, 2 September 2017 at 14:04:07 UTC, Jean-Louis Leroy wrote: On Thursday, 31 August 2017 at 23:37:03 UTC, EntangledQuanta wrote: [Windows] I'll try again at some point. I haven't got around to messing with it again. Did you get a chance? I'll try real quick again. I'll have to rewrite the code as I moved on but: When I just add the mixin and update(to main) I get the error openmethods.d(1432): Error: function `main` has no members main.d-mixin-15(15): Error: CTFE failed because of previous errors in _registerMethods This is when I have the mixin(registerMethods) in a module that doesn't use any open methods. It says add once per module in the help, but I think it means once per module where open methods are used? Removing that mixin from main allows it to compile(but I haven't created any methods yet). You might look in to adding updateMethods in a static this() since it will be ran per process and do everything necessary, I think. After a few stupid bugs by me, I was able to get it to work! Pretty much a drop in replacement! I didn't do anything fancy, very basic, but it did work. It's not a real test but does show it can, for the most part, replace traditional code. Strangely enough, I had a protected member that I was using and it works, I guess because I defined the openmethod in the same module. I changed it to private and it worked too. So the issues about encapsulation I thought about before may be irrelevant as long as the openmethods are used in the same module(which is a nice feature of D). So, everything looks good on my end. Once I get around to creating something new or rewriting some old stuff I'll try to use them more and see what happens.
Re: [OT] "Safe Systems Software and the Future of Computing" talk by Joe Duffy
On Saturday, 2 September 2017 at 20:03:17 UTC, Paulo Pinto wrote: Hi everyone, Videos of Rust Conf 2017 are now available, and Joe Duffy did the closing keynote telling his experience developing Midori. Specially relevant are the parts where he explains the internal resistance from classical C devs at Microsoft, adopting a more safe systems programming. https://www.youtube.com/watch?v=EVm938gMWl0 Some of his ideas also apply to improving D's adoption among system devs. -- Paulo Thanks for sharing this, looks quite interesting so far.
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: Editor recommendations for new users.
On 2017-08-30 11:28:35 +, Anonymouse said: ... considering that my vim knowledge so far largely consists of :wq and :q!. If you want to learn it fast up to a level that covers 90% of what you need www.shortcutfoo.com is your friend. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
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: C++ / Why Iterators Got It All Wrong
On 2017-09-01 20:34:32 +, Mark said: On Tuesday, 29 August 2017 at 12:50:08 UTC, Robert M. Münch wrote: Maybe of interest: https://www.think-cell.com/en/career/talks/iterators/#1 I haven't read everything, so not sure if it worth to take a look. Iterators have many problems. Andrei's talk some years ago, titled "Iterators Must Go", points out many of them in a clear fashion. I think most of the problems stem from the fact that they are inherently a leaky abstraction. Iterators basically treat all data structures as a singly/doubly linked list or as arrays (if they allow random access). There is no natural or intuitive way of describing, say, a tree or an arbitrary graph as a list/array. Ranges and cursors try to solve some of the issues but they still have this fundamental problem. Iterators are not the silver bullet. But IIRC you can specify if you want to iterate over a graph BF or DF. If you just need to "iterate" over the elements things work pretty good IMO. If you want to select a sub-set and then iterate things get much complicater anyway. It may be unrealisic to expect such a nice abstraction of iteration for other data structures, not to mention a universal one which will work for all interesting data structures. That's true, hence I didn't ever expected this at all. Some pretty simple & basic building blocks and the rest is done on-demand fitting the use-case. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
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: C++ / Why Iterators Got It All Wrong
On 2017-08-31 07:13:55 +, drug said: Interesting. How is it comparable with iterators and ranges ideas? Well, see: http://www.rebol.com/docs/core23/rebolcore-6.html#section-6 Just download the interpreter and play around with it to get a feeling. Overall it's way more functional. Like getting the last element: copy back tail my-series What I don't like is that indexing starts at 1, because this makes working with +/- offsets from a specific positon cumbersome. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
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(...`).
[OT] "Safe Systems Software and the Future of Computing" talk by Joe Duffy
Hi everyone, Videos of Rust Conf 2017 are now available, and Joe Duffy did the closing keynote telling his experience developing Midori. Specially relevant are the parts where he explains the internal resistance from classical C devs at Microsoft, adopting a more safe systems programming. https://www.youtube.com/watch?v=EVm938gMWl0 Some of his ideas also apply to improving D's adoption among system devs. -- Paulo
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 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: D easily overlooked?
On Saturday, 2 September 2017 at 15:41:54 UTC, Joakim wrote: On Saturday, 2 September 2017 at 14:49:30 UTC, thinwybk wrote: On Friday, 14 July 2017 at 13:29:30 UTC, Joakim wrote: Yes, D's compile-time regex are still the fastest in the world. I've been benching it recently for a marketing-oriented blog post I'm preparing for the official D blog, std.regex beats out the top C and Rust entries from the benchmarks game on linux/x64 with a single core: http://benchmarksgame.alioth.debian.org/u64q/regexredux.html https://github.com/joakim-noah/regex-bench D comes in third on Android/ARM, but not far behind, suggesting it would still be third on that list if run with a bunch of other languages on mobile. Dmitry thinks it might be alignment issues, the bane of cross-platform, high-performance code on ARM, as he hasn't optimized his regex code for ARM. Do you plan to implement a version for the fastest benchmark "n-body" (http://benchmarksgame.alioth.debian.org/u64q/nbody.html) as well? No, the goal is to demonstrate the nice, super-speedy regex engine in the D standard library by using that same benchmark that Dmitry exhibited years ago, to show D still does really well at regex. It's not to try and compete across all those benchmarks, which D used to dominate at one time. I did wonder how D does on that n-body benchmark now, so I built and ran the fastest C++ version, #8, on my single-core linux/x64 VPS. Here's the source link for each benchmark, the compiler version, and the command I used to build it: C++: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody=gpp=8 clang/llvm 4.0.1 clang -O3 -std=c++11 nbody.cpp -lm -onbody-cpp D: https://bitbucket.org/qznc/d-shootout/raw/898f7f3b3c5d55680229113e973ef95ece6f711a/progs/nbody/nbody.d ldc 1.4 beta1, llvm 4.0.1 ldc2 -O3 nbody.d The D version averages 2.5 seconds, the C++ version 6 seconds, which means D would likely still be at the top of that n-body ranking today. Sorry, I assumed the D version worked fine and didn't bother to check the output, turns out it needs two foreach loops changed in advance(dt). Specifically, "Body i" should be changed to "ref Body i" in both foreach statements, so the data is actually updated. ;) After that change, the C++ version wins by a little, 6 seconds vs. 6.5 seconds for the D translation. I see that the C++ version directly invokes SIMD intrinsics, so perhaps that's to be expected.
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(, 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: D easily overlooked?
On Saturday, 2 September 2017 at 14:49:30 UTC, thinwybk wrote: On Friday, 14 July 2017 at 13:29:30 UTC, Joakim wrote: Yes, D's compile-time regex are still the fastest in the world. I've been benching it recently for a marketing-oriented blog post I'm preparing for the official D blog, std.regex beats out the top C and Rust entries from the benchmarks game on linux/x64 with a single core: http://benchmarksgame.alioth.debian.org/u64q/regexredux.html https://github.com/joakim-noah/regex-bench D comes in third on Android/ARM, but not far behind, suggesting it would still be third on that list if run with a bunch of other languages on mobile. Dmitry thinks it might be alignment issues, the bane of cross-platform, high-performance code on ARM, as he hasn't optimized his regex code for ARM. Do you plan to implement a version for the fastest benchmark "n-body" (http://benchmarksgame.alioth.debian.org/u64q/nbody.html) as well? No, the goal is to demonstrate the nice, super-speedy regex engine in the D standard library by using that same benchmark that Dmitry exhibited years ago, to show D still does really well at regex. It's not to try and compete across all those benchmarks, which D used to dominate at one time. I did wonder how D does on that n-body benchmark now, so I built and ran the fastest C++ version, #8, on my single-core linux/x64 VPS. Here's the source link for each benchmark, the compiler version, and the command I used to build it: C++: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody=gpp=8 clang/llvm 4.0.1 clang -O3 -std=c++11 nbody.cpp -lm -onbody-cpp D: https://bitbucket.org/qznc/d-shootout/raw/898f7f3b3c5d55680229113e973ef95ece6f711a/progs/nbody/nbody.d ldc 1.4 beta1, llvm 4.0.1 ldc2 -O3 nbody.d The D version averages 2.5 seconds, the C++ version 6 seconds, which means D would likely still be at the top of that n-body ranking today. Adding D to the performance comparison of https://github.com/derekmolloy/exploringBB/tree/master/chp05/performance (companion code to the book "Exploring BeagleBone - Tools and Techniques For Building With Embedded Linux") could be good promotion in the embedded domain (where performance, Linux compatibility and code maintainability matters). Hmm, I have not used an ARM board in years, my Pandaboard is in storage far away. By including Android/ARM in the regex blog post, hopefully some people will realize D is a good option there.
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: D easily overlooked?
On Friday, 14 July 2017 at 13:29:30 UTC, Joakim wrote: Yes, D's compile-time regex are still the fastest in the world. I've been benching it recently for a marketing-oriented blog post I'm preparing for the official D blog, std.regex beats out the top C and Rust entries from the benchmarks game on linux/x64 with a single core: http://benchmarksgame.alioth.debian.org/u64q/regexredux.html https://github.com/joakim-noah/regex-bench D comes in third on Android/ARM, but not far behind, suggesting it would still be third on that list if run with a bunch of other languages on mobile. Dmitry thinks it might be alignment issues, the bane of cross-platform, high-performance code on ARM, as he hasn't optimized his regex code for ARM. Do you plan to implement a version for the fastest benchmark "n-body" (http://benchmarksgame.alioth.debian.org/u64q/nbody.html) as well? Adding D to the performance comparison of https://github.com/derekmolloy/exploringBB/tree/master/chp05/performance (companion code to the book "Exploring BeagleBone - Tools and Techniques For Building With Embedded Linux") could be good promotion in the embedded domain (where performance, Linux compatibility and code maintainability matters).
Re: Function pointer from mangled name at runtime?
On Friday, 1 September 2017 at 20:27:45 UTC, Jonathan Marler wrote: You would also need to know type information, not just the name itself. If you had a name like mine.A.B.Test, then you would need to know what A, B, and Test are, are they modules, classes, structs, enums, etc Actually found a way around this. When `reflectFqn` below is instantiated, the fully qualified name that was provided as the template arg gets baked into the function name in hex. So all I have to do is figure out how to get the mangle of reflectFqn!("some string") at runtime. ` abstract class Reflection { string name() const; } class ReflectionImpl(T) : Reflection { override string name() const { return T.stringof; } } export extern(C) const(Reflection) reflectFqn(string fqn)() { mixin("alias T = " ~ fqn ~ ";"); static const(Reflection) refl = new ReflectionImpl!T; return refl; } const(Reflection) reflect(T)() { return (reflectFqn!(fullyQualifiedName!(Unqual!T))); } int main(string[] argv) { alias TFunc = const(Reflection) function(); string mangle = reflectFqn!"package.module.Test".mangleof; auto handle = GetModuleHandleA(null); auto getRefl= cast(TFunc)GetProcAddress(handle, mangle.toStringz); writeln(getRefl().name); return 0; } `
Re: Open Methods: From C++ to D
On Thursday, 31 August 2017 at 23:37:03 UTC, EntangledQuanta wrote: [Windows] I'll try again at some point. I haven't got around to messing with it again. Did you get a chance?
Re: SIMD GC
On 02/09/2017 1:42 PM, Márcio Martins wrote: I was curious if anyone has tried implementing the GC mark phase with SIMD instrs? If so, what were the results, and why didn't it get accepted? At first thought, it seems like a simple project that could improve performance of big-memory programs by a significant margin, right? I'm not so sure it can be. https://github.com/dlang/druntime/blob/master/src/gc/impl/conservative/gc.d#L1955
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); }
SIMD GC
I was curious if anyone has tried implementing the GC mark phase with SIMD instrs? If so, what were the results, and why didn't it get accepted? At first thought, it seems like a simple project that could improve performance of big-memory programs by a significant margin, right?
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(); Next I tried setting processAllocator instead of theAllocator by using: auto newAlloc = Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)); processAllocator = sharedAllocatorObject(); 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?
Re: LDC 1.4.0-beta1
On Saturday, 2 September 2017 at 09:59:42 UTC, Igor Shirkalin wrote: On Saturday, 26 August 2017 at 22:35:11 UTC, kinke wrote: Hello! Hi everyone, on behalf of the LDC team, I'm glad to announce LDC 1.4.0-beta1. The highlights of version 1.4 in a nutshell: * Based on D 2.074.1. Is it possible to build LDC based on D 2.076 with latest -betterC feature? No, we're still ironing out 2.075. https://github.com/ldc-developers/ldc/pull/2252 https://github.com/ldc-developers/ldc/pull/2273
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: LDC 1.4.0-beta1
On Saturday, 26 August 2017 at 22:35:11 UTC, kinke wrote: Hello! Hi everyone, on behalf of the LDC team, I'm glad to announce LDC 1.4.0-beta1. The highlights of version 1.4 in a nutshell: * Based on D 2.074.1. Is it possible to build LDC based on D 2.076 with latest -betterC feature?
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.
[Issue 17800] [2.076] "static foreach" allocates closures in GC without reason
https://issues.dlang.org/show_bug.cgi?id=17800 --- Comment #1 from Илья Ярошенко--- struct S { enum N = 1; } S foo(S v) @nogc { static foreach(_; 0 .. typeof(return).N) { } return S.init; } Error: cannot use typeof(return) inside function __lambda1 with inferred return type --
[Issue 17800] [2.076] "static foreach" allocates closures in GC without reason
https://issues.dlang.org/show_bug.cgi?id=17800 Илья Ярошенкоchanged: What|Removed |Added Keywords||rejects-valid --
[Issue 17800] New: [2.076] "static foreach" allocates closures in GC without reason
https://issues.dlang.org/show_bug.cgi?id=17800 Issue ID: 17800 Summary: [2.076] "static foreach" allocates closures in GC without reason Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ilyayaroshe...@gmail.com struct S { enum N = 1; } void foo(S v) @nogc { static foreach(_; 0 .. v.N) { } } Error: function mir.ndslice.slice.foo is @nogc yet allocates closures with the GC source\mir\ndslice\slice.d(290,23): foo.__lambda2.__lambda1 closes over variable v --