Re: Efficient way to pass struct as parameter
Am Wed, 3 Jan 2018 10:57:13 -0800 schrieb Ali Çehreli: > On 01/03/2018 10:40 AM, Patrick Schluter wrote: > > On Tuesday, 2 January 2018 at 23:27:22 UTC, H. S. Teoh wrote: > >> > >> When it comes to optimization, there are 3 rules: profile, profile, > >> profile. I used to heavily hand-"optimize" my code a lot (I come from > >> a strong C/C++ background -- premature optimization seems to be a > >> common malady among us in that crowd). > > > > That's why I always tell that C++ is premature optimization oriented > > programming, aka as POOP. > > […] > > That's why I like producer functions that return values: > > vector makeInts(some param) { > // ... > } > > And if they can be 'pure', D allows them to be used to initialize > immutable variables as well. Pretty cool! :) > > Ali May I add, this is also optimal performance-wise. The result variable will be allocated on the caller stack and the callee writes directly to it. So even POOPs like me, do it. -- Marco
Re: __dtor vs __xdtor
Am Fri, 11 Aug 2017 17:10:14 + schrieb bitwise: > Ok thanks. > > I don't understand why you would ever want to call __dtor > then...is it possible to have only __dtor without also having > __xdtor? Like, if I want to call a struct's destructor, do I have > to check for both, or can I just always check for, and call > __xdtor? I think it was simply that all the special methods needed a symbol name, so this() was called __ctor and ~this() was called __dtor. It was never supposed to cover field destruction, mixed in destructors or inheritance in classes. User code was not expected to call these directly anyways. Not very long ago __xdtor and __xpostblit were introduced that wrap up the entire finalization and copy operation. __dtor will remain as the 1:1 representation of the ~this() method. -- Marco
Re: readText with added null-terminator that enables sentinel-based search
Am Tue, 08 Aug 2017 20:48:39 + schrieb Nordlöw: > Has anybody written a wrapper around `std.file.readText` (or > similar) that appends a final zero-byte terminator in order to > realize sentinel-based search in textual parsers. What do you mean by similar? There are many ways to load a file into memory before appending \0. In fast.json I used a memory mapped file. On some OSs you can read past the end of such mappings safely to generate extra \0 bytes. 16 zero-bytes is a good amount if you want to use the SSE4.2 string instruction. https://github.com/mleise/fast/blob/master/source/fast/json.d#L1464 -- Marco
Re: returning D string from C++?
Am Sat, 05 Aug 2017 20:17:23 + schrieb bitwise: > virtual DString getTitle() const { > DString ret; > ret.length = GetWindowTextLength(_hwnd) + 1; > ret.ptr = (const char*)gc_malloc(ret.length, 0xA, NULL); > GetWindowText(_hwnd, (char*)ret.ptr, ret.length); > return ret; > } In due diligence, you are casting an ANSI string into a UTF-8 string which will result in broken Unicode for non-ASCII window titles. In any case it is better to use the wide-character versions of Windows-API functions nowadays. (Those ending in 'W' instead of 'A'). Starting with Windows 2000, the core was upgraded to UTF-16[1], which means you don't have to implement the lossy conversion to ANSI code pages and end up like this ... [information loss] UTF-8 <-> Windows codepage <-> UTF-16 || in your code inside Windows ... but instead directly pass and get Unicode strings like this ... UTF-8 <-> UTF-16 | in your code string to zero terminated UTF-16: http://dlang.org/phobos/std_utf.html#toUTF16z zero terminated UTF-16 to string: ptr.to!string() or just ptr[0..len] if known Second I'd like to mention that you should have set ret.length = GetWindowText(_hwnd, (char*)ret.ptr, ret.length); Currently your length is anything from 1 to N bytes longer than the actual string[2], which is not obvious because any debug printing or display of the string stops at the embedded \0 terminator. [1] https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows [2] https://msdn.microsoft.com/de-de/library/windows/desktop/ms633521(v=vs.85).aspx -- Marco
Re: Compile Time versus Run Time
Am Mon, 31 Jul 2017 15:43:21 + schrieb Martin Tschierschke: > As a rookie in D programming I try to understand the power of > templated functions with compile time parameters. With DMD 2.074 > a compile time format > (auto output = format!("Print this %s")(var);) > > was introduced, now we all know that very many of this format > strings are immutable, so wouldn't it be cool to automatically > detect this and use the compile time version? > > Without the need to think about it and to use an other syntax? > Is this theoretically possible? I see no way to accomplish this. For the compiler to see the contents of the format string it needs to be a template argument and as soon as you want to also allow runtime values to be accepted there, you need to use an alias, which in turn precludes the use of function results or concatenation. Believe me I've spent quite some time on trying something like this for format strings. > Regards mt. As far as using template arguments for code optimizations go, I know that at least GCC will turn runtime arguments into template arguments of sorts internally, thereby creating duplicates of the function with one or more arguments optimized out. On the other hand, you don't want to drive this too far. While it is nice to have compile-time checks, templates are actually troublesome on some levels. For example, the duplicated code makes it hard to cache the formatting function in the CPU and when writing libraries you always have to provide the full implementation that will get linked into the host application, which is a concern under certain licensing schemes. The benefits of shared libraries, like loading the code into memory once and use it by multiple processes or fixing security issues in one central place and have all programs use the new code without recompilation are also void. I.e. without template arguments, `format()` and all its dependencies (templates as well as regular functions) are compiled right into the Phobos shared library for all programs to use. If there is a security issue, it can be replaced with a patched version. Now with template arguments, `format!()` is compiled into each Dlang application multiple times for each format string and security fixes cannot be applied without recompiling them all. -- Marco
Re: Error 1: Previous Definition Different : _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo)
Am Fri, 28 Jul 2017 22:53:52 + schrieb FoxyBrown: > After upgrading to latest dmd and having to rebuild gtk, I now > get the following error > > Error 1: Previous Definition Different : > _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo) > > > in my apps that were previously working(no changes, opened up old > app and tried to build it and it didn't work). All I did was > upgrade dmd2. Expect potential changes to the ABI in every Dlang version. After a compiler upgrade you have to rebuild all libraries. That's why for the Gentoo Linux packages I maintain, there is a separate library path for each Dlang version, compiler vendor and architecture (i.e. 32-bit/64-bit). That way an upgrade doesn't affect existing apps at the cost of manually maintaining the list of compilers (and versions) you want to install GtkD for. > So tired of D and it's crap ;/ So unstable in so many ways. About > 10% as productive overall than other languages I've used. It's > error messages are about as helpful as a rock. Error messages did get better, but generic functions will always end up looking more verbose than e.g. errors for C function calls. -- Marco
Re: GtkD nothing
Am Thu, 06 Jul 2017 03:49:04 + schrieb FoxyBrown: > Unfortunately, importing that module seems to throw an error for > some insane reason. > > Error 42: Symbol Undefined _D3gtk6All12__ModuleInfoZ > (gtk.AllGTK.__ModuleInfo) > > without importing it in to the project(but directly importing all > the other modules works fine, e.g., copying and pasting). > Sounds like there is no compiled version of gtk.All in the GtkD lib. You could compile it together with your application as a workaround. -- Marco
Re: avoid extra variable during void pointer cast
Am Mon, 15 May 2017 19:30:00 + schrieb Bauss: > pragma(inline, true); doesn't actually do what you think it does. > In lining is always done whenever possible and that only tells > the compiler to spit out an error if it can't inline it. A compiler doesn't simply inline whenever it can. A big function that's called often would lead to massive code duplication in that case. What I meant pragma(inline, true) to do is overrule this cost calculation. Since the OP asked for no extra function calls, the error on failure to inline seemed appropriate. Cross-module inlining may fail for example on some compiler(s) or with separate compilation. -- Marco
Re: D on AArch64 CPU
Am Sun, 14 May 2017 15:11:09 + schrieb Richard Delorme: > Or should I wait for an offcial support of this architecture? You ARE the official support now. :) -- Marco
Re: avoid extra variable during void pointer cast
Am Sun, 14 May 2017 20:18:24 + schrieb Kevin Brogan: > I have a piece of code that takes a callback function. > > The callback has the signature void callback(void* state, void* > data) > > There are several of these functions. All of them use state and > data as differing types. > > As an example, let's look at one that uses both of them as int*. > > addInt(void* state, void* data) > { > *cast(int*)state += *cast(int*)data; > } > > Is it not possible to specify the cast as an alias so that I can > declare the cast once at the beginning of the function? > > Something like this? > > addInt(void* state, void* data) > { > alias _state = cast(int*)state; // Error: basic type > expected, not cast > alias _data = cast(int*)data; // Error: basic type expected, > not cast > > *_state += *_data; > } No, that is not possible. An alias can only be assigned a symbol. > I can always do this: > > addInt(void* state, void* data) > { > int* _state = cast(int*)state; > int* _data = cast(int*)data; > > *_state += *_data; > } > > But I don't want to create a new variable and assign it everytime > I call the function. The examples I'm using are contrived, but in > the c code I am porting this from, the callback gets called > thousands of times a second, every optimization matters, and the > variables are used many times per function. I don't want to > riddle the code with casts if i can avoid it and I don't want to > create and destroy useless proxy variables every time the > function is called. Let the compiler optimize the assignment away and don't worry much about it. Inlining also works well within the same module. In this case here I would probably use "consume" functions as I dub them: import std.traits; pragma(inline, true) /* Not really needed I hope ;) */ ref T consume(T)(ref void* data) if (!hasIndirections!T) { T* ptr = cast(T*)data; data += T.sizeof; return *ptr; } You can then rewrite your addInt function like this: void add(T)(void* state, void* data) if (isNumeric!T) { state.consume!T += data.consume!T; } -- Marco
Re: Easy sockets - don't exist yet?
Just in case, here are the relevant docs: http://dlang.org/phobos/std_net_curl.html
Re: Easy sockets - don't exist yet?
Am Mon, 26 Sep 2016 23:40:10 + schrieb Vincent: > 1. Easy to use. No more stupid "UNIX sockets", "TCP types" and so > on. Just simple as this: > > // Client side > auto sock = new ClientSocket("google.com", 80); > sock.WriteLine("GET / HTTP/1.0"); > sock.WriteLine("Host: google.com"); > sock.WriteLine();// empty line sent Haha, this is not how I learned network layers at school. You seem to want on the ... Network Layer (3): A connection based socket using the Internet Protocol Transport Layer (4): A stateful connection using TCP Application Layer (6): HTTP Just that you don't ask for HTTP directly, but shoehorn a packet based socket into sending microscopic strings. In this case I recommend cURL, which you can feed with all the header data at once and sends your complete request in one packet. That'll also handle most of the HTTP specialties. Not all data transmissions via IP are TCP either. A good bunch is sent via stateless UDP. That would not be considered a stream though. I'm just getting at the name "ClientSocket" here, which can entail more than TCP/IP streams. -- Marco
Re: How to debug (potential) GC bugs?
Am Sun, 25 Sep 2016 16:23:11 + schrieb Matthias Klumpp: > So, I would like to know the following things: > > 1) Is there any caveat when linking to C libraries and using the > GC in a project? So far, it seems to be working well, but there > have been a few cases where I was suspicious about the GC > actually doing something to malloc'ed stuff or C structs present > in the bindings. If you pass callbacks into the C code, make sure they never throw. Stack unwinding and exception handling generally doesn't work across language boundaries. A tracing garbage collector starts with the assumption that all the memory that it allocated is no longer reachable and then starts scanning the known memory for any pointers to allocations that falsify this assumption. What you malloc'ed is unknown to the GC and wont be scanned. Should you ever have GC memory pointers in your malloc'ed stuff, then you need to call GC.addRange() to make those pointers keep the allocations alive. Otherwise you will get a "used after free" error: data corruption or access violations. A simple case would be a string that you constructed in D and store in C as a pointer. The GC can automatically scan the stack and any globals/statics on the D side, but that's about it. I know of no tools similar to valgrind specially designed to debug the D GC. You can plug into the GC API and keep track of the allocation sizes. I.e. write a proxy GC. -- Marco
Re: Cannot compare object.opEquals is not nogc
Am Sat, 23 Jul 2016 13:18:03 + schrieb Rufus Smith: > Trying to compare a *ptr value with a value in nogc code results > in the error: > > Error: @nogc function '...' cannot call non-@nogc function > 'object.opEquals' > > Shouldn't object opEquals be marked? The only situation that you can work around is if the 'object' is actually known to be one of your @nogc objects. Then you can simply downcast before calling opEquals. It's certainly limiting, but just an artifact of OOP and I can assure you that making D usable without GC has been high on the priority list (for an community driven open-source project anyways). Phobos got reworked to get rid of unnecessary GC allocations and Andrei Alexandrescu contemplated making object's methods @nogc at one point. If you need a restricted object hierarchy, you'll have to write a new "NoGcObject" base class. opEquals would still take "object", though you can avoid a dynamic cast by writing: (cast(NoGcObject)cast(void*)obj).someMethod(); The cast to void* prior to the downcast drops the class type information and a dynamic cast becomes a static cast. -- Marco
Re: asm woes...
Am Fri, 27 May 2016 10:16:48 + schrieb Era Scarecrow: > On Friday, 27 May 2016 at 10:14:31 UTC, Era Scarecrow wrote: > > inc dword ptr [EAX+Foo.x.offsetof]; > > > So just tested it, and it didn't hang, meaning all unittests > also passed. > > Final solution is: > >asm pure @nogc nothrow { > mov EAX, this; > add dword ptr [EAX+wideIntImpl.lo.offsetof], 1; > adc dword ptr [EAX+wideIntImpl.lo.offsetof+4], 0; > adc dword ptr [EAX+wideIntImpl.hi.offsetof], 0; > adc dword ptr [EAX+wideIntImpl.hi.offsetof+4], 0; >} The 'this' pointer is usually in some register already. On Linux 32-bit for example it is in EAX, on Linux 64-bit is in RDI. What DMD does when it encounters an asm block is, it stores every parameter (including the implicit this) on the stack and when you do "mov EAX, this;" it loads it back from there using EBP as the base pointer to the stack variables. The boilerplate will look like this on 32-bit Linux: push EBP // Save what's currently in EBP movEBP,ESP // Remember current stack pointer as base for variables push EAX // Save implicit 'this' parameter on the stack movEAX,DWORD PTR [EBP-0x4] // Load 'this' into EAX as you requested movESP,EBP // Restore stack to what it was before saving parameters and variables popEBP // Restore EBP register ret// Return from function Remember that this works only for x86 32-bit in DMD and LDC. GDC passes inline asm right through to an arbitrary external assembler after doing some template replacements. It will not understand any of the asm you feed it, but forward the external assemblers error messages. On the other hand GDC's and LDC's extended assemblers free you from manually loading stuff into registers. You just use a placeholder and tell the compiler to put 'this' into some register. The compiler will realize it is already in EAX or RDI and do nothing but use that register instead of EAX in your code above. Sometimes that has the additional benefit that the same asm code works on both 32-bit and 64-bit. Also, extended asm is transparent to the optimizer. The code can be inlined and already loaded variables reused. By the way, you are right that 32-bit does not have access to 64-bit machine words (actually kind of obvious), but your idea wasn't far fetched, since there is the X32 architecture at least for Linux. It uses 64-bit machine words, but 32-bit pointers and allows for compact and fast programs. -- Marco
Re: asm woes...
Am Fri, 27 May 2016 10:06:28 + schrieb Guillaume Piolat: > Referencing EBP or ESP yourself is indeed dangerous. Not sure why > the documentation would advise that. Using "this", names of > parameters/locals/field offset is much safer. DMD makes sure that the EBP relative access of parameters and stack variables works by copying everything to the stack that's in registers when you have an asm block in the function. Using var[EBP] or just plain var will then dereference that memory location. -- Marco
Re: Is there an easy way to convert a pointer to malloc'd memory to an array?
Am Tue, 24 May 2016 20:58:14 + schrieb Gary Willoughby: > On Tuesday, 24 May 2016 at 18:43:22 UTC, Adam D. Ruppe wrote: > > On Tuesday, 24 May 2016 at 18:42:41 UTC, Gary Willoughby wrote: > >> I have a T* pointer to the start of a malloc'd chunk of > >> memory, the type T and the number of T's stored in the chunk. > >> > >> Is there an efficient way of converting this information to a > >> D array of type T[] or even T[n]? > > > > Slice it: > > > > T[] = t[0 .. n]; > > That! ...is amazing! How did you _ever_ read structs from files without this knowledge? -- Marco
Re: Formatted Output: Exact number of Decimal Places
Am Mon, 16 May 2016 20:24:51 + schrieb Q. Schroll: > Lets say I want to print a table with floats. How can it be > formatted like that: > | 2.4 | > | 12.2 | > | 8.131 | > | 17.44 | > Also acceptable is > | 2.400 | > | 12.200 | > | 8.131 | > | 17.440 | Use %#6.3f to get the above output. > but not > | 02.4 | > | 12.2 | > | 08.131 | > | 17.44 | > or any other solutions with leading zeros. -- Marco
Re: inferred size for static array initialization
Am Mon, 2 May 2016 18:52:11 +0200 schrieb ag0aep6g <anonym...@example.com>: > On 02.05.2016 15:53, Marco Leise wrote: > >immutable tab = { static enum S[] s = [ > > `static enum`? What kind of black magic is this? I don't know, but it works, haha. -- Marco
Re: inferred size for static array initialization
Am Mon, 02 May 2016 13:00:27 + schrieb Erik Smith: > Is there a way to initialize a static array and have it's size > inferred (and that works for arrays of structs using braced > literals)? This would make it easier to maintain longer static > array definitions. The code below doesn't work when removing the > array size even though the array is declared as static immutable. > > import std.traits; > static immutable int[] a = [1,2,3]; > static assert(isStaticArray!(typeof(a))); // fails > Sure, struct S { int a, b; } immutable tab = { static enum S[] s = [ {1,2}, {3,4}, ]; return cast(typeof(s[0])[s.length])s; }(); static assert(isStaticArray!(typeof(tab))); // succeeds -- Marco
Re: Garbage Collector : Ignoring a reference
Am Tue, 26 Apr 2016 13:35:37 + schrieb Begah: > When the screen switches to another screen ie from menu to the > game, > I want that the "button.png" texture is automaticly destroyed by > the gc. My ideological point of view is that you must not use non-deterministic garbage collection for resources. Neither for files, GUI widgets or textures. The garbage collector cannot look past its own confined environment (heap memory allocated by the D program and loaded D libraries) and will not have enough information to tell if the process is running out of file handles, backing buffer for widgets or texture memory on the graphics card. It only takes action, when its own heap is filling up or when you manually call GC.collect(). All the convenient 100% GC languages from Java to Python require the user to call ".close()" for files, ".dispose()/.Destroy()" for widgets, etc. Reference counting is the correct approach. It makes using external resources safe and convenient by removing the need for manual lifetime management. Cyclic references cannot exist in the D code in this scenario. The texture constructor: - sets ref count to 1 - adds texture to hash map The copy constructor: - increments the ref count The destructor: - decrements the ref count - if ref count reaches 0: - removes the texture from the hash table - destroys the texture data -- Marco
Re: Adding a float with all four elements of a float4
Am Thu, 21 Apr 2016 00:14:53 + schrieb Straivers: > Hi, > > I want to make a utility wrapper around a core.simd.float4, and > have been trying to make the following code work, but have been > met with no success. > > auto add(float rhs) > { > return __simd(XMM.ADDPS, lhs, rhs); > } It seems like your are duplicating std.simd: https://github.com/TurkeyMan/simd -- Marco
Re: char array weirdness
Am Mon, 28 Mar 2016 16:29:50 -0700 schrieb "H. S. Teoh via Digitalmars-d-learn": > […] your diacritics may get randomly reattached to > stuff they weren't originally attached to, or you may end up with wrong > sequences of Unicode code points (e.g. diacritics not attached to any > grapheme). Using filter() on Korean text, even with autodecoding, will > pretty much produce garbage. And so on. I'm on the same page here. If it ain't ASCII parsable, you *have* to make a conscious decision about whether you need code units or graphemes. I've yet to find out about the use cases for auto-decoded code-points though. > So in short, we're paying a performance cost for something that's only > arguably better but still not quite there, and this cost is attached to > almost *everything* you do with strings, regardless of whether you need > to (e.g., when you know you're dealing with pure ASCII data). An unconscious decision made by the library that yields the least likely intended and expected result? Let me think ... mhhh ... that's worse than iterating by char. No talking back :p. -- Marco
Re: How to be more careful about null pointers?
Am Tue, 29 Mar 2016 06:00:32 + schrieb cy: > struct Database { >string derp; >Statement prepare(string s) { > return Statement(1234); >} > } > > struct Statement { >int member; >void bind(int column, int value) { > import std.stdio; > writeln("derp",member); >} > > } > > > class Wrapper { >Database something; >Statement prep; >this() { > something = Database("..."); > prep = something.prepare("..."); >} > } > > Wrapper oops; > void initialize() { >oops = new Wrapper(); > } > > class Entry { >Wrapper parent; >this(Wrapper parent) { > //this.parent = parent; > //oops > parent = parent; >} >void usefulmethod() { > parent.prep.bind(1,42); > //parent.prep.execute(); > //parent.prep.reset(); >} > } > > void main() { >initialize(); >auto entry = new Entry(oops); >entry.usefulmethod(); > } > > That program causes a segmentation fault on my machine. Somehow > despite never initializing Entry.parent, a class object (whose > default init is a null pointer), I can still call methods on it, > access members on it, and call methods on those members. No > warnings or errors. The segfault doesn't happen until the bind() > method. Dlang aborts programs that run into invalid states. Common invalid states are failing contract assertions, out of memory conditions or in this case a null-pointer dereference. When designing Dlang, Walter decided that null pointers don't require checks as the operating system will eventually abort the program and debuggers are designed to assist you in this situation. Some people with a different programming background feel that a modern language should wrap every pointer access in a check and possibly throw a recoverable Exception here or make null-pointer opt-in to begin with. The topic is still open for discussion: http://wiki.dlang.org/Language_issues#Null_References -- Marco
Re: I need some help benchmarking SoA vs AoS
Am Sat, 26 Mar 2016 17:43:48 + schrieb maik klein: > On Saturday, 26 March 2016 at 17:06:39 UTC, ag0aep6g wrote: > > On 26.03.2016 18:04, ag0aep6g wrote: > >> https://gist.github.com/aG0aep6G/a1b87df1ac5930870ffe/revisions > > > > PS: Those enforces are for a size of 100_000 not 1_000_000, > > because I'm impatient. > > Thanks, okay that gives me more more reliable results. > for 1_000_000 > > benchmarking complete access > AoS: 1 sec, 87 ms, 266 μs, and 4 hnsecs > SoA: 1 sec, 491 ms, 186 μs, and 6 hnsecs > benchmarking partial access > AoS: 7 secs, 167 ms, 635 μs, and 8 hnsecs > SoA: 1 sec, 20 ms, 573 μs, and 1 hnsec > > This is sort of what I expected. I will do a few more benchmarks > now. I probably also randomize the inputs. That looks more like it. :) There is a few things to keep in mind. When you use constant data and don't use the result compilers can: - Const-fold computations away. - Specialize functions on compile-time known arguments. That works mostly as if the argument was a template argument. A new instance of the function is created for each invokation with a compile-time known value. (Disabling inlining wont prevent this.) - Call pure functions with the same argument only once in a loop of 1_000_000. - Replace 1_000_000 additions of the number X in a loop with the expression 1_000_000*X. In addition to these real-world optimizations, when you don't accumulate the result of the function call and print it or store it in some global variable, the whole computation may be removed as "no side-effect", as others have pointed out. When inlining is used the compiler may also see through attempts to only use a part of the result and remove instructions that lead to the rest of it. For example when you return a struct with two fields - a and b - and store the sum of a, but ignore b, then the compiler may remove computations that are only needed for b! Try to generate input from random number generators or external files. Disable inlining for the benchmarked function via attribute or pragma(inline, false) or otherwise make sure that the compiler cannot guess what any of the arguments are and perform const-folding after inlining. When the result is returned, make sure you use so much of it, that the compiler cannot elide instructions after inlining. It is often enough to just store it in a global variable. -- Marco
Re: If stdout is __gshared, why does this throw / crash?
Got it now: https://issues.dlang.org/show_bug.cgi?id=15768 writeln() creates a copy of the stdout struct in a non thread-safe way. If stdout has been assigned a File struct created from a file name this copy includes a "racy" increment/decrement of a reference count to the underlying C-library FILE*. In the case that the reference count is erroneously reaching 0, the file is closed prematurely and when Glibc tries to access internal data it results in the observable SIGSEGV. -- Marco
Re: If stdout is __gshared, why does this throw / crash?
Am Sat, 05 Mar 2016 14:18:31 + schrieb Atila Neves: > void main() { > stdout = File("/dev/null", "w"); > foreach(t; 1000.iota.parallel) { > writeln("Oops"); > } > } First thing I tried: void main() { stdout = File("/dev/null", "w"); foreach(t; 1000.iota.parallel) { stdout.writeln("Oops"); } } That does NOT segfault ... hmm. -- Marco
Re: Backslash escaping weirdness
Am Tue, 01 Mar 2016 05:14:13 + schrieb Nicholas Wilson: > On Tuesday, 1 March 2016 at 04:48:01 UTC, Adam D. Ruppe wrote: > > On Tuesday, 1 March 2016 at 04:18:11 UTC, Nicholas Wilson wrote: > >> What is causing these errors? I'm using \t and \n in string > >> all over the place and they work. > > > > I don't think there's enough context to know for sure... but my > > guess is you forgot to close one of the quotes a couple lines > > above. > > > > So look up for an unpaired " > > It was. Thanks. And then God created syntax highlighting and He saw that it was good. ;) -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Tue, 09 Feb 2016 00:38:10 + schrieb tsbockman <thomas.bock...@gmail.com>: > On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote: > > What I like most about your proposal is that it doesn't break > > any existing code that wasn't broken before. That can't be > > emphasized enough. > > Although I wish more than 3 people had voted in my poll, two of > them did claim to need the `ref`-ness of `Tuple.slice`, so I > don't think we can just ditch it. (I did not vote.) > > If you guys want to add a return-by-value version, it should be > treated as an enhancement, not a bug fix in my opinion. As mentioned I never used the feature myself and wont vote for one or the other. Three people with no source code to exemplify current use of .slice! is indeed not much to base decisions on and both fixes yield unexpected results in different contexts that warrant bug reports. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 11:02:37 + schrieb tsbockman: > On Saturday, 6 February 2016 at 08:47:01 UTC, Saurabh Das wrote: > > I think we should add a static assert to slice to ensure that > > the current implementation is not used in a case where the > > alignment doesn't match. This is better than failing without > > any warning. > > If we pursue the deprecation route, I agree that this is a > necessary step. That would hurt the least, yes. It's more like a .dup with start and end parameter then. > > We could add new (differently named) functions for slicing > > non-aligned tuples. > > > > I agree that my approach of removing the ref may break existing > > code, so if introduced, it should be named differently. > > > > I am not comfortable with tuple(42, true, "abc").slice(1, 3) > > being different in type from tuple(true, " abc"). > > Why? What practical problem does this cause? For me it is mostly a gut feeling. Historically types mimicking other types have often evoked trouble for example in generic functions or concretely - if you look at my other post - in D's AA implementation. -- Marco
Re: Things that keep D from evolving?
Am Sat, 06 Feb 2016 11:47:02 + schrieb Ola Fosheim Grøstad: > Of course, Swift does not aim for very high performance, but for > convenient application/gui development. And frankly JavaScript is > fast enough for that kind of programming. My code would not see much ref counting in performance critical loops. There is no point in ref counting every single point in a complex 3D scene. I could imagine it used on bigger items. Textures for example since they may be used by several objects. Or - a prime example - any outside resource that is potentially scarce and benefits from deterministic release: file handles, audio buffers, widgets, ... -- Marco
Re: Things that keep D from evolving?
Am Sat, 06 Feb 2016 23:18:59 + schrieb Ola Fosheim Grøstad: > Things that could speed up collection: > - drop destructors so you don't track dead objects Interesting, that would also finally force external resources off the GC heap and into deterministic release. That needs a solution to inheritance though. Think widget kits. -- Marco
Re: Custom hash table key is const, how to call dtors?
Am Sun, 07 Feb 2016 01:05:28 + schrieb cy <dl...@verge.info.tm>: > On Saturday, 6 February 2016 at 03:57:16 UTC, Marco Leise wrote: > > > No, but they could have dtors because they contain malloc'd > > data. E.g. string literals that don't live on the GC heap. > > Character arrays allocated with glibc malloc are immutable? News > to me... err... well... you got a point there, but then new string(100) is probably allocated with malloc, too deep down in druntime. immutable really means that there is no mutable reference to the data. At any point in your code you can cast something to immutable when you that no mutable references will exist thereafter. We do this all the time during construction of immutable stuff, because when something is newly created, there is only one unique reference that is turned immutable after construction and you are set. You can go the same route with other MM schemes such as malloc, just that without a GC you are responsible for not freeing the immutable data as long as there are references to it. For example (and this applies to Ds GC'd AA, too) you must not delete entries while you iterate over the keys. There is no way to say "Hey I just borrowed the list of keys, please disallow any writes to it." For now, issues related to dtor-constness need to be fixed. Then working with immutable data structures is a lot less of a mine field. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 07:57:08 + schrieb tsbockman <thomas.bock...@gmail.com>: > On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote: > > I don't want to sound dismissive, but when that thought came > > to my mind I considered it unacceptable that the type of > > Tuple!(int, bool, string).slice(1, 3) would be something > > different than Tuple!(bool, string). In your case > > Tuple!(TuplePad!4LU, bool, string). That's just a matter of > > least surprise when comparing the types. > > > > I'll let others decide, since I never used tuple slices. > > I'm not sure which approach is ultimately better, but aside from > the performance implications, your "needed change" could break a > lot of valid code in the wild - or it might break none; it really > just depends on whether anyone actually *uses* the `ref`-ness of > the `Tuple.slice` return type. True. > (It appears that Phobos, at least, does not. But there is no > guarantee that the rest of the world is using `Tuple` only in the > ways that Phobos does.) > Leaving aside bizarre meta-programming stuff (because then > *anything* is a breaking change), my PR does not break any code, > except that which was already broken: the type of the slice is > only different in those cases where it *has* to be, for alignment > reasons; otherwise it remains the same as it was before. I understand that. We just have a different perspective on the problem. Your priorities: - don't break what's not broken - .slice! lends on opSlice and should return by ref My priorities: - type of .slice! should be as if constructing with same values from scratch - keep code additions in Phobos to a minimum Why do I insist on the return type? Because surprisingly simple code breaks if it doesn't match. Not everything can be covered by runtime conversions in D. It still took me a while to come up with something obvious: uint[Tuple!(uint, ulong)] hash; auto tup = tuple(1u, 2u, 3UL); hash[tup.slice!(1, 3)] = tup[0]; compiles? works? original Tuple : yesno Saurabh Das changes: yesyes your changes : no no What I like most about your proposal is that it doesn't break any existing code that wasn't broken before. That can't be emphasized enough. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Sat, 06 Feb 2016 04:28:17 + schrieb tsbockman <thomas.bock...@gmail.com>: > On Friday, 5 February 2016 at 19:16:11 UTC, Marco Leise wrote: > >> > 1. Removing 'ref' from the return type > > > > Must happen. 'ref' only worked because of the reinterpreting > > cast which doesn't work in general. This will change the > > semantics. Now the caller of 'slice' will deal with a whole new > > copy of everything in the returned slice instead of a narrower > > view into the original data. But that's a needed change to fix > > the bug. > > Actually, it's not: > https://github.com/D-Programming-Language/phobos/pull/3973 > > All that is required is to include a little padding at the > beginning of the slice struct to make the alignments match. I don't want to sound dismissive, but when that thought came to my mind I considered it unacceptable that the type of Tuple!(int, bool, string).slice(1, 3) would be something different than Tuple!(bool, string). In your case Tuple!(TuplePad!4LU, bool, string). That's just a matter of least surprise when comparing the types. I'll let others decide, since I never used tuple slices. -- Marco
Re: Template to create a type and instantiate it
Mixin templates is the way to go if you want something new on every use of the template. Otherwise using the template multiple times with the same arguments will always give you the first instance. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Fri, 05 Feb 2016 05:31:15 + schrieb Saurabh Das: > On Friday, 5 February 2016 at 05:18:01 UTC, Saurabh Das wrote: > [...] > > Apologies for spamming. This is an improved implementation: > > @property > Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t > to)() @safe const > if (from <= to && to <= Types.length) > { > return typeof(return)(field[from .. to]); > } > > /// > unittest > { > Tuple!(int, string, float, double) a; > a[1] = "abc"; > a[2] = 4.5; > auto s = a.slice!(1, 3); > static assert(is(typeof(s) == Tuple!(string, float))); > assert(s[0] == "abc" && s[1] == 4.5); > > Tuple!(int, int, long) b; > b[1] = 42; > b[2] = 101; > auto t = b.slice!(1, 3); > static assert(is(typeof(t) == Tuple!(int, long))); > assert(t[0] == 42 && t[1] == 101); > } That's quite concise. I like this. Though 'field' is now called 'expand': // backwards compatibility alias field = expand; > These questions still remain: > > 1. Removing 'ref' from the return type Must happen. 'ref' only worked because of the reinterpreting cast which doesn't work in general. This will change the semantics. Now the caller of 'slice' will deal with a whole new copy of everything in the returned slice instead of a narrower view into the original data. But that's a needed change to fix the bug. > > 2. Adding 'const' to the function signature Hmm. Since const is transitive this may add const to stuff that wasn't const, like in a Tuple!(Object). When you call const slice on that, you would get a Tuple!(const(Object)). I would use inout, making it so that the tuple's original constness is propagated to the result. I.e.: @property inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)() @safe inout > > 3. Is the new implementation less efficient for correctly > > aligned tuples? Yes, the previous one just added a compile-time known offset to the "this"-pointer. That's _one_ assembly instruction after inlining and optimization. The new one makes a copy of every field. On struct fields this can call the copy constructor "this(this)" which is used for example in reference counting to preform an increment for the copy. On "plain old data" it would simply copy the bit patterns. But that's obviously still less efficient than adding an offset to the pointer. You need two methods if you want to offer the best of both worlds. As soon as your function does not return a pointer or has 'ref' on it, the compiler will provide memory on the stack to hold the result and a copy will occur. That said, sufficiently smart compilers can analyze what's happening and come to the conclusion that when after the copy, the original is no longer used, they can be merged. > 4. @trusted -> @safe? Sounds good, but be aware of the mentioned implications with "this(this)". Copy constructors often need to do unsafe things, so @safe here would disallow them in Tuples. On the other hand recent versions of the front-end should infer attributes for templates, so you can generally omit them and "let the Tuple decide". This mechanism also already adds @nogc, pure, nothrow as possible in both the original and your implementation. (The original code only had @trusted on it because the compiler would always infer the safety as @system due to the pointer casts and @system is close to intolerable for a "high-level" functional programming feature such as tuples. The other attributes should have been inferred correctly.) -- Marco
Custom hash table key is const, how to call dtors?
Usually I want the keys to be declared "immutable" to signal that their content must not change in order to provide stable hashes. But when you remove items from the table you need to call a const/immutable dtor that needs to be written for everything that can be a hash table key. What do you put into such a const/immutable dtor? How do others deal with this? -- Marco
Re: Custom hash table key is const, how to call dtors?
Am Sat, 06 Feb 2016 03:38:54 + schrieb cy <dl...@verge.info.tm>: > On Friday, 5 February 2016 at 22:18:50 UTC, Marco Leise wrote: > > But when you remove items from the table you need to call a > > const/immutable dtor that needs to be written for everything > > that can be a hash table key. > > You need to write destructors for hash keys? How would you use > string literals as keys then? Could you provide an example > maybe...? No, but they could have dtors because they contain malloc'd data. E.g. string literals that don't live on the GC heap. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
https://issues.dlang.org/show_bug.cgi?id=15645
Re: Octree implementation?
Am Mon, 01 Feb 2016 02:56:06 + schrieb Tofu Ninja: > Just out of curiosity, does anyone have an octree implementation > for D laying around? Just looking to save some time. I have one written in Delphi that you could prune till it fits. -- Marco
Re: Is this a bug in std.typecons.Tuple.slice?
Am Thu, 04 Feb 2016 15:17:54 + schrieb Saurabh Das: > On Thursday, 4 February 2016 at 12:28:39 UTC, Saurabh Das wrote: > > This code: > > [...] > > Update: Simplified, this also doesn't work: > > void main() > { > import std.typecons; > auto tp = tuple(10, false, "hello"); > > auto u0 = tp.slice!(0, tp.length); > auto u1 = tp.slice!(1, tp.length); > auto u2 = tp.slice!(2, tp.length); > > static assert(is(typeof(u0) == Tuple!(int, bool, string))); > static assert(is(typeof(u1) == Tuple!(bool, string))); > static assert(is(typeof(u2) == Tuple!(string))); > > assert(u2[0] == "hello"); > assert(u0[2] == "hello"); > assert(u1[1] == "hello");// This fails > } > > rdmd erasetype.d > core.exception.AssertError@erasetype.d(16): Assertion failure > > Any ideas? Yes this is a clear bug, I'll report a bug and post the issue number later. -- Marco
Re: Something about Chinese Disorder Code
Am Tue, 24 Nov 2015 17:08:33 + schrieb BLM768: > On Tuesday, 24 November 2015 at 09:48:45 UTC, magicdmer wrote: > > I display chinese string like: > > > > auto str = "你好,世界" > > writeln(str) > > > > and The display is garbled。 > > > > some windows api like MessageBoxA ,if string is chinese, it > > displays disorder code too > > > > i think i must use WideCharToMultiByte to convert it , is there > > any other answer to solve this question simplely > > You can also try using a wide string literal, i.e. "你好,世界"w. The > suffix forces the string to use 16-bit characters. > > The garbled display from writeln might be related to your console > settings. If you aren't using the UTF-8 codepage in cmd.exe, that > would explain why the text appears garbled. Unfortunately, > Windows has some significant bugs with UTF-8 in the console. This is really our problem. We pretend the output terminal is UTF-8 without providing any means to configure the terminal or converting the output to the terminal's encoding. All OSs provide conversion API that works for the most part (assuming normalization form D for example), but we just don't use them. Most contributers were on Linux or English Windows system where the issue is not obvious. But even in Europe łáö will come out garbled. Now this is mostly not an issue with modern Linux and OS X as the default is UTF-8, but some people refuse to change to variable length encodings and Windows has always been preferring fixed length encodings. The proper way to solve this for the OP in a cross-platform way is to replace writeln with something that detects whether the output is a terminal and then converts the string to something that will display correctly, which can be a simple wchar[] on Windows or the use of iconv on Linux. Ketmar is currently using iconv to print D string on his Linux set up for Cyrillic KIO-8U and I think I used it in some code as well. It is not perfect, but will make most printable strings readable. ICU I think is the only library that gets it 100% correct with regards to normalization and offering you different error concealment methods. -- Marco
Re: Implicit conversion rules
Am Wed, 21 Oct 2015 12:49:35 -0700 schrieb Ali Çehreli: > On 10/21/2015 12:37 PM, Sigg wrote: > > > cause at least few more "fun" side effects. > > One of those side effects would be function calls binding silently to > another overload: > > void foo(bool){/* ... */} > void foo(int) {/* ... */} > >auto a = 0; // If the type were deduced by the value, >foo(a); // then this would be a call to foo(bool)... > // until someone changed the value to 2. :) > > Ali God forbid anyone implement such nonsense into D ! That would be the last thing we need that we cannot rely on the overload resolution any more. It would be as if making 'a' const would change the overload resolution when none of the overloads deal with constness... import std.format; import std.stdio; string foo(bool b) { return format("That's a boolean %s!", b); } string foo(uint u) { return format("Thats an integral %s!", u); } void main() { int a = 2497420, b = 2497419; const int c = 2497420, d = 2497419; writeln(foo(a-b)); writeln(foo(c-d)); writeln("WAT?!"); } -- Marco
Re: [sdc] linker problems when building programs with sdc
Am Sun, 18 Oct 2015 11:35:16 +0200 schrieb Joseph Rushton Wakeling via Digitalmars-d-learn: > Hello all, > > I recently decided to have another play with sdc to see how it's doing. > Since > my dmd is installed in /opt/dmd/ I had to do a couple of tricks to get sdc > itself to build: > > (i) put a dlang.conf in /etc/ld.so.conf.d/ containing the /opt/dmd/lib64 path; > > (ii) call 'make LD_PATH=/opt/dmd/lib64' when building sdc > > sdc itself then builds successfully, and I wind up with a bin/ directory > containing sdc and sdc.conf (which contains includePath and libPath options) > and > a lib/ directory containing libd.a, libd-llvm.a, libphobos.a and libsdrt.a. > > However, when I try to build any program, even a simple hello-world, I get a > linker error: > > $ ./sdc hello.d > hello.o: In function `_D5hello4mainFMZv': > hello.d:(.text+0x1c): undefined reference to `_D3std5stdio7writelnFMAyaZv' > collect2: error: ld returned 1 exit status > > To solve this, I tried adding in a library-path flag, but this simply > resulted > in an exception being thrown by sdc's options parsing: > > $ ./sdc -L$MYHOMEDIR/code/D/sdc/lib hello.d > std.getopt.GetOptException@/opt/dmd/bin/../import/std/getopt.d(604): > Unrecognized option -L$MYHOMEDIR/code/D/sdc/lib > > [cut great big backtrace] > > Can anyone advise what's missing in my setup? I did also try adding > $MYHOMEDIR/code/D/sdc/lib to the /etc/ld.so.conf.d/dlang.conf file, and > re-running ldconfig, but that didn't seem to make any difference. > > Thanks & best wishes, > > -- Joe Maybe you should have started with `return 42;`? :D writeln is not a light-weight in terms of exercised compiler features. I didn't even know that it compiles yet. Last time I heard it was not usable. -- Marco
Re: How to check if JSONValue of type object has a key?
Am Tue, 06 Oct 2015 21:39:28 + schrieb Fusxfaranto: > Additionally, just like associative arrays, if you need to access > the value, you can get a pointer to it with the in operator (and > if the key doesn't exist, it will return a null pointer). > > const(JSONValue)* p = "key" in root; > if (p) > { > // key exists, do something with p or *p > } > else > { > // key does not exist > } And you could go further and write if (auto p = "key" in root) { // key exists, do something with p or *p } else { // key does not exist } -- Marco
Re: __simd_sto confusion
This is a bug in overload resolution when __vector(void[16]) is involved. You can go around it by changing float4 to void16, only to run into an internal compiler error: backend/gother.c 988 So file a bug for both @ issues.dlang.org Also it looks like DMD wants you to use the return value of the intrinsic, is that expected? -- Marco
Re: __simd_sto confusion
Am Sat, 03 Oct 2015 23:42:22 + schrieb Nachtraaf: > I changed the type of result to void16 like this: > > float dot_simd1(float4 a, float4 b) > { > void16 result = __simd(XMM.DPPS, a, b, 0xFF); > float value; > __simd_sto(XMM.STOSS, value, result); > return value; > } > > and for me this code compiles and runs without any errors now. > I'm using DMD64 D Compiler v2.068 on Linux. If you got an > internal compiler error that means that it's a compiler bug > though I have no clue what. Did you try the same thing I did or > casting the variable? > I guess I should file a bugreport for overload resolution if it's > not a duplicate for now? Yes. At some point the intrinsics will need a more thorough rework. Currently none of those that return void, int or set flags work as they should. -- Marco
Re: Mac IDE with Intellisense
Am Sat, 26 Sep 2015 10:38:25 + schrieb Gary Willoughby: > Auto-complete in D is tricky because of this feature and no-one > has invested any time to figure out a nice way to provide > auto-complete for this. Mono-D does have UFCS auto-complete. The plugin is going to bit-rot though, since its only developer is done studying. -- Marco
Re: WTF does "Enforcement failed" actually mean?
Am Thu, 01 Oct 2015 08:52:43 + schrieb John Colvin: > On Thursday, 1 October 2015 at 07:08:00 UTC, Russel Winder wrote: > > On Wed, 2015-09-30 at 23:35 -0700, Ali Çehreli via > > Digitalmars-d-learn wrote: > >> On 09/30/2015 10:46 PM, Russel Winder via Digitalmars-d-learn > >> wrote: > >> > [...] > >> > >> It's coming from the following no-message enforce(): > >> > >> enforce(!r.empty); > >> > >> > >> https://github.com/D-Programming-Language/phobos/blob/master/std/algo > >> rithm/iteration.d#L2481 > >> > >> You are using the no-seed version of reduce(), which uses the > >> first element as seed, which means that the range cannot be > >> empty. > > > > Well that explanation (*) makes it abundantly clear that the > > error reporting from this part of Phobos is distinctly > > substandard, let alone below par. > > > > > > (*) Which is clear and informative! > > Bug report? Then it'll get fixed. The problem is that in out minds addition has an implicit seed value of 0 and multiplication has 1, so a potentially empty range doesn't immediately raise a red flag. The correct thing to use, following this train of thought, is http://dlang.org/phobos/std_algorithm_iteration.html#.sum (Additionally it provides better accuracy when summing up floating-point values.) -- Marco
Re: Interval Arithmetic
Am Tue, 29 Sep 2015 21:04:00 + schrieb Wulfrick: > Is there an interval arithmetic library in D? I couldn’t find one. > > In case I had to write my own, I understand that the IEEE > standard floating point arithmetic provides operations for > rounding up or down certain operations like summing, subtracting, > etc. (thus overriding the default behavior of rounding to nearest > representable). > > How do I access this functionality in D? At first I thought that > std.math.nextDown and nextUp is what I needed, but not so. > Apparently these functions return the previous or next > representable *after* the calculation has been done. > > For example, I would like the value of x+y rounded in the > arithmetic towards -\infty, which may or may not be nextDown(x+y). > > Any luck? > Thanks for reading! Yes, Phobos provides you with this thing: http://dlang.org/phobos/std_math.html#.FloatingPointControl Read the help carefully. End of the scope generally means "}". You can also use the C standard library from D and use: http://www.cplusplus.com/reference/cfenv/fesetround/ import core.stdc.fenv; fesetround( FE_DOWNWARD ); auto z = x + y; And if all that still isn't enough you can write it in inline assembler using the `fldcw` mnemonic. Note that the FP control word is per thread and any external code you call or even buggy interrupt handlers could change or reset it to defaults. Known cases include a faulty printer driver and Delphi's runtime, which enables FP exceptions to throw exceptions on division by 0. Just saying this so if it ever happens you have it in the back of your mind. Against interrupt handlers you probably cannot protect, but when calling other people's code it would be best not depend on what the FP control word is set to on return. `FloatingPointControl` is nice here, because you can temporarily set the rounding mode directly for a block of FP instructions where no external libraries are involved. -- Marco
Re: Interval Arithmetic
Am Thu, 01 Oct 2015 12:03:10 + schrieb ponce: > I have a RAII struct to save/restore the FP control word. > It also handle the SSE control word which unfortunately exist. > > https://github.com/p0nce/dplug/blob/master/plugin/dplug/plugin/fpcontrol.d Nice to have in Phobos. I assume you have to set the correct control word depending on whether you perform math on the FPU or via SSE (as is standard for x86_64)? And I assume further that DMD always uses FPU math and other compilers provide flags to switch between FPU and SSE? -- Marco
Re: final class & final methods
Am Fri, 25 Sep 2015 10:28:54 + schrieb ref2401: > If I declare a class as `final` do I have to mark all methods of > the class as `final` too? No. -- Marco
Re: Why does reverse also flips my other dynamic array?
Thanks for the clarification.
Re: Why does reverse also flips my other dynamic array?
Am Sat, 12 Sep 2015 10:55:50 + schrieb "Namal": > > Why is also b flipped here? This doesn't happen if I use static > > arrays. > > nvm. I need to .dup that. Correct, static arrays are value types and copied on assignment. Dynamic arrays on the other hand are generally slices of memory on the garbage collected heap represented by just a pointer to the first element and a length. When you assign those you only get a second reference to the same data. Note that often the original dynamic array has additional capacity beyond its length. This can be used to ~= additional items without causing a reallocation, but is lost when you do the assignment "b = a". (This is so you can't accidentally append different items to both a and b and have them overwrite each other.) You can query the actual capacity with a.capacity. Just felt like writing down some knowledge you might need along the way. :) -- Marco
Re: Utf8 to Utf32 cast cost
Am Mon, 8 Jun 2015 12:59:31 +0200 schrieb Daniel Kozák via Digitalmars-d-learn digitalmars-d-learn@puremagic.com: On Mon, 08 Jun 2015 10:41:59 + Kadir Erdem Demir via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: I want to use my char array with awesome, cool std.algorithm functions. Since many of this algorithms requires like slicing etc.. I prefer to create my string with Utf32 chars. But by default all strings literals are Utf8 for performance. With my current knowledge I use to!dhar to convert Utf8[](or char[]) to Utf32[](or dchar[]) dchar[] range = to!dchar(erdem.dup) How costly is this? import std.conv; import std.utf; import std.datetime; import std.stdio; void f0() { string somestr = some not so long utf8 string forbenchmarking; dstring str = to!dstring(somestr); } void f1() { string somestr = some not so long utf8 string forbenchmarking; dstring str = toUTF32(somestr); } void main() { auto r = benchmark!(f0,f1)(1_000_000); auto f0Result = to!Duration(r[0]); auto f1Result = to!Duration(r[1]); writeln(f0 time: ,f0Result); writeln(f1 time: ,f1Result); } /// output /// f0 time: 2 secs, 281 ms, 933 μs, and 8 hnsecs f1 time: 600 ms, 979 μs, and 8 hnsecs Please have the result of the transcode influence the program output. E.g. Add the first character of the UTF32 string to some global variable and print it out. At the moment - at least in theory - you allow the compiler to deduce f0/f1 as pure, return-nothing functions and you will benchmark anything from your written code to an empty loop. I'm talking out of experience here: https://github.com/mleise/fast/blob/master/source/fast/internal.d#L99 -- Marco
Re: Utf8 to Utf32 cast cost
Am Mon, 08 Jun 2015 11:13:25 + schrieb Daniel Kozak kozz...@gmail.com: BTW on ldc(ldc -O3 -singleobj -release -boundscheck=off) transcode is the fastest: f0 time: 1 sec, 115 ms, 48 μs, and 7 hnsecs // to!dstring f1 time: 449 ms and 329 μs // toUTF32 f2 time: 272 ms, 969 μs, and 1 hnsec // transcode Three functions, each twice as fast and twice as hidden as the one before. :) -- Marco
Re: Convert C array pointer to a D slice without data copy
Am Mon, 18 May 2015 09:51:48 + schrieb John Colvin john.loughran.col...@gmail.com: No need to worry about the GC here, it only scans the stack and its own heap (unless you specifically add a new root). And even if you add a root it wont free anything it did not allocate itself! You could even append to your C array. It will check how much capacity the slice still has on the GC heap and after realizing the .ptr is not even in one of its pools, allocate a GC copy of the C array right away. -- Marco
Re: 'const' and 'in' parameter storage classes
Am Mon, 18 May 2015 09:05:51 -0400 schrieb Steven Schveighoffer schvei...@yahoo.com: On 5/15/15 2:19 PM, ref2401 wrote: On Friday, 15 May 2015 at 16:30:29 UTC, Steven Schveighoffer wrote: On 5/15/15 12:04 PM, ref2401 wrote: What is the difference between 'const' and 'in' parameter storage classes? When should I use 'const' or 'in'? The documentation says 'in' is the same as 'const scope' but I can't write 'const scope ref' though it's legal to write 'in ref'. scope ref const still getting the error: Error: scope cannot be ref or out interesting. Seems you would be right then. The only other possibility could be ref scope const, but that doesn't seem right, I'll try it. Nope, so basically there is no way to do in by expanding to scope const. This is something that should be considered if we ever want to modify what 'in' means. I am not sure yet whether in ref should be valid or scope ref should be valid either. It doesn't seem to me that it should trigger an error. -Steve Issue 8121 - scope ref is perfectly OK https://issues.dlang.org/show_bug.cgi?id=8121 -- Marco
Re: Function name from function pointer
Am Sat, 11 Apr 2015 18:28:35 + schrieb Paul D Anderson claude.re...@msnmail.com: Is there a way to return the name of a function (a string) from a pointer to that function? Function pointer example from D Reference: --- int function() fp; void test() { static int a = 7; static int foo() { return a + 3; } fp = foo; } void bar() { test(); int i = fp(); // i is set to 10 } --- Can I get foo from fp? Paul Nope, that would require that fp not only contains a pointer to the function but also a pointer to the name. That's not how it works. But continuing that thought, you could add the function's name as an additional variable and set that every time you set fp. -- Marco
Re: Is it any faster to read array slices than just elements of an array?
Am Wed, 08 Apr 2015 17:01:43 + schrieb ZILtoid1991 ziltoidtheomnic...@gmail.com: While I technically finished the 0.2 version of my graphics engine which has a reasonable speed at low internal resolutions and with only a couple of sprites, but it still gets bottlenecked a lot. First I'll throw out the top-down determination algorhythm as it requires constant memory paging (alrought it made much more sense when the engine was full OO and even slower). Instead I'll use a overwriting (bottom-up) method. It still needs constant updates and I have to remove the per sprite transparency key and use a per layer key, however it requires much less paging, and still have the ability of unbound layer numbers and sprite count with unbound sizes. I also came up with the idea of reading slices out from the graphical elements to potentially speed up the process a bit, especially as the custom bitmaps it uses are 16bit for palette operations, so per pixel read operations would waste a portion of memory bus. So should I write a method for the bitmap class which gets a line from it? (an array slice as it contains the data in a single 1D array to avoid jagged arrays on a future expansion for a scaler) And can I write an array slice at a position of an array? (to reduce writeback calls) I don't get the whole picture, but an array slice is just a pointer and a length, so it doesn't access the pixels at all. If you know you will be going over the whole scanline, by all means get an array slice (or a C style raw pointer) and process it in as big chunks as possible. For example copying with 128-bit SSE registers will be much faster than 16-bit ushorts. (SSE4 also offers a table lookup function.) Beyond that - since it is a gfx engine - why not use OpenGL and drop the palette lookup altogether ? -- Marco
Re: naked popcnt function
Am Sat, 22 Nov 2014 18:30:05 + schrieb Ad a...@fakmail.fg: Hello, I would like to write a popcnt function. This works fine ulong popcnt(ulong x) { asm { mov RAX, x ; popcnt RAX, RAX ; } } However, if I add the naked keyword ( which should improve performance? ) it doesn't work anymore and I can't figure out what change I am supposed to make ( aside from x[RBP] instead of x ) This function is going to be *heavily* used. Thanks for any help. It is long ago that I tried naked, but IIRC it strips all compiler generated code from the function and I see no 'ret' in your function. So it probably runs into whatever code lies behind that function in the executable. I would use a tool like obj2asm or objdump to check what the generated code looks like, or use a debugger that can disassemble on the fly. -- Marco
Re: Question about Vectors
Am Thu, 20 Nov 2014 20:17:31 + schrieb Charles csmith.ku2...@gmail.com: So I was reading the documentation page: http://dlang.org/simd.html and noticed what appears to be a typo: int4 v; (cast(int*)v)[3] = 2; // set 3rd element of the 4 int vector (cast(int[4])v)[3] = 2; // set 3rd element of the 4 int vector v.array[3] = 2; // set 3rd element of the 4 int vector v.ptr[3] = 2;// set 3rd element of the 4 int vector v.array[3] = 2; and v.ptr[3] = 2; set the fourth element, and not the third. As I was verifying this, I realized I had to compile it in 64 bit code. The 32 bit code produced the error SIMD vector types not supported on this platform. My test code is: void main() { import std.stdio; import core.simd; int4 v = 7; v.ptr[3] = 2; writeln(v.array[]); } Is that related to me compiling while using a 64 bit OS, or is that true of any 32 bit OS, and thus, vectors can't be used in programs intended to be run on 32 bit OSs? Thanks, Charles DMD supports SIMD only on amd64, but you can use the GDC or LDC2 compilers if you need 32-bit support for vector types. -- Marco
Does the compiler always semantically analyze everything in a project?
Specifically, when I put some code in a separately compiled lib, does that save me anything in terms of files that have to be analyzed or will dmd always go through every file that can be reached through includes ? (.di files are out of question, because they have issues) -- Marco
Re: Does the compiler always semantically analyze everything in a project?
Am Thu, 13 Nov 2014 16:54:45 + schrieb Dicebot pub...@dicebot.lv: Apart from unused templates - yes. In abscence of .di files separate compilation only affects generated object files I thought so and wonder how that will scale with large code bases. Lately I found so many bugs and shortcomings that the ice is growing thin. There's bugs with .di files, with separate compilation, with SIMD, static dtors inside templates... and no the uncertainty how D projects will scale if the module with main imports the world. It makes me want to switch to C++. :p I hope Walter's idea of full lazy evaluation can help here. -- Marco
Re: Destructor order
Am Thu, 23 Oct 2014 12:15:13 + schrieb Marc Schütz schue...@gmx.net: Yet another use case for borrowing. Cool, how does it keep the original struct alive though, if it isn't stored anywhere? Or will it error out when you attempt to use the dangling pointer to the object? -- Marco
Re: m_condition.mutex cannot be used in shared method ?
Am Sun, 19 Oct 2014 17:09:22 + schrieb Sean Kelly s...@invisibleduck.org: What really needs to happen is for everything in core.sync to be made shared. I got partway through this at one point and stopped, because it was imposing a terrible design on the classes--I had shared methods that were casting away shared and then calling the non-shared methods to do the work. The reason for this was that the transitivity of shared was preventing me from calling pthread_mutex_lock or whatever because those functions didn't take a shared pthread_mutex_t. And attempting to rewrite core.sys.posix to make the logically shared types explicitly shared had a cascading effect that made me uncomfortable. Because of this, I remain unconvinced that the semantics of the shared attribute are actually correct when applied to user-defined types. I want some kind of an I know what I'm doing label, perhaps equivalent to the mutable attribute in C++, but to exempt contained types from shared. Thank you for that honest response. The situation is really bizarre. I just tried to create a shared worker thread and there is no ctor in Thread that creates a shared instance. Is a shared constructor even meaningful? [1] If yes, what do we need it for? Can't we otherwise just implicitly and safely cast to shared _after_ the constructor ran when we write `new shared(Foo)(...)`? Casting away shared is not @safe. Since this is normal to do in synchronized blocks, I figure the whole core.Thread and core.sync.xxx family are @system functionality ? [1] (Note that I created a PR for DMD that disables shared destruction: https://github.com/D-Programming-Language/dmd/pull/4072) -- Marco
Re: Runtime execution
Am Sun, 19 Oct 2014 06:55:17 + schrieb Bauss jj_1...@live.dk: Is there anyway to pull of a runtime compilation of D code or at the very least asm execution? Sure. For runtime compilation you invoke any installed D compiler and compile a conventional shared library that you then load with: http://dlang.org/library/core/runtime/Runtime.loadLibrary.html For ASM execution you'd simply load the ASM into an executable memory area (See virtual memory page protection attributes for your OS) and call or jump into it through D's inline asm {} blocks. I hope that helps. -- Marco
m_condition.mutex cannot be used in shared method ?
I have a thread that is shared by others, so I have a shared method, inside of which I wrote: final void opOpAssign(string op : ~)(ref StreamingObject item) shared { synchronized (m_condition.mutex) { m_list.unshared ~= item; m_condition.notify(); } } Error: non-shared method core.sync.condition.Condition.mutex is not callable using a shared object Where exactly should my stuff stop to be shared so I can call .mutex ? Btw.: StreamingObject is a struct unshared is a @property that casts away sharedness -- Marco
Re: How do you get T from shared(T) ?
Am Tue, 30 Sep 2014 14:48:03 + schrieb John Colvin john.loughran.col...@gmail.com: On Sunday, 28 September 2014 at 09:11:07 UTC, Marco Leise wrote: For head-unshared there is `static if (is(T U : shared U))`. But how do you get the unshared type for anything from `shared void*` to `shared uint` ? template UnShared(T, bool removeAll = false) { static if(is(T : shared U, U)) { static if(is(U : shared(V)*, V)) { alias UnShared = UnShared!(V, true)*; } else { alias UnShared = U; } } else { static if(removeAll is(T : U*, U)) { alias UnShared = UnShared!(U, true)*; } else { alias UnShared = T; } } } unittest { static assert(is(UnShared!(shared int) == int)); static assert(is(UnShared!(shared void*) == void*)); static assert(is(UnShared!(shared(int**)*) == shared(int**)*)); static assert(is(UnShared!(shared(int**)**, true) == int)); } Ah, thanks. That does the trick! -- Marco
Re: A hash table implementation benchmark
Am Wed, 01 Oct 2014 14:40:01 -0700 schrieb Ali Çehreli acehr...@yahoo.com: Found on Reddit: http://lonewolfer.wordpress.com/2014/03/13/benchmarking-hash-table-implementations-in-different-languages/ Are you motivated enough to compare D's associative arrays with those results? :) Ali The question is ... do you dare with the current state of the GC :D -- Marco
Re: A hash table implementation benchmark
Oh wit! It is a read-only benchmark.
How do you get T from shared(T) ?
For head-unshared there is `static if (is(T U : shared U))`. But how do you get the unshared type for anything from `shared void*` to `shared uint` ? -- Marco
Re: How do you get T from shared(T) ?
Am Sun, 28 Sep 2014 14:07:22 + schrieb tcak t...@gmail.com: On Sunday, 28 September 2014 at 09:11:07 UTC, Marco Leise wrote: For head-unshared there is `static if (is(T U : shared U))`. But how do you get the unshared type for anything from `shared void*` to `shared uint` ? shared int a; int b = cast()a; No, I mean for `shared void*`, too. But I special cased for one level of pointer indirection now, so it works. -- Marco
Re: Parsing
Am Mon, 31 Mar 2014 04:06:38 + schrieb Joel joel...@gmail.com: I've got a program that uses user input, but I'm having trouble with it. Here's an example, the unenclosed numbers (1 2 3 in example) add entries: 0 Achievement 1 2 3 cWon! st4 5 6 - user input (create 3 entries all with st4 5 6) 0 Achievement 1 house [4, 5, 6] 2 rock [4, 5, 6] 3 mouse [4, 5, 6] cmud - user input 0 Achievement 1 house [4, 5, 6] mud 2 rock [4, 5, 6] mud 3 mouse [4, 5, 6] mud So add the entries and while they are still hot, you can edit them. I don't know if this an impossible ask for help, but I though I might get some help. I'll keep going over my code to work it out. Thanks. So what is the question? -- Marco
Re: best D equivalent to C'stimeval
Am Mon, 31 Mar 2014 05:09:22 + schrieb ed sillymong...@gmail.com: Hi, Just wondering what the best replacement for C timeval is in D. I'm looking at std.datetime.SysTime, but std.datetime is huge so I'm not sure. Thanks, ed If you just need to time something, TickDuration from core.time is an efficient cross-platform timer. auto t1 = TickDuration.currentSystemTick; ... auto t2 = TickDuration.currentSystemTick; writefln(Took %s ms, (t2-t1).msecs); -- Marco
Re: Templates: generic return null;
Am Mon, 03 Feb 2014 10:25:17 + schrieb Chris wend...@tcd.ie: MyStruct(T) { T[T] attributes; // public auto getAttribute(T attr) { if (!(attr in attributes)) { return null; // Doesn't work for numbers! } return attributes[attr]; } } void main() { auto myStr = MyStruct!int(0); // Error } MyStruct(T) { T[T] attributes; // public auto getAttribute(T attr) { return attr in attributes; } } There you go. -- Marco
Re: 3d vector struct
Am Mon, 03 Feb 2014 22:01:14 + schrieb Stanislav Blinov stanislav.bli...@gmail.com: Return-by-value being optimized as a move might be one more reason why you would like to use slices instead of variables to store coordinates (since that would mean just moving a pointer and a size_t), but that might have to wait until custom allocators finally arrive. 3 doubles is only one machine word more than an array slice and there are no indirections, allocations and length attribute to deal with (which is always 3 here). -- Marco
Re: Performant method for reading huge text files
Am Tue, 04 Feb 2014 00:04:22 + schrieb Rene Zwanenburg renezwanenb...@gmail.com: On Monday, 3 February 2014 at 23:50:54 UTC, bearophile wrote: Rene Zwanenburg: The problem is speed. I'm using LockingTextReader in std.stdio, but it't not nearly fast enough. On my system it only reads about 3 MB/s with one core spending all it's time in IO calls. Are you reading the text by lines? In Bugzilla there is a byLineFast: https://d.puremagic.com/issues/show_bug.cgi?id=11810 Bye, bearophile Nope, I'm feeding it to csvReader which uses an input range of characters. Come to think of it.. Well this is embarassing, I've been sloppy with my profiling :). It appears the time is actually spent converting strings to doubles, done by csvReader to read a row into my Record struct. No way to speed that up I suppose. Still I find it surprising that parsing doubles is so slow. Parsing textual representations of numbers is slow. The other way around is faster. You have to check all kinds of stuff, like preceding +/-, starts with a dot, are all characters '0' to '9', is there an exponent? Is it NaN or nan? Floating point math is slow, but when you store the intermediate results while parsing inside an integer, you may run out of digits if the number string is long. On the other hand repeated floating point math will introduce some error as you append digits. Here is the ~400 lines version in Phobos: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L2250 -- Marco
Re: How to destroy a shared struct.
Am Sun, 26 Jan 2014 21:36:58 + schrieb Benjamin Thaut c...@benjamin-thaut.de: On Sunday, 26 January 2014 at 17:15:10 UTC, Marco Leise wrote: Since shared hasn't change much in the last years, I assume it is somewhat accepted in its current state. My understanding is that if something cannot be attributed to a single thread, it is shared. So far so good. Now I wrote an object pool struct with two properties: it can be used by multiple threads during its lifetime and this(this) is disabled. Logically the struct is both created and destroyed while only the creator thread (which holds the data) has access to it and there is no two ways about it. An object can only be destroyed when it is no longer shared. Yet the D compiler asks for a shared ~this(). This sounds as if it asks me to commit a logical error. So the question is, how do I define a shared struct without a shared ~this() which would be broken by definition? I ran into this issue some time ago too. https://d.puremagic.com/issues/show_bug.cgi?id=8295 Walter stated in a discussion on the newsgroup that this is by design. It basically came down to, that shared structs should not be destroyed ... Although I really don't agree with this, it should be fixed. In my opinion it should not be neccessary to have a shared destructor, because as soon as it is destroyed, it is no longer shared. So no special shared destructor should be neccessary. *nod* But you must have misunderstood Walter. Keeping shared structs alive forever certainly doesn't work. :p -- Marco
How to destroy a shared struct.
Since shared hasn't change much in the last years, I assume it is somewhat accepted in its current state. My understanding is that if something cannot be attributed to a single thread, it is shared. So far so good. Now I wrote an object pool struct with two properties: it can be used by multiple threads during its lifetime and this(this) is disabled. Logically the struct is both created and destroyed while only the creator thread (which holds the data) has access to it and there is no two ways about it. An object can only be destroyed when it is no longer shared. Yet the D compiler asks for a shared ~this(). This sounds as if it asks me to commit a logical error. So the question is, how do I define a shared struct without a shared ~this() which would be broken by definition? -- Marco
extern(C) function literals for stubs
Can I define them somehow? The use case is defining extern C functions that contain code to load the real thing from a library. nothrow extern(C) void function(int) someFunc = ??? -- Marco
Re: extern(C) function literals for stubs
Am Wed, 22 Jan 2014 17:52:03 + schrieb bearophile bearophileh...@lycos.com: Marco Leise: Can I define them somehow? The use case is defining extern C functions that contain code to load the real thing from a library. nothrow extern(C) void function(int) someFunc = ??? Perhaps you want: extern(C) nothrow void someFunc(int someArg); Bye, bearophile Thanks, but I want it to be a function pointer so I can swap it from within the function literal in the fashion of nothrow extern(C) void function(int) someFunc = (int arg) { someFunc = GetProcAddress(someFunc); someFunc(arg); } -- Marco
Re: extern(C) function literals for stubs
Am Wed, 22 Jan 2014 17:52:03 + schrieb bearophile bearophileh...@lycos.com: Marco Leise: Can I define them somehow? The use case is defining extern C functions that contain code to load the real thing from a library. nothrow extern(C) void function(int) someFunc = ??? Perhaps you want: extern(C) nothrow void someFunc(int someArg); Bye, bearophile Got it now. By declaring the literal stub function in a template instead I can use the normal function declaration syntax without introducing a new symbol at the definition site: { ... nothrow extern(C) void function(int) someFunc = Stub!someFunc; ... } nothrow extern(C) auto Stub(alias func)(ParameterTypeTuple!func args) { debug printf(Loading %s...\n, func.stringof.ptr); return (func = impl)(args); } -- Marco
Re: How do I choose the correct primative?
C compilers like D compilers will pack a struct of two 16-bit words into a 32-bit type if you don't force an alignment: http://dlang.org/attribute.html#align What you should avoid is having a data type start at an address that is not a multiple of its size, especially when it comes to SIMD. Working with 16-bit values is not really supported in todays x86 CPUs though, and integer math in D typically yields ints even when you use smaller data types, reflecting what happens on the hardware. Usually I use uint, size_t, real for things that will go to CPU registers and the smallest data type that will work for storage in memory. Keep in mind that RAM access is slow compared to how fast CPUs run. It can be beneficial to have slower data types if they allow more data to fit into the CPU cache. Typically you sort the fields of a struct by size with the larger ones (e.g. pointers) at the top followed by ints, shorts and finally bytes if you want to conserve memory. There is even a template to do that for you, but I think it is more of a toy, when you can easily do that manually without the clutter: http://dlang.org/phobos/std_typecons.html#.alignForSize
Re: Converting char to int
Am Wed, 01 Jan 2014 07:27:54 + schrieb Meta jared...@gmail.com: Your code is working correctly. D's chars, for all values up to 255, are the same as the ASCII character set. UTF-8 reuses the ASCII mapping which is only defined from 0 to 127. Everything above is not ASCII and 255 is in fact not even defined for UTF-8, which is why it was chosen as the initializer for char in D. -- Marco
Re: Custom binary operators
Am Sat, 28 Dec 2013 15:24:31 + schrieb Dicebot pub...@dicebot.lv: AFAIK it is intentionally banned to constrain operator overloading abuse. That and it makes the compiler faster. -- Marco
Re: Reading file by line, weird result
Am Fri, 27 Dec 2013 10:24:15 + schrieb Dfr defle...@yandex.ru: On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote: The solution is to append `line.dup` instead of `line`. I guess this note in the documentation should be marked red: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed. Thank you, .dup helped. To avoid allocating new memory for each line of text, byLine reuses the buffer. You are supposed to make a duplicate if you plan to keep it. It would be different if you had: string s; foreach (line; frange) { s ~= line } in which case, the _contents_ of the line buffer, not the buffer itself are appended to the string s. -- Marco
Re: Which Libraries?
Am Fri, 27 Dec 2013 07:00:29 + schrieb Rikki Cattermole alphaglosi...@gmail.com: On Friday, 27 December 2013 at 05:00:30 UTC, Josh Phillips wrote: I was wondering if people could suggest which libraries may be best to use for building an application which would be a type of text editor with multiple documents and branches. I need something whereby I can create simple, custom windows and do simple text editing, but then i need it to also handle much more complicated graphics in a 3D viewport looking at lots of branching documents. I'm not quite sure if something like GtkD or QtD can handle the more complicated graphics or not, or if it is possible to build it with windows, or perhaps trying to make a text editor with opengl. I've been looking into different ideas and thought i'd try and ask for some advice. GtkD and QtD are both bindings to my knowledge so they should have the same power as the library itself. If you choose to go the route of making a gui lib yourself. Would you be kind enough to look at mine (DOOGLE[1]). I could use some help if you want to go that way. There is also DQuick and DWT. [1] https://github.com/rikkimax/DOOGLE/wiki/Roadmap GtkD has OpenGL support -- Marco
Re: Range of n lines from stdin
Am Fri, 27 Dec 2013 14:26:59 + schrieb Ivan Kazmenko ga...@mail.ru: Quick question. (1) I can do n.iota.map!(_ = readln) to get the next n lines from stdin. (2) However, when I do readln.repeat(n) it looks clearer but works differently: preserves front and reads only one line. (3) In the particular case of readln, we can substitute it with stdin.byLine.take(n) but the question remains for other impure functions. So, what I ask for is some non-caching repeat for functions with side effects. More idiomatic than (1). Is there something like that in Phobos? Is it an OK style to have an impure function in an UFCS chain? If repeat could know whether its first argument is pure, it could then enable or disable front caching depending on purity... no way currently? repeat() is only meant to repeat the same first element over and over. I think it would be wrong if it changed its value during iteration. A wrapper struct could be more ideomatic: FuncRange!readln.take(n) Ivan Kazmenko. -- Marco
Re: getting __DIR__ and __TIME__ of compilation?
Am Fri, 27 Dec 2013 12:43:15 + schrieb Ravn ravnd...@gmail.com: On Friday, 27 December 2013 at 11:56:08 UTC, Ali Çehreli wrote: However, __FILE__ happens to be the current source file that is being compiled but I think the OP wants the current compilation directory. Being a C library file, getcwd() does not work at compile time: import std.stdio; void main() { import std.path: dirName; enum compiledFile = __FILE__; writeln(compiledFile); static const compileTime = __DATE__ ~ ~ __TIME__; writeln(compileTime); /* import std.file: getcwd; static const compilationDir = getcwd(); writeln(compilationDir); Error: getcwd cannot be interpreted at compile time, because it has no available source code */ } Ali Yes, just like what Ali said above, __FILE__, __DATE__ and __TIME__ do work for their respective usages, but I'm also looking for a way to get the current compilation directory during compile time, and getcwd() doesn't seem to be working. Isn't there something like __DIR__ or __PATH__ that I can use to get that information? -Ravn- No, but if you just want the path where your sources are you could use __FILE__ for any module and cut off the part of it that belongs to the module path. A lot of Phobos works at compile time, so you might be able to write a one-liner for that. -- Marco
Re: imports and a data structure (any critique welcome)
Am Fri, 27 Dec 2013 13:45:10 + schrieb bearophile bearophileh...@lycos.com: Timon Gehr: mixin ADT!q{ Term: Var char | Op char Term[] }; void main(){ const expr = Op('f', [Op('g',[Var('x'), Var('y')]), Op('a',[]), Var('x')]); } Where is ADT defined? (And why isn't it a Phobos patch on GitHub?) convertNum could be written more compactly as: char convertNum(int x){ return exyzfgh[x$?x:0]; That's too much compact :-) Humans put a space around operators, and sometimes some parentheses don't hurt: char convertNum(in int x) pure nothrow in { assert(x = 0); } body { return exyzfgh[(x $) ? x : 0]; } Bye, bearophile Before you go _that_ far, just write: char convertNum(in size_t x) pure nothrow { return exyzfgh[(x $) ? x : 0]; } :-) -- Marco
Re: getting __DIR__ and __TIME__ of compilation?
Am Fri, 27 Dec 2013 20:14:00 + schrieb Ravn ravnd...@gmail.com: Tried enum path = dirName(__FILE__), compiles normally, no error from the compiler, but it still returns a relative path instead of a fullpath in my machine. Too bad :-/ I hoped it would use absolute paths. -- Marco
Re: Range of n lines from stdin
Am Fri, 27 Dec 2013 20:34:02 + schrieb Ivan Kazmenko ga...@mail.ru: Maybe the imperative should be repeat is a function, and arguments of functions should be evaluated only once? It does make sense from a language point of view, but somewhat breaks the abstraction for me. The documentation is clear about it: Repeats one value forever. It has nothing to do with purity, whether the input range is lazy or the element is fetched eagerly. If it was meant to do what you expected it would read: Constructs a range from lazily evaluating the expression passed to it over and over. This is not a limitation of the language either I think, since arguments to functions can be declared lazy. -- Marco
Re: Ultra-pure map()?
Am Sat, 28 Dec 2013 01:54:26 + schrieb John Colvin john.loughran.col...@gmail.com: On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote: import std.algorithm; import std.stdio; import std.conv; class Trivial { int sideEffect() { return n++; } override string toString() pure { return to!string(n); } int n; } void main() { Trivial[] objs = [ new Trivial ]; map!(o = o.sideEffect())(objs); writeln(objs); // [0] foreach (o; objs) o.sideEffect(); writeln(objs); // [1] } Can someone explain to me why map() is not equivalent to foreach in the code above? From what I can tell, map() doesn't do anything at all on objs, even though it is a perfectly legitimate range (as far as I can tell). Dave Map is lazy and is never iterated over in your code, therefore no side effects. Yeah, this is kind of unintended usage. Typically with map you take some input range, apply some algorithm to each element, and return a range of the results. Side effects and altering the input object itself makes me want to pull out my crucifix. You shall not have impurity in your functional style code! -- Marco
Re: how to detect OS architecture?
Am Wed, 18 Dec 2013 13:19:09 - schrieb Regan Heath re...@netmail.co.nz: On Tue, 17 Dec 2013 15:13:20 -, Marco Leise marco.le...@gmx.de wrote: Am Tue, 17 Dec 2013 13:30:25 - schrieb Regan Heath re...@netmail.co.nz: On Mon, 16 Dec 2013 21:27:13 -, Hugo Florentino h...@acdam.cu wrote: On Mon, 16 Dec 2013 20:23:00 +0100, Jacob Carlborg wrote: On 2013-12-16 17:46, Marco Leise wrote: Hehe, I guess the whole purpose of the launcher is to run in 32-bit and detect at runtime if the 64-bit main executable can be run or the 32-bit version must be used. The only advantage of that is that only a 32bit launcher needs to be distributed. Perhaps that's the whole idea. It is. :) Process Explorer by sysinternals, now distributed by M$ does something similar. http://technet.microsoft.com/en-gb/sysinternals/bb896653.aspx It is a 32 bit exe, which detects the OS bit width and if it's 64 bit extracts a 64 exe from within itself to run. When you quit that 64 bit exe, it deletes the file it extracted from disk. It's quite a neat solution. R Only if your executable is self-contained. If you already have external DLLs or assets you can as well have a launcher and 2 actual binaries. I don't see why that changes things? Sure, you cannot extract your *static* dependent dlls (those linked at compile time with libs), those have to exist before you can execute your 32 bit launcher. But, if you really wanted to, you could extract and runtime load dlls no problem. R That's my point. If you really wanted, you could do that but you can as well have a launcher and 2 application binaries and avoid this repeated file extraction/deletion and save yourself some troubles at the end of the day. -- Marco
Re: Unique IDs for each template instantiation at compile-time?
Am Thu, 19 Dec 2013 00:01:03 +0100 schrieb Weasel weasel...@gmail.com: I was wondering if it was possible to generate unique(in order) IDs for each template instantiation of a class at compile-time. A short example of what I'm trying to do: static int counter = 0; class A(T) { enum id = counter++; } class B : A!B { } Ofcourse, this doesn't compile because the counter variable can't be read at compile-time. Something like that cannot work. Imagine your template is in a.d and you instantiate it in b.d and c.d. Now you compile: dmd -c b.d dmd -c c.d Both times the counter imported from a.d would start at 0. -- Marco
Re: Embed Windows Internet Explorer
Am Wed, 18 Dec 2013 21:48:30 +0100 schrieb Andre an...@s-e-a-p.de: Am 16.12.2013 19:44, schrieb Andre: Hi, I try to embed Windows Internet Explorer into my application. Most of the coding should be availabe. During method navigate2 I get an empty white screen. No errors is thrown but also the web page is not loaded. Do you have some ideas? = Is use the windows headers from DSource and the dgui forms library. I attached the source code. Kind regards André The issue was related to SysAllocString: VARIANT myURL; VariantInit(myURL); myURL.vt = cast(VARTYPE)VARENUM.VT_BSTR; = myURL.bstrVal = SysAllocString(cast(const(wchar*))url); webBrowser2.Navigate2( myURL, null, null, null, null); It only works with statement: myURL.bstrVal = cast(wchar*)http://www.google.de;; Did you mean this?: myURL.bstrVal = http://www.google.dew.ptr; -- Marco
Re: Embed Windows Internet Explorer
Am Thu, 19 Dec 2013 17:36:57 + schrieb Richard Webb richard.w...@boldonjames.com: On 18/12/2013 20:48, Andre wrote: = myURL.bstrVal = SysAllocString(cast(const(wchar*))url); Looks like the problem there is casting a string to a wchar* - I guess the resulting BSTR will contain garbage instead of the intended value. It only works with statement: myURL.bstrVal = cast(wchar*)http://www.google.de;; Treating a wchar* as a BSTR might cause unexpected things to happen - converting the string to a wchar* and then passing that to SysAllocString would be safer. Oh yes, you are right and I was totally ignorant of what a BSTR is! It is a data structure for strings consisting of size prefix for the character data (4 bytes), the character data as wchars and a terminating zero wchar. So your first approach was correct: string url = …; BSTR* bstrUrl = enforce(SysAllocString(toUTFz!(const(wchar)*)(url)), Out of memory or url is null); myURL.bstrVal = bstrUrl; … SysFreeString(bstrUrl); -- Marco
Re: how to detect OS architecture?
Am Tue, 17 Dec 2013 13:30:25 - schrieb Regan Heath re...@netmail.co.nz: On Mon, 16 Dec 2013 21:27:13 -, Hugo Florentino h...@acdam.cu wrote: On Mon, 16 Dec 2013 20:23:00 +0100, Jacob Carlborg wrote: On 2013-12-16 17:46, Marco Leise wrote: Hehe, I guess the whole purpose of the launcher is to run in 32-bit and detect at runtime if the 64-bit main executable can be run or the 32-bit version must be used. The only advantage of that is that only a 32bit launcher needs to be distributed. Perhaps that's the whole idea. It is. :) Process Explorer by sysinternals, now distributed by M$ does something similar. http://technet.microsoft.com/en-gb/sysinternals/bb896653.aspx It is a 32 bit exe, which detects the OS bit width and if it's 64 bit extracts a 64 exe from within itself to run. When you quit that 64 bit exe, it deletes the file it extracted from disk. It's quite a neat solution. R Only if your executable is self-contained. If you already have external DLLs or assets you can as well have a launcher and 2 actual binaries. -- Marco