Re: Phobos Action Items
On Saturday, 18 June 2016 at 20:04:50 UTC, Walter Bright wrote: 6. replace std.xml with something we can be proud of that is second to none in performance (Robert burner Schadek is mentoring on this https://github.com/lodo1995/experimental.xml) I hope it will support html and xpath too. Andrea
Re: Phobos: __FILE__ as template default parameter
On 06/20/2016 01:13 AM, Johan Engelen wrote: > On Sunday, 19 June 2016 at 21:40:20 UTC, David Nadlinger wrote: >> On Sunday, 19 June 2016 at 21:13:00 UTC, Johan Engelen wrote: >>> On Sunday, 19 June 2016 at 21:11:59 UTC, Johan Engelen wrote: (I think we can pretty much inline anything the user throws at us) >>> >>> (as long as it is not a naked asm function) >> >> Another example is `alloca`, which you might not want to inline. > > And also variadic functions, for which Dicebot needs __FILE__ to be a > template param.. It is template-based variadic list though in all Phobos cases. This is one of logger examples I was referring to : https://github.com/dlang/phobos/blob/master/std/experimental/logger/core.d#L202-L216 How about defining semantics like "try inlining if possible, fallback to always emitting symbol to object file otherwise"? That would also allow compatible implementation in dmd. My reasoning for proposing that is that for all legitimate cases I'd have to use __FILE__ as a template argument I'd also want the symbol inlined to prevent the bloat. After all CT computation such functions tend to contain 1-2 lines of runtime code only.
Re: Possible bug in std.path?
On Monday, 20 June 2016 at 05:44:53 UTC, Mike Parker wrote: It shouldn't hurt to use the A variant, as Windows will do the necessary conversions under the hood. However, I'd love to know what the problem is with converting wchar* to a string type. This also prints an address: auto foo = "I'm a wstring"w.ptr; writeln(to!wstring(foo)); There was a bug report in std.conv, which was partially fixed in master branch (the one I used). Compiling your code with that fix produces the expected result. However it seems something is still missing. Regarding GetCommandLineA, I could use it but I believe this would exclude several eastern languages, for example.
Re: Possible bug in std.path?
On Monday, 20 June 2016 at 02:19:22 UTC, Hugo wrote: Perhaps I should have said unusual rather than non-standard. But if you want to understand better what I mean, try doing this in the command line, it works correctly: cd \ mkdir test cd test\ mkdir "..\second test\" cd "..\second test\" On the other hand, the way D gets the arguments is the same as in C/C++. Doing it differently than that would be unusual, too. Either way, someone is going to be surprised. I would guess that you're in the minority here with your expectation. It's better then to surprise you than the majority of people who expect the same behavior as in C/C++ programs.
Re: Parameterized inheritence issues, bug or ignorance?
On Monday, 20 June 2016 at 00:01:58 UTC, Joerg Joergonson wrote: I have a gui based on the following classes: public class Widget { Widget Parent; } public class Item : Widget; public class Button(T : ButtonItem) : Widget { T[] Items; ... } public class ButtonItem : Item { void Do() { auto parent = (cast(Button!ButtonItem)this.Parent); ...} ... } What you ask for is called template covariance. D doesn't have it. You can solve your problem by providing Button!ButtonItem-specific functionality in an intermediate ButtonBase class: https://dpaste.dzfl.pl/4c071b237aa0
problem using ldc 1.0.0 as D compiler
Hi folks! I'm using ldc version: LDC - the LLVM D compiler (1.0.0): based on DMD v2.070.2 and LLVM 3.8.0 built with DMD64 D Compiler v2.071.0 Default target: x86_64-unknown-linux-gnu Host CPU: core2 And when trying to run this code (it compiles ok): import std.regex; void main(string[] args) { processLine ("abc int char[]"); } long processLine (string l) { long count; int[string] lpb; lpb = ["char" : 0, "int" : 0, "for" : 0]; foreach (rw; lpb.byKey) { string re = r"(^|\W)" ~ rw ~ r"(\W|$)"; count = 0; auto r = matchAll(l, re); foreach(c; r) count++; lpb[rw] += count; } return count; } I get this error: ./ldcfail Fatal Error while loading '/usr/lib/libphobos2-ldc.so.70': The module 'std.regex.internal.parser' is already defined in './ldcfail'. The same code compiles and executes ok with both dmd (DMD64 D Compiler v2.071.0) and gdc (gdc (GCC) 6.1.1 20160501). Is this a bug in ldc or is it somehow related to my code? Thanks for your help.
Re: Performance issue in struct initialization
Am Sat, 28 May 2016 07:08:52 + schrieb Era Scarecrow : > On Friday, 27 May 2016 at 09:02:17 UTC, Johan Engelen wrote: > > That language guarantee prevents optimization of the > > initialization (in this case, the optimized result would be no > > initialization at all). So a breaking language spec change > > would be needed. Is this pursued by anyone? Perhaps only relax > > the spec when the struct S overrides opEquals ? > > > > (Once the optimization is allowed, I think it will be a fun > > project for me to implement it in LDC. But please keep the > > discussion clean by not discussing how a compiler should make > > use of this language change, how to implement it, etc. Thanks!) > > If opEquals and opCmp are overridden then I don't see why voids > in initialization can't work since how you are comparing it would > determine equality and not a bitwise compare... > I don't think this is a good solution. A '=void' field will always break 'a is b', even with a user defined opEquals. And of course a custom opEquals could do bit comparisons as well. I think a better way to frame this for the spec is: * A struct containing a =void field (directly or nested) cannot be compared bitwise. The compiler is allowed to fill the =void parts with arbitrary data. a == b will only compile if a user provided opEquals is available. a is b will never compile for such structs.
Re: Performance issue in struct initialization
Am Sun, 19 Jun 2016 20:52:52 + schrieb deadalnix : > On Sunday, 19 June 2016 at 11:11:18 UTC, Basile B. wrote: > > On Saturday, 23 April 2016 at 13:37:31 UTC, Andrei Alexandrescu > > wrote: > >> https://issues.dlang.org/show_bug.cgi?id=15951. I showed a few > >> obvious cases, but finding the best code in general is tricky. > >> Ideas? -- Andrei > > > > A new "@noinit" attribute could solve this issue and other > > cases where the initializer is a handicap: > > > > The runtime would skip the copy of the initializer when > > 1- @noinit is an attribute of an aggregate. > > 2- a ctor that takes at least one parameter is present. > > 3- the default ctor is disabled (only a condition for the > > structs or the new free form unions) > > > > // OK > > @noinit struct Foo > > { > >uint a; > >@disable this(); > >this(uint a){} > > } > > > > // not accepted because a ctor with parameters misses > > @noinit struct Foo > > { > >@disable this(); > > } > > > > // Ok but a warning will be emitted... > > @noinit struct Foo > > { > >uint a = 1; // ...because this value is ignored > >@disable this(); > >this(uint a){} > > } > > > > // not accepted because there's a default ctor > > @noinit struct Foo > > { > >this(){} > > } > > > > The rationale is that when there's a constructor that takes > > parameters it's really suposed to initialize the aggregate. At > > least that would be the contract, the "postulate', put by the > > usage of @noinit. > > No new attribute please. Just enable the damn thing where there > is an argumentless constructor and be done with it. Can somebody explain how exactly are constructors related to the problem? If I've got this: struct Foo { int a = 42; int b = void; @disable this(); this(int b) {this.b = b;} } auto foo = Foo(41); I'd still expect a to be initialized to 42. Note that this does _not_ require a initializer symbol or memcpy. I'll post a more detailed follow up post to issue 15951.
Need DMD AST expertise
Context: I'm working on a more correct implementation of the C++ name mangling for Linux/OSX. This is needed for the integration with C++/STL. Problem 1: -- In the following D code 'Expression' is a D class, 'foo' is a C++ function, its argument must be mangled as a pointer to Expression because D has reference semantic (whereas C++ has value semantic). class Expression; extern(C++) void foo(Expression); Question: - - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it. Problem 2: -- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which. extern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_"); In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: - - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? Thx in advance!
Re: More suggestions for find()
On Sunday, 19 June 2016 at 10:38:27 UTC, qznc wrote: On Saturday, 18 June 2016 at 18:54:28 UTC, Andrei Alexandrescu wrote: Got this link from the reddit discussion around the blog article: http://effbot.org/zone/stringlib.htm. The Bloom-filter-style trick looks quite cool. Anyone interested in running some more experiments? Thx! -- Andrei Compare with memmem. That is 4x faster than the current stuff. I guess vector instructions are key. There is a branch in my repo. More like 2x after looking again. For some more concrete numbers: LDC: Search in Alice in Wonderland std: 438 ±12 manual: 315 ±8 A2Phobos: 254 ±7 Chris: 325 ±9 Andrei: 434 ±11 Andrei2: 259 ±6 memmem: 100 ±0 Search in random short strings std: 127 ±14 manual: 124 ±12 A2Phobos: 107 ±8 Chris: 130 ±15 Andrei: 110 ±7 Andrei2: 106 ±7 memmem: 108 ±8 Mismatch in random long strings std: 534 ±432 manual: 587 ±428 A2Phobos: 353 ±274 Chris: 605 ±448 Andrei: 550 ±399 Andrei2: 360 ±280 memmem: 136 ±50 Search random haystack with random needle std: 293 ±211 manual: 265 ±141 A2Phobos: 212 ±163 Chris: 271 ±133 Andrei: 285 ±212 Andrei2: 215 ±164 memmem: 118 ±20 (avg slowdown vs fastest; absolute deviation) CPU ID: GenuineIntel Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz DMD: Search in Alice in Wonderland std: 554 ±17 manual: 382 ±11 A2Phobos: 346 ±10 Chris: 501 ±18 Andrei: 498 ±14 Andrei2: 342 ±9 memmem: 100 ±0 Search in random short strings std: 153 ±31 manual: 131 ±19 A2Phobos: 108 ±9 Chris: 146 ±29 Andrei: 109 ±10 Andrei2: 106 ±7 memmem: 108 ±8 Mismatch in random long strings std: 674 ±542 manual: 651 ±469 A2Phobos: 445 ±362 Chris: 821 ±604 Andrei: 618 ±459 Andrei2: 436 ±354 memmem: 134 ±50 Search random haystack with random needle std: 379 ±307 manual: 284 ±175 A2Phobos: 233 ±177 Chris: 370 ±245 Andrei: 299 ±238 Andrei2: 238 ±188 memmem: 110 ±14 (avg slowdown vs fastest; absolute deviation) CPU ID: GenuineIntel Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
Re: Possible bug in std.path?
On Monday, 20 June 2016 at 10:01:25 UTC, ag0aep6g wrote: On the other hand, the way D gets the arguments is the same as in C/C++. Doing it differently than that would be unusual, too. Not necessarily, cmd.exe is made in C/C++ AFAIK, most other console applications for Windows behave the same way too.
Re: Phobos Action Items
On Saturday, 18 June 2016 at 20:04:50 UTC, Walter Bright wrote: Starting a new thread with this, as requested. There are things here for all skill levels and time commitments. 3. use -cov to improve code coverage of Phobos unittests 4. make sure every function in Phobos has an example 5. make sure every function in Phobos has Params: and Returns: sections http://www.digitalmars.com/d/archives/digitalmars/D/Phobos_Documentation_-_call_to_action_258777.html Maybe someone would like to go a step meta and look into automatically tracking and checking things first? Here is what autotester (or some other tool) could do: * Check for a lower bound of coverage, so we never regress. * Check documentation for Example, Params:, Returns: * Check for broken links By tracking I think: Count the stuff above and plot over time. Somebody did this for the number of pull requests, for example. This in itself does not fix anything, but it motivates. "Measure it and it will improve" –Jack Welch
Re: Possible bug in std.path?
On Monday, 20 June 2016 at 12:38:23 UTC, Hugo wrote: Not necessarily, cmd.exe is made in C/C++ AFAIK, most other console applications for Windows behave the same way too. As seen on MSDN, it's how "Microsoft C/C++ startup code" does it. It's what you get in a C main's argv. Populating a D main's args in a different way would be unusual. Of course you can parse the command line yourself, and do it differently then. You can do this in C, in C++, and in D too. But the default is the other way, in all of them.
Re: problem using ldc 1.0.0 as D compiler
Hi Antonio, On Monday, 20 June 2016 at 11:28:58 UTC, Antonio Corbi wrote: ./ldcfail Fatal Error while loading '/usr/lib/libphobos2-ldc.so.70': The module 'std.regex.internal.parser' is already defined in './ldcfail'. […] Is this a bug in ldc or is it somehow related to my code? Thanks for your help. This is a bug in LDC, or rather its interplay with certain system linker versions. This issue has also been reported at https://github.com/ldc-developers/ldc/issues/1534, but we are not sure how to reproduce it yet. Could you please add your test case and system details there? (Of particular interest are the version of the Linux distribution you are using, and `ld --version`.) As a workaround, you can always use Phobos as a static library in the meantime (e.g. from our the binary release packages). — David
Re: More suggestions for find()
On Monday, 20 June 2016 at 12:34:55 UTC, qznc wrote: On Sunday, 19 June 2016 at 10:38:27 UTC, qznc wrote: On Saturday, 18 June 2016 at 18:54:28 UTC, Andrei Alexandrescu wrote: Got this link from the reddit discussion around the blog article: http://effbot.org/zone/stringlib.htm. The Bloom-filter-style trick looks quite cool. Anyone interested in running some more experiments? Thx! -- Andrei Compare with memmem. That is 4x faster than the current stuff. I guess vector instructions are key. There is a branch in my repo. More like 2x after looking again Cool :) What are the chances of getting this in Phobos?
inout and opApply
Please consider the following program: struct V(T) { int opApply(scope int delegate(ref T value) dg) { return 0; } int opApply(scope int delegate(ref const T value) dg) const { return 0; } } struct V1(T) { int opApply(scope int delegate(ref inout T value) dg) inout { return 0; } } void main() { const V!int mytype1; V!int mytype2; V1!int mytype3; foreach( v; mytype1 ) { } foreach( v; mytype2 ) { } foreach( v; mytype3 ) { // <- This line doesn't compile: cannot uniquely infer foreach argument types } } So the only way to get inout to work is... not to use it? Shachar
Re: Need DMD AST expertise
On Monday, 20 June 2016 at 12:33:31 UTC, Guillaume Chatelet wrote: class Expression; extern(C++) void foo(Expression); Question: - - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it. A FuncDeclaration is a Declaration, which contains the field `LINK linkage;`. That's the one you want. -Johan
Re: inout and opApply
On 06/20/2016 04:47 PM, Shachar Shemesh wrote: > Please consider the following program: > > struct V(T) { > int opApply(scope int delegate(ref T value) dg) { > return 0; > } > int opApply(scope int delegate(ref const T value) dg) const { > return 0; > } > } > > struct V1(T) { > int opApply(scope int delegate(ref inout T value) dg) inout { > return 0; > } > } > > void main() { > const V!int mytype1; > V!int mytype2; > V1!int mytype3; > > foreach( v; mytype1 ) { > } > foreach( v; mytype2 ) { > } > foreach( v; mytype3 ) { // <- This line doesn't compile: cannot > uniquely infer foreach argument types > } > } > > So the only way to get inout to work is... not to use it? > > Shachar I think Steven has mentioned this issue during his DConf inout talk.
Re: Need DMD AST expertise
On Monday, 20 June 2016 at 13:50:45 UTC, Johan Engelen wrote: On Monday, 20 June 2016 at 12:33:31 UTC, Guillaume Chatelet wrote: class Expression; extern(C++) void foo(Expression); Question: - - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it. A FuncDeclaration is a Declaration, which contains the field `LINK linkage;`. That's the one you want. -Johan Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss?
Re: Phobos: __FILE__ as template default parameter
On 2016-06-19 12:43, Dicebot wrote: Yes. It is necessary because runtime parameter list is variadic - template bloat in such cases is usually eliminated by forwarding to another private method immediately turning file/line into first runtime argument instead. Would it be a bad idea to allow this in the compiler: void foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__); It wouldn't be possible to pass "file" or "line" when calling "foo". But it's useful for the special default values, __FILE__ and __LINE__. -- /Jacob Carlborg
Re: Need DMD AST expertise
On 2016-06-20 16:06, Guillaume Chatelet wrote: Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss? 1. Check if the type is a class. There's a field "ty" in Type 2. If it's a class, cast it to TypeClass 3. TypeClass has a field "sym" of type ClassDeclaration 4. ClassDeclaration has three fields: "com", "cpp" and "objc". I think these fields indicate if the class declaration has extern(C++), extern(Objective-C) and so on. If none of them are true, it's standard extern(D) -- /Jacob Carlborg
Re: Need DMD AST expertise
On Monday, 20 June 2016 at 14:42:22 UTC, Jacob Carlborg wrote: On 2016-06-20 16:06, Guillaume Chatelet wrote: Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss? 1. Check if the type is a class. There's a field "ty" in Type 2. If it's a class, cast it to TypeClass 3. TypeClass has a field "sym" of type ClassDeclaration 4. ClassDeclaration has three fields: "com", "cpp" and "objc". I think these fields indicate if the class declaration has extern(C++), extern(Objective-C) and so on. If none of them are true, it's standard extern(D) Pretty cool. Thx Jacob! Anyone has a suggestion for my second problem? If not I'll have to do some kind of mapping between the template args and the parameters...
Re: inout and opApply
On 6/20/16 9:55 AM, Dicebot wrote: On 06/20/2016 04:47 PM, Shachar Shemesh wrote: Please consider the following program: struct V(T) { int opApply(scope int delegate(ref T value) dg) { return 0; } int opApply(scope int delegate(ref const T value) dg) const { return 0; } } struct V1(T) { int opApply(scope int delegate(ref inout T value) dg) inout { return 0; } } void main() { const V!int mytype1; V!int mytype2; V1!int mytype3; foreach( v; mytype1 ) { } foreach( v; mytype2 ) { } foreach( v; mytype3 ) { // <- This line doesn't compile: cannot uniquely infer foreach argument types } } So the only way to get inout to work is... not to use it? I think Steven has mentioned this issue during his DConf inout talk. Yes, it's something I'm going to post about soon. In essence, the delegate which takes inout parameter is currently its own wrapping of inout. Meaning, the implicit delegate the compiler creates does not participate in the inout wrapping for the opApply call. Consider how this works for the compiler. I'll give you an example: V1!int mutableX; foreach(ref int a; mutableX) { a = 5; } Here, I've removed the type inference to set that issue aside for now. What the compiler does is convert your foreach body into a local delegate. This local delegate looks like this: int __foreachBody(ref int a) { a = 5; // this is added by the compiler for flow control return 0; } and then calls: switch(mutableX.opApply(&__foreachBody)) { // process specialized returns from delegate } So, ignoring the special opApply machinery, we can see the fundamental issue here is that we are passing a function pointer of type int (ref int a) into the opApply. However, currently, the compiler treats a function pointer with inout parameters to be simply a pointer to an inout function. The constructed delegate cannot be this, since a is ref int, not ref inout(int). So it cannot compile. We could change the body to not modify a, and possibly we could create a solution, but it's not ideal. What I would like the compiler to do (and I went over this in my talk), is to allow the compiler to inout-wrap a delegate along with the other inout prameters to the function. That is, for: int opApply(scope int delegate(ref inout T value) dg) inout The inout inside the delegate is wrapped just like the inout of the 'this' parameter. effectively, this becomes equivalent to several function signatures: int opApply(scope int delegate(ref T value) dg) int opApply(scope int delegate(ref const T value) dg) const int opApply(scope int delegate(ref immutable T value) dg) immutable int opApply(scope int delegate(ref inout T value) dg) inout And interestingly enough, the rules are kind of backwards for delegates -- while inout doesn't cast to anything, delegates with inout parameters can cast to any type of mutability modifier (I believe this is called contravariance). This is because the actual function is inout, so it cannot harm the mutability. So something like this: foreach(inout a; anyV1) { } should work for any flavor of V1. I think this should work with existing code, and would simply open up things like opApply to inout support. The only issue is that the compiler has to assume that while calling the delegate, the inout parameters passed COULD change value, because it doesn't know whether the passed delegate is truly inout, or just matches the constancy of the type, which could potentially be mutable. This differs from current expectations of inout delegate or function pointers. It's a lot of complex explanation, but the end result is that you could simply tag your opApply's with inout and have one version for all modifiers. -Steve
Re: Need DMD AST expertise
On Monday, 20 June 2016 at 14:06:57 UTC, Guillaume Chatelet wrote: Thx Johan. I'm confused though Sorry for misreading your question.
Re: More suggestions for find()
On 6/20/16 8:34 AM, qznc wrote: On Sunday, 19 June 2016 at 10:38:27 UTC, qznc wrote: On Saturday, 18 June 2016 at 18:54:28 UTC, Andrei Alexandrescu wrote: Got this link from the reddit discussion around the blog article: http://effbot.org/zone/stringlib.htm. The Bloom-filter-style trick looks quite cool. Anyone interested in running some more experiments? Thx! -- Andrei Compare with memmem. That is 4x faster than the current stuff. I guess vector instructions are key. There is a branch in my repo. [snip] Super cool! One thought - the current algorithm computes a "skip". In the case of Alice in Wonderland, that skip is relatively small, I recall like 4. If the skip is large enough, the current algorithm is faster than memmem. So it would be best to compute the skip and then switch to memmem if the skip falls below a cutoff. -- Andrei
Fiber implementation questions
Hello, I am thinking about faster event loop that vibe.d has (does not matter what driver are used). I want to implement (at least DIP) advanced Fiber yielding loop that can allow to eliminate context switching for all kind of event waiters. Q1: Is it save to detach Fiber context from one thread and attach it to another thread? Q2: core.thread.Fiber implementation looks like GC does not scan function stacks for yielded contexts. Why? Best regards, Ilya
Re: Fiber implementation questions
Am 20.06.2016 um 17:43 schrieb Ilya Yaroshenko: Hello, I am thinking about faster event loop that vibe.d has (does not matter what driver are used). I want to implement (at least DIP) advanced Fiber yielding loop that can allow to eliminate context switching for all kind of event waiters. I'm currently working on a successor of vibe.d's core module [1], which is more or less an internal rewrite to yield maximum performance. The vibe.d side definitely plays a part there, but most of the improvements are based on a rewritten event loop abstraction [2], which gives roughly a 3x speedup over both, libevent and libasync*, for a simple HTTP server request benchmark. This event loop abstraction is currently just a proof of concept and still experimental, though. Q1: Is it save to detach Fiber context from one thread and attach it to another thread? It will at least always break TLS variables in one way or another. [1]: https://github.com/vibe-d/vibe-core [2]: https://github.com/vibe-d/eventcore * May have changed in the past weeks/months
Re: More suggestions for find()
On Monday, 20 June 2016 at 13:27:59 UTC, Jack Stouffer wrote: On Monday, 20 June 2016 at 12:34:55 UTC, qznc wrote: On Sunday, 19 June 2016 at 10:38:27 UTC, qznc wrote: On Saturday, 18 June 2016 at 18:54:28 UTC, Andrei Alexandrescu wrote: Got this link from the reddit discussion around the blog article: http://effbot.org/zone/stringlib.htm. The Bloom-filter-style trick looks quite cool. Anyone interested in running some more experiments? Thx! -- Andrei Compare with memmem. That is 4x faster than the current stuff. I guess vector instructions are key. There is a branch in my repo. More like 2x after looking again Cool :) What are the chances of getting this in Phobos? Low. It requires the GNU libc to link against. We don't want that dependency. We cannot port it directly since it is GPL code. It is even more of a special case, since it only works for the == predicate. I'm not sure about the vector instructions it requires. What we need is a clean room implementation of the two way string matching algorithm with vector instructions?
Re: Phobos: __FILE__ as template default parameter
On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote: Would it be a bad idea to allow this in the compiler: void foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__); It wouldn't be possible to pass "file" or "line" when calling "foo". But it's useful for the special default values, __FILE__ and __LINE__. I very much agree with this idea. Like with the current system of forwarding to a function with explicit file and line run-time arguments, a function can be made accessible that has them as explicit parameters for those cases when you want to pretend to be somewhere you're not. :p -- Simen
Re: Fiber implementation questions
On 06/20/2016 06:43 PM, Ilya Yaroshenko wrote: > Hello, > > I am thinking about faster event loop that vibe.d has (does not matter > what driver are used). I want to implement (at least DIP) advanced Fiber > yielding loop that can allow to eliminate context switching for all kind > of event waiters. > > Q1: Is it save to detach Fiber context from one thread and attach it to > another thread? No, not without special (expensive) runtime and possibly compiler support. Primarily because TLS. > Q2: core.thread.Fiber implementation looks like GC does not scan > function stacks for yielded contexts. Why? Don't know. It indeed sounds wrong though I have never experienced premature collection with fibers so the matter maybe more complicated than it seems.
Re: UTF-8 Everywhere
On 06/19/2016 11:44 PM, Walter Bright via Digitalmars-d wrote: On 6/19/2016 11:36 PM, Charles Hixson via Digitalmars-d wrote: To me it seems that a lot of the time processing is more efficient with UCS-4 (what I call utf-32). Storage is clearly more efficient with utf-8, but access is more direct with UCS-4. I agree that utf-8 is generally to be preferred where it can be efficiently used, but that's not everywhere. The problem is efficient bi-directional conversion...which D appears to handle fairly well already with text() and dtext(). (I don't see any utility for utf-16. To me that seems like a first attempt that should have been deprecated.) That seemed to me to be true, too, until I wrote a text processing program using UCS-4. It was rather slow. Turns out, 4x memory consumption has a huge performance cost. The approach I took (which worked well for my purposes) was to process the text a line at a time, and for that the overhead of memory was trivial. ... If I'd needed to go back and forth this wouldn't have been desirable, but there was one dtext conversion, processing, and then several text conversions (of small portions), and it was quite efficient. Clearly this can't be the approach taken in all circumstances, but for this purpose it was significantly more efficient than any other approach I've tried. It's also true that most of the text I handled was actually ASCII, which would have made the most common conversion processes simpler. To me it appears that both cases need to be handled. The problem is documenting the tradeoffs in efficiency. D seems to already work quite well with arrays of dchars, so there may well not be any need for development in that area. Direct indexing of utf-8 arrays, however, is a much more complicated thing, which I doubt can ever be as efficient. Memory allocation, however, is a separate, though not independent, complexity. If you can work in small chunks then it becomes less important.
Re: Need DMD AST expertise
On 2016-06-20 14:33, Guillaume Chatelet wrote: Problem 2: -- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which. extern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_"); In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: - - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? Not sure I understand the question. Are you saying that the two integers are mangled differently because there are two template parameters? I'm guessing you need to look at the template declaration to get more information about the template parameters. -- /Jacob Carlborg
Re: Fiber implementation questions
On Monday, 20 June 2016 at 15:43:27 UTC, Ilya Yaroshenko wrote: Hello, I am thinking about faster event loop that vibe.d has (does not matter what driver are used). I want to implement (at least DIP) advanced Fiber yielding loop that can allow to eliminate context switching for all kind of event waiters. Q1: Is it save to detach Fiber context from one thread and attach it to another thread? No, and there are no way to make it safe without significant penalty for ALL code (not just code using fibers) and breaking the type system. Q2: core.thread.Fiber implementation looks like GC does not scan function stacks for yielded contexts. Why? Doesn't it ?
Re: Performance issue in struct initialization
On Monday, 20 June 2016 at 11:45:28 UTC, Johannes Pfau wrote: Am Sun, 19 Jun 2016 20:52:52 + schrieb deadalnix : On Sunday, 19 June 2016 at 11:11:18 UTC, Basile B. wrote: > On Saturday, 23 April 2016 at 13:37:31 UTC, Andrei > Alexandrescu wrote: >> https://issues.dlang.org/show_bug.cgi?id=15951. I showed a >> few obvious cases, but finding the best code in general is >> tricky. Ideas? -- Andrei > > A new "@noinit" attribute could solve this issue and other > cases where the initializer is a handicap: > > The runtime would skip the copy of the initializer when > 1- @noinit is an attribute of an aggregate. > 2- a ctor that takes at least one parameter is present. > 3- the default ctor is disabled (only a condition for the > structs or the new free form unions) > > // OK > @noinit struct Foo > { >uint a; >@disable this(); >this(uint a){} > } > > // not accepted because a ctor with parameters misses > @noinit struct Foo > { >@disable this(); > } > > // Ok but a warning will be emitted... > @noinit struct Foo > { >uint a = 1; // ...because this value is ignored >@disable this(); >this(uint a){} > } > > // not accepted because there's a default ctor > @noinit struct Foo > { >this(){} > } > > The rationale is that when there's a constructor that takes > parameters it's really suposed to initialize the aggregate. > At least that would be the contract, the "postulate', put by > the usage of @noinit. No new attribute please. Just enable the damn thing where there is an argumentless constructor and be done with it. Can somebody explain how exactly are constructors related to the problem? The initializer is copied to the chunk that represents the new aggregate instance. The idea here is to explicitly disable this copy to get a faster instantiation, under certain conditions. For example in allocator.make() this would mean "skip the call to emplace() and call directly __ctor() on the new chunk". If I've got this: struct Foo { int a = 42; int b = void; @disable this(); this(int b) {this.b = b;} } auto foo = Foo(41); I'd still expect a to be initialized to 42. That's exactly why with @noinit you would get a warning Note that this does _not_ require a initializer symbol or memcpy. I'be verified again and the initializer is copied. For example with a gap in the static initial values: struct Foo { int a = 7; int gap = void; int c = 8; @disable this(); this(int a) {this.a = a;} } auto fun(){ auto foo = Foo(41); return foo.a;} I get (-O -release -inline) for fun(): 00457D58h sub rsp, 18h 00457D5Ch mov esi, 004C9390h // typid(Foo).initializer.ptr 00457D61h lea rdi, qword ptr [rsp+08h] 00457D66h movsq //copy 8, note that the gap is not handled at all 00457D68h movsb //copy 1 00457D69h movsb //copy 1 00457D6Ah movsb //copy 1 00457D6Bh movsb //copy 1 00457D6Ch mov eax, 0029h //inlined __ctor 00457D71h mov dword ptr [rsp+08h], eax 00457D75h add rsp, 18h 00457D79h ret But that was obvious. How would you expect a = 7 and c = 8 to be generated otherwise ? with @noinit you would get sub rsp, 18h mov eax, 0029h //inlined __ctor mov dword ptr [rsp+08h], eax add rsp, 18h ret That's a really simple and pragmatic idea. But I guess that if you manage to get the compiler to generate a smarter initializer copy then the problem is fixed. At least I'll experiment this noinit stuff in my user library.
Re: Need DMD AST expertise
On Monday, 20 June 2016 at 18:59:09 UTC, Jacob Carlborg wrote: On 2016-06-20 14:33, Guillaume Chatelet wrote: Problem 2: -- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which. extern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_"); In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: - - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? Not sure I understand the question. Sorry about not being too clear. Are you saying that the two integers are mangled differently because there are two template parameters? Yes exactly. I'm guessing you need to look at the template declaration to get more information about the template parameters. The TemplateInstance [1] gives me `tiargs` and `tdtypes`. // Array of Types/Expressions of template // instance arguments [int*, char, 10*10] Objects* tiargs; // Array of Types/Expressions corresponding // to TemplateDeclaration.parameters // [int, char, 100] Objects tdtypes; I'm using `tiargs` right now (I'm not really sure what `tdtypes` is). AFAIU I can access TemplateDeclaration from TemplateInstance through `tempdecl` even though it's stored as a Dsymbol. I'll have a look at `parameters` from TemplateDeclaration [2] but I still need to match it to the function arguments somehow. The following example illustrates the process of pairing the int to the template parameter. extern(C++) B foo(A, B)(*B, ref const A); foo!(int, int) => int foo(*int, ref const int); ^^ ^^ ^ 12 21 2 1. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L5895 2. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L406
Re: Phobos: __FILE__ as template default parameter
On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote: On 2016-06-19 12:43, Dicebot wrote: Yes. It is necessary because runtime parameter list is variadic - template bloat in such cases is usually eliminated by forwarding to another private method immediately turning file/line into first runtime argument instead. Would it be a bad idea to allow this in the compiler: void foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__); It wouldn't be possible to pass "file" or "line" when calling "foo". But it's useful for the special default values, __FILE__ and __LINE__. I think it would be good idea to take this even further: T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 t2, T3 t3) In other words, I think that the limitation that variadic template parameter list must be at the end of the function parameters is arbitrary and just a deficiency of the current implementation. A fixed number of parameters proceeding or following a variadic list should all work equally well, even in combination with IFTI. BTW, Ruby also allows to define methods with such parameters: foo(first_arg, *middle_arguments, last_arg)
Re: Phobos: __FILE__ as template default parameter
On Tuesday, 21 June 2016 at 02:59:44 UTC, ZombineDev wrote: On Monday, 20 June 2016 at 14:28:06 UTC, Jacob Carlborg wrote: On 2016-06-19 12:43, Dicebot wrote: Yes. It is necessary because runtime parameter list is variadic - template bloat in such cases is usually eliminated by forwarding to another private method immediately turning file/line into first runtime argument instead. Would it be a bad idea to allow this in the compiler: void foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__); It wouldn't be possible to pass "file" or "line" when calling "foo". But it's useful for the special default values, __FILE__ and __LINE__. I think it would be good idea to take this even further: T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Args args, T2 t2, T3 t3) In other words, I think that the limitation that variadic template parameter list must be at the end of the function parameters is arbitrary and just a deficiency of the current implementation. A fixed number of parameters proceeding or following a variadic list should all work equally well, even in combination with IFTI. BTW, Ruby also allows to define methods with such parameters: foo(first_arg, *middle_arguments, last_arg) I meant: T4 foo(T4, T0, T1, Ts..., T2, T3)(T0 t0, T1 t1, Ts ts, T2 t2, T3 t3)
Re: Possible bug in std.path?
On Monday, 20 June 2016 at 12:55:21 UTC, ag0aep6g wrote: On Monday, 20 June 2016 at 12:38:23 UTC, Hugo wrote: Not necessarily, cmd.exe is made in C/C++ AFAIK, most other console applications for Windows behave the same way too. As seen on MSDN, it's how "Microsoft C/C++ startup code" does it. It's what you get in a C main's argv. Populating a D main's args in a different way would be unusual. Of course you can parse the command line yourself, and do it differently then. You can do this in C, in C++, and in D too. But the default is the other way, in all of them. I guess all the console programs I have used for MS products (since MS-DOS) have been unusual then according to MSDN. ;)
Examples of dub use needed
Dub doesn't really work like other package managers. When I load a package: dub fetch scriptlike It stores it someplace and doesn't say where. You have to run 'dub list' to figure out where. That's is very different than other packages. It deserves a bigger mention in the meager documentation. I've been trying to init a project using the command dub -init -f sdl trickproject -or- dub -f sdl -init trickproject and nothing seems to parse. So, I look at the source code for the format option and see this: args.getopt("f|format", &m_format, [ "Sets the format to use for the package description file. Possible values:", " " ~ [__traits(allMembers, PackageFormat)].map!(f => f == m_format.init.to!string ? f ~ " (default)" : f).join(", ") ]); It doesn't look straightforward at all. Not sure why there is so much complexity on this particular commandline option, but shouldn't these command options work the way I have them? In the interactive mode, I get to make the selection for the project file format. I don't see many examples of how to use options.
Re: Performance issue in struct initialization
Am Mon, 20 Jun 2016 20:34:12 + schrieb Basile B. : > On Monday, 20 June 2016 at 11:45:28 UTC, Johannes Pfau wrote: > > Am Sun, 19 Jun 2016 20:52:52 + > > schrieb deadalnix : > > > >> On Sunday, 19 June 2016 at 11:11:18 UTC, Basile B. wrote: > >> > On Saturday, 23 April 2016 at 13:37:31 UTC, Andrei > >> > Alexandrescu wrote: > >> >> https://issues.dlang.org/show_bug.cgi?id=15951. I showed a > >> >> few obvious cases, but finding the best code in general is > >> >> tricky. Ideas? -- Andrei > >> > > >> > A new "@noinit" attribute could solve this issue and other > >> > cases where the initializer is a handicap: > >> > > >> > The runtime would skip the copy of the initializer when > >> > 1- @noinit is an attribute of an aggregate. > >> > 2- a ctor that takes at least one parameter is present. > >> > 3- the default ctor is disabled (only a condition for the > >> > structs or the new free form unions) > >> > > >> > // OK > >> > @noinit struct Foo > >> > { > >> >uint a; > >> >@disable this(); > >> >this(uint a){} > >> > } > >> > > >> > // not accepted because a ctor with parameters misses > >> > @noinit struct Foo > >> > { > >> >@disable this(); > >> > } > >> > > >> > // Ok but a warning will be emitted... > >> > @noinit struct Foo > >> > { > >> >uint a = 1; // ...because this value is ignored > >> >@disable this(); > >> >this(uint a){} > >> > } > >> > > >> > // not accepted because there's a default ctor > >> > @noinit struct Foo > >> > { > >> >this(){} > >> > } > >> > > >> > The rationale is that when there's a constructor that takes > >> > parameters it's really suposed to initialize the aggregate. > >> > At least that would be the contract, the "postulate', put by > >> > the usage of @noinit. > >> > >> No new attribute please. Just enable the damn thing where > >> there is an argumentless constructor and be done with it. > > > > Can somebody explain how exactly are constructors related to > > the problem? > > The initializer is copied to the chunk that represents the new > aggregate instance. The idea here is to explicitly disable this > copy to get a faster instantiation, under certain conditions. For > example in allocator.make() this would mean "skip the call to > emplace() and call directly __ctor() on the new chunk". > > > If I've got this: > > struct Foo > > { > > int a = 42; > > int b = void; > > > > @disable this(); > > this(int b) > > {this.b = b;} > > } > > auto foo = Foo(41); > > > > I'd still expect a to be initialized to 42. > > That's exactly why with @noinit you would get a warning > > > Note that this does _not_ require a initializer symbol or > > memcpy. > > I'be verified again and the initializer is copied. For example > with a gap in the static initial values: I meant this does not have to use a symbol. Right now it does, but that's an implementation issue. > > > struct Foo > { > int a = 7; > int gap = void; > int c = 8; > @disable this(); > this(int a) > {this.a = a;} > } > auto fun(){ auto foo = Foo(41); return foo.a;} > > > I get (-O -release -inline) for fun(): > > 00457D58h sub rsp, 18h > 00457D5Ch mov esi, 004C9390h // > typid(Foo).initializer.ptr > 00457D61h lea rdi, qword ptr [rsp+08h] > 00457D66h movsq //copy 8, note that the gap is not > handled at all > 00457D68h movsb //copy 1 > 00457D69h movsb //copy 1 > 00457D6Ah movsb //copy 1 > 00457D6Bh movsb //copy 1 > 00457D6Ch mov eax, 0029h //inlined __ctor > 00457D71h mov dword ptr [rsp+08h], eax > 00457D75h add rsp, 18h > 00457D79h ret > > But that was obvious. How would you expect a = 7 and c = 8 to be > generated otherwise ? Instead of doing foo = Foo.init(symbol) you could do foo = {a:7, c:8}(literal) (in the compiler). Then you don't need memory to memory moves at all if your architecure allows hardcoding constants in instructions. Additionally this allows the optimizer to see if you're writing to a default initialized variable and remove the useless initialization. If you don't have any default initializers / all are =void, foo = {} is a no-op. With @noinit using default initializers causes a warning, with my idea using default initializers works fine and if you don't want any, just set all fields to =void. (This does not produce optimal code right now, but considering the =void fields when initializing is a simple change in GDC) See https://issues.dlang.org/show_bug.cgi?id=15951#c4 for details. > > with @noinit you would get > > sub rsp, 18h > mov eax, 0029h //inlined __ctor > mov dword ptr [rsp+08h], eax > add rsp, 18h > ret > > That's a really simple and pragmatic idea. But I guess that if > you manage to get the compiler to generate a smarter initializer > copy then the problem is fixed. At least I'll experiment this > noinit stuff in my user library.
Re: Need DMD AST expertise
On 2016-06-20 22:52, Guillaume Chatelet wrote: The TemplateInstance [1] gives me `tiargs` and `tdtypes`. // Array of Types/Expressions of template // instance arguments [int*, char, 10*10] Objects* tiargs; // Array of Types/Expressions corresponding // to TemplateDeclaration.parameters // [int, char, 100] Objects tdtypes; I'm using `tiargs` right now (I'm not really sure what `tdtypes` is). A guess: "tiargs" is the types of the values passed to the template. "tdtypes" is the types the template is instantiated with. void foo(T)(T* a); int b; foo!(int)(&b*); "tiargs" is "int*" and "tdtypes" is "int". But this can easily be confirmed using some printf debugging. AFAIU I can access TemplateDeclaration from TemplateInstance through `tempdecl` even though it's stored as a Dsymbol. I'll have a look at `parameters` from TemplateDeclaration [2] but I still need to match it to the function arguments somehow. The following example illustrates the process of pairing the int to the template parameter. extern(C++) B foo(A, B)(*B, ref const A); foo!(int, int) => int foo(*int, ref const int); ^^ ^^ ^ 12 21 2 1. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L5895 2. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L406 Are the types the same objects so you can compare by just comparing the pointers? -- /Jacob Carlborg
Re: Examples of dub use needed
On 2016-06-21 06:42, Guido wrote: Dub doesn't really work like other package managers. When I load a package: dub fetch scriptlike It stores it someplace and doesn't say where. You have to run 'dub list' to figure out where. That's is very different than other packages. It deserves a bigger mention in the meager documentation. Dub doesn't install packages. It's not a tool meant for end users. If you want something installed in the traditional sense it should go in the system package manager. I've been trying to init a project using the command dub -init -f sdl trickproject -or- dub -f sdl -init trickproject and nothing seems to parse. The correct way is: dub init trickproject -f sdl Note that "init" is a command and not a flag. You can run "dub --help" to see the "init" command. The run "dub init --help" to see that help for that specific command. -- /Jacob Carlborg