Re: core.simd woes
SIMD in LDC is currently broken What problems did you have with it? It seems to work fine for me.
Re: openMP
And is there also a pragma omp critical analogon? On Tuesday, 2 October 2012 at 20:16:36 UTC, Peter Alexander wrote: On Tuesday, 2 October 2012 at 19:15:19 UTC, Farmer wrote: Hi, I am tempted to start D programming but for me it is crucrial to be able to parallelize for-loops as can be done with openMP for C/C++ (mainly @pragma omp parallel for, @pragma omp critical). I have already seen the std.parallelism library but I'm unsure whether it can provide me with the same functionality. Thanks It can. Here's an example from the docs of parallelising a simple for loop: auto logs = new double[10_000_000]; foreach(i, ref elem; taskPool.parallel(logs, 100)) { elem = log(i + 1.0); } This creates a pool of workers that each perform 100 iterations of the loop body in parallel.
Re: std.intrinsic?
On Tuesday, 2 October 2012 at 21:06:04 UTC, Manu wrote: I just installed dmd 2.60 in linux, and it seems std.intrinsic isn't there... is this my fault somehow, or has it been removed? I need the bsr() intrinsic which (used to?) live there. import core.bitop;
Re: std.intrinsic?
On 3 October 2012 00:17, Iain Buclaw ibuc...@ubuntu.com wrote: On Tuesday, 2 October 2012 at 21:06:04 UTC, Manu wrote: I just installed dmd 2.60 in linux, and it seems std.intrinsic isn't there... is this my fault somehow, or has it been removed? I need the bsr() intrinsic which (used to?) live there. import core.bitop; Cheers!
Re: Idea: Introduce zero-terminated string specifier
On 10/2/12, Walter Bright newshou...@digitalmars.com wrote: On 9/30/2012 11:31 AM, deadalnix wrote: If you know that a string is 0 terminated, you can easily create a slice from it as follow : char* myZeroTerminatedString; char[] myZeroTerminatedString[0 .. strlen(myZeroTerminatedString)]; Since %zs is inherently unsafe, it hides such unsafety in a commonly used library function, which will infect everything else that transitively calls writefln with unsafety. This makes %zs an unacceptable feature. How does it hide anything if you have to explicitly mark the format specifier as %zs? It would be documented, just like it's documented that passing pointers to garbage-collected memory to the C side is inherently unsafe. deadalnix's example shows that adding a new format specifier %zs adds little value. It adds convenience, which is an important trait in this day and age. If that's not a concern, why is printf a symbol you can get your hands on as soon as you import std.stdio? And if safety is a concern why is printf used in Phobos at all? I count 427 lines of printf calls in Phobos and 843 lines in Druntime (druntime might have a good excuse since it shouldn't import Phobos functions). Many of these calls in Phobos are not simple D string literal printf calls either. Btw, some weeks ago when dstep was announced you were jumping for joy and were instantly proposing language changes to add better support for wrapping C. But asking for better library support is somehow controversial. I don't understand the double-standard.
Re: openMP
On Tuesday, 2 October 2012 at 21:13:33 UTC, Farmer wrote: And is there also a pragma omp critical analogon? For critical sections you could use a low-level mutex. I don't do much parallel stuff in D, so I don't know if this is the preferred way, but it's an option. http://dlang.org/phobos/core_sync_mutex.html import std.stdio; import std.parallelism; import std.math; import core.sync.mutex; void main() { auto logs = new double[1_000_000]; double x = 0.0; Mutex m = new Mutex(); foreach(i, ref elem; taskPool.parallel(logs, 100)) { elem = log(i + 1.0); m.lock(); x += 1.0; m.unlock(); } }
Re: qtD
On Monday, 1 October 2012 at 17:31:11 UTC, Habibutsu wrote: Anybody knows, project qtd (http://www.dsource.org/projects/qtd/) is alive or died? Last changes was one year ago. Tracking system contains critical bugs and nobody fixes. There may be other working bindings for Qt? Hey, yes I haven't been working on QtD for quite some time now, and unfortunately no one else has picked up on it. I don't know of any other efforts made, and due to the big undertaking it would be wiser to build on what's there already...
Re: IndexType for ranges
On Tue, 02 Oct 2012 19:23:48 +0200 Jonathan M Davis jmdavisp...@gmx.com wrote: On Tuesday, October 02, 2012 19:10:53 monarch_dodra wrote: Ideally, only size_t would be allowed. Reality makes it so that we need ulong in some cases (e.g. iota). Given that fact, you'd ideally restrict it to size_t or ulong specfically (or at least IndexType.sizeof = size_t.sizeof). The problem is that I'm quite sure that there are plenty of programmers out there who have been using int for length and indices even though it's a horribly bad idea. It's a classic mistake. Yea, typing int tends to be automatic enough, and then the awkwardness of size_t on top of that tends to ensure it doesn't get used as much as it should.
Is it possible to tag pull requests?
Some pull requests are rather trivial to approve and merge (e.g. small doc fixes, typo fixes), and it would be nice if a pull requester could tag a pull as trivial when the pull is made. Otherwise I guess we could start using a convention and add [trivial] before the title? I think it might help speed up the merging process.
Re: Idea: Introduce zero-terminated string specifier
On Tuesday, 2 October 2012 at 21:30:35 UTC, Andrej Mitrovic wrote: On 10/2/12, Walter Bright newshou...@digitalmars.com wrote: On 9/30/2012 11:31 AM, deadalnix wrote: If you know that a string is 0 terminated, you can easily create a slice from it as follow : char* myZeroTerminatedString; char[] myZeroTerminatedString[0 .. strlen(myZeroTerminatedString)]; Since %zs is inherently unsafe, it hides such unsafety in a commonly used library function, which will infect everything else that transitively calls writefln with unsafety. This makes %zs an unacceptable feature. How does it hide anything if you have to explicitly mark the format specifier as %zs? It would be documented, just like it's documented that passing pointers to garbage-collected memory to the C side is inherently unsafe. writefln cannot be @safe if it has to support an unsafe format specifier. It's hidden because it affects every call to writefln, even if it doesn't use the unsafe format specifier.
Re: RFC: DConf 2013
On Monday, 1 October 2012 at 16:25:12 UTC, Andrei Alexandrescu wrote: The project is not live, it will be within a few days. In the spirit of having the community actively participate, I'm making this as transparent as it gets. Please comment: http://www.kickstarter.com/projects/dlang/1177501541?token=df96761a Question about: Pledge $50 or more - DON'T LOSE YOUR SHIRT... So, the shirts will be send even for who live in another country? The value has shipping included?
Re: core.simd woes
On Tuesday, 2 October 2012 at 21:03:36 UTC, jerro wrote: SIMD in LDC is currently broken What problems did you have with it? It seems to work fine for me. Can you post an example of doing a simple arithmetic with two 'float4's? My simple tests either fail with LLVM errors or don't produce correct results (which reminds me, I meant to report them, I'll do that). Here's an example: import core.simd, std.stdio; void main() { float4 a = 1, b = 2; writeln((a + b).array); // WORKS: [3, 3, 3, 3] float4 c = [1, 2, 3, 4]; // ERROR: Stored value type does // not match pointer operand type! // [..a bunch of LLVM error code..] float4 c = 0, d = 1; c.array[0] = 4; c.ptr[1] = 4; writeln((c + d).array); // WRONG: [1, 1, 1, 1] }
Re: core.simd woes
Also, I'm using the LDC off the official Arch community repo.
How do I run DMD unittests on win32?
I'm starting to contribute to DMD by fixing some bugs, but I need to run the test-suite. Anyone know how this is done on win32? There's a makefile in the test dir but what I don't know is if I need to set up my directory structure in any special way? Is it simpler to just make the pull request and wait for the autotester to finish, or should I try to do this locally first? Thanks.
Re: Idea: Introduce zero-terminated string specifier
On 10/3/12, Jakob Ovrum jakobov...@gmail.com wrote: writefln cannot be @safe if it has to support an unsafe format specifier. It's hidden because it affects every call to writefln, even if it doesn't use the unsafe format specifier. Ah damn I completely forgot about @safe. I tend to avoid recent features.. OK then I think my arguments are moot. Nevertheless I can always define a helper function for my own purposes I guess. Sorry Walter for not taking @safe into account. :)
Re: Idea: Introduce zero-terminated string specifier
On Wed, Oct 03, 2012 at 03:07:14AM +0200, Andrej Mitrovic wrote: On 10/3/12, Jakob Ovrum jakobov...@gmail.com wrote: writefln cannot be @safe if it has to support an unsafe format specifier. It's hidden because it affects every call to writefln, even if it doesn't use the unsafe format specifier. [...] Hmm, this seems to impose unnecessary limitations on @safe. I guess the current language doesn't allow for a conditionally-safe tag where something can be implicitly marked @safe if it's provable at compile-time that it's safe? T -- Elegant or ugly code as well as fine or rude sentences have something in common: they don't depend on the language. -- Luca De Vitis
Re: core.simd woes
import core.simd, std.stdio; void main() { float4 a = 1, b = 2; writeln((a + b).array); // WORKS: [3, 3, 3, 3] float4 c = [1, 2, 3, 4]; // ERROR: Stored value type does // not match pointer operand type! // [..a bunch of LLVM error code..] float4 c = 0, d = 1; c.array[0] = 4; c.ptr[1] = 4; writeln((c + d).array); // WRONG: [1, 1, 1, 1] } Oh, that doesn't work for me either. I never tried to use those, so I didn't notice that before. This code gives me internal compiler errors with GDC and DMD too (with float4 c = [1, 2, 3, 4] commented out). I'm using DMD 2.060 and a recent versions of GDC and LDC on 64 bit Linux.
Re: How do I run DMD unittests on win32?
On 10/3/12, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: I'm starting to contribute to DMD by fixing some bugs, but I need to run the test-suite. Anyone know how this is done on win32? There's a makefile in the test dir but what I don't know is if I need to set up my directory structure in any special way? Is it simpler to just make the pull request and wait for the autotester to finish, or should I try to do this locally first? Thanks. Hmm I was trying to find the autotester source script to figure this out on my own, but I can't find the source anywhere. :) I'm pretty sure I saw it on github somewhere though?
Re: How do I run DMD unittests on win32?
On 10/3/12, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: Hmm I was trying to find the autotester source script to figure this out on my own, but I can't find the source anywhere. :) I'm pretty sure I saw it on github somewhere though? Ok found it: https://github.com/braddr/d-tester Source was linked from website but I didn't notice.
Re: How do I run DMD unittests on win32?
On 10/3/12, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: Ok found it: https://github.com/braddr/d-tester Yikes, this is cygwin. Well if nothing else I'll make a D driver script, I'm not in the mood to deal with cygwin or virtual machines.
Re: RFC: DConf 2013
On 10/2/12 8:23 PM, MattCoder wrote: On Monday, 1 October 2012 at 16:25:12 UTC, Andrei Alexandrescu wrote: The project is not live, it will be within a few days. In the spirit of having the community actively participate, I'm making this as transparent as it gets. Please comment: http://www.kickstarter.com/projects/dlang/1177501541?token=df96761a Question about: Pledge $50 or more - DON'T LOSE YOUR SHIRT... So, the shirts will be send even for who live in another country? The value has shipping included? Good question. I'll circle back to the logistics guy. Andrei
Re: Idea: Introduce zero-terminated string specifier
On Tuesday, October 02, 2012 18:21:30 H. S. Teoh wrote: On Wed, Oct 03, 2012 at 03:07:14AM +0200, Andrej Mitrovic wrote: On 10/3/12, Jakob Ovrum jakobov...@gmail.com wrote: writefln cannot be @safe if it has to support an unsafe format specifier. It's hidden because it affects every call to writefln, even if it doesn't use the unsafe format specifier. [...] Hmm, this seems to impose unnecessary limitations on @safe. I guess the current language doesn't allow for a conditionally-safe tag where something can be implicitly marked @safe if it's provable at compile-time that it's safe? The format string is a runtime argument, so nothing can be proven about it at compile time. If you want any kind of @safe inferrence, you need to use a template. If writefln took the format string as a template argument and generated different code (which was @safe or not depending on what it did) based on what was in the format string, then inferrence could take place, but otherwise no. - Jonathan M Davis
Re: Is it possible to tag pull requests?
On Tuesday, 2 October 2012 at 23:21:13 UTC, Andrej Mitrovic wrote: Some pull requests are rather trivial to approve and merge (e.g. small doc fixes, typo fixes), and it would be nice if a pull requester could tag a pull as trivial when the pull is made. Otherwise I guess we could start using a convention and add [trivial] before the title? I think it might help speed up the merging process. It is a feature of github, but I believe was disabled. This sounds like a good reason to enable it. Project owners?
Re: core.simd woes
jerro wrote: This code gives me internal compiler errors with GDC and DMD too (with float4 c = [1, 2, 3, 4] commented out). I'm using DMD 2.060 and a recent versions of GDC and LDC on 64 bit Linux. Yes the SIMD situation isn't entirely usable right now with DMD and LDC. Only simple vector arithmetic is possible to my knowledge. The internal DMD error is actually from processing '(a + b)' and returning it to writeln() without assigning to an separate float4 first.. for example, this compiles with DMD and outputs correctly: import core.simd, std.stdio; void main() { float4 a = 1, b = 2; float4 r = a + b; writeln(r.array); float4 c = [1, 2, 3, 4]; float4 d = 1; c.array[0] = 4; c.ptr[1] = 4; r = c + d; writeln(r.array); } correctly outputs: [3, 3, 3, 3] [5, 5, 4, 5] I've never tried to do SIMD with GDC, though I understand it's done differently and core.simd XMM operations aren't supported (though I can't get them to work in DMD either... *sigh*). Take a look at Manu's std.simd library for reference on GDC SIMD support: https://github.com/TurkeyMan/phobos/blob/master/std/simd.d
Re: A study on immutability usage
On 10/01/2012 09:39 PM, Bernard Helyer wrote: Our results from 14 Java applications Only 14? So it's a useless statistic. No, that isn't true. How many language decisions in D are based on an analysis of even 5 programs, let alone 14? What if you were testing to see how fair a coin was, and it came up heads 14 times in a row? Would you have a very strong suspicion that the coin was biased? This isn't an idle question, as this kind of question happens a lot during preliminary testing of medical treatments, for example. How many examples you have to look at depends on what you are looking for and the kind of results you get.
Re: Idea: Introduce zero-terminated string specifier
On Tue, Oct 02, 2012 at 07:50:09PM -0700, Jonathan M Davis wrote: On Tuesday, October 02, 2012 18:21:30 H. S. Teoh wrote: On Wed, Oct 03, 2012 at 03:07:14AM +0200, Andrej Mitrovic wrote: On 10/3/12, Jakob Ovrum jakobov...@gmail.com wrote: writefln cannot be @safe if it has to support an unsafe format specifier. It's hidden because it affects every call to writefln, even if it doesn't use the unsafe format specifier. [...] Hmm, this seems to impose unnecessary limitations on @safe. I guess the current language doesn't allow for a conditionally-safe tag where something can be implicitly marked @safe if it's provable at compile-time that it's safe? The format string is a runtime argument, so nothing can be proven about it at compile time. If you want any kind of @safe inferrence, you need to use a template. If writefln took the format string as a template argument and generated different code (which was @safe or not depending on what it did) based on what was in the format string, then inferrence could take place, but otherwise no. [...] Yes that's what I mean. If the format string is known at compile-time and known to involve only @safe code, then this would work. Something like this might work if CTFE is used to parse the format string piecemeal (i.e., translate something like writefln(%d %s,x,y) into write!int(x); write!string( ); write!string(y)). The safe instances of write!T(...) will be marked @safe. But it does seem like a lot of work just so we can use @safe, though. I suppose we could just use @trusted and call it a day. T -- Claiming that your operating system is the best in the world because more people use it is like saying McDonalds makes the best food in the world. -- Carl B. Constantine
Re: Idea: Introduce zero-terminated string specifier
On Wednesday, 3 October 2012 at 05:04:01 UTC, H. S. Teoh wrote: Yes that's what I mean. If the format string is known at compile-time and known to involve only @safe code, then this would work. Something like this might work if CTFE is used to parse the format string piecemeal (i.e., translate something like writefln(%d %s,x,y) into write!int(x); write!string( ); write!string(y)). The safe instances of write!T(...) will be marked @safe. It doesn't matter if the argument is known at compile-time or not, because there's no way to know that without receiving the format string as a template parameter, in which case it must *always* be known at compile-time (runtime format string would not be supported), and then the syntax is no longer writefln(%d %s, x, y). Obviously, such a change is not acceptable. I suppose we could just use @trusted and call it a day. No, that would be abusing @trusted. The function would no longer be safe, *because it contains possibly unsafe code*. @trusted is for safe functions that the compiler cannot prove safe.
Tips for debugging EXC_BAD_ACCESS
I'm trying to debug the Mac OS X port of DWT. Almost as soon as a DWT application starts to process events I receive a segmentation fault. The error happens in the objc_msgSend C function when calling an Objective-C method. GDB backtrace: http://pastebin.com/0fmUmPQ1 The source code of DWT is located here: https://github.com/d-widget-toolkit/dwt-mac The error happens at this call: https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Shell.d#L1874 Which calls: https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Widget.d#L1824 Then: https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Widget.d#L230 Some other points of interest: https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Display.d#L4871 https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Shell.d#L1818 https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Display.d#L4501 https://github.com/d-widget-toolkit/dwt-mac/blob/master/dwt/widgets/Display.d#L4367 -- /Jacob Carlborg
Re: Accessing CoInit [is Troubleshooting Linker error]
I haven't tried to use DMD 2.060 yet, will see if i've got time later.
Re: Accessing CoInit [is Troubleshooting Linker error]
On 10/2/12, Jesse Phillips jessekphillip...@gmail.com wrote: I've made the changes needed to get past the linker error I'm sorry, I was completely wrong about STDAPI being extern(C). I saw EXTERN_C and immediately thought this was the calling convention, it's not: #define STDAPI EXTERN_C HRESULT STDAPICALLTYPE #define STDAPICALLTYPE __stdcall So this is actually extern(Windows). Linker errors persist when using implib, but when using coffimplib on an existing COFF import library it will link and work at runtime. Here's one I made just now: https://dl.dropbox.com/u/9218759/Ole32_dmd.lib It works for me with this: pragma(lib, Ole32_dmd.lib); extern(Windows) int CoInitializeEx(void*, uint dwCoInit); void main() { CoInitializeEx(null, 0x2); }
Re: Troubleshooting Linker error (Symbol Undefined)
On 10/2/12, Jesse Phillips jessekphillip...@gmail.com wrote: Thank you, making these changes did do the trick As mentioned in the other thread I was wrong, it's extern(Windows), but implib produced an import lib which didn't quite work. coffimplib does the trick though.
Re: Accessing CoInit [is Troubleshooting Linker error]
On Tuesday, 2 October 2012 at 09:48:00 UTC, Andrej Mitrovic wrote: I'm sorry, I was completely wrong about STDAPI being extern(C). I saw EXTERN_C and immediately thought this was the calling convention, it's not: #define STDAPI EXTERN_C HRESULT STDAPICALLTYPE #define STDAPICALLTYPE __stdcall So this is actually extern(Windows). Linker errors persist when using implib, but when using coffimplib on an existing COFF import library it will link and work at runtime. Here's one I made just now: https://dl.dropbox.com/u/9218759/Ole32_dmd.lib It works for me with this: pragma(lib, Ole32_dmd.lib); extern(Windows) int CoInitializeEx(void*, uint dwCoInit); void main() { CoInitializeEx(null, 0x2); } Thank you, it does work, and I figured out why my coffimplib didn't work. I forgot to rename it, so I moved it as out.lib :( I'm going to go write up some docs tonight.
Functional vs simple code
Without optimization the range and algorithm method takes about 10 times as long as the simple code below it, with no array bounds checking and optimization it takes six times as long. Why is the difference so huge? I'd expect a moderate overhead but that's a big difference. module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.peek.msecs.writeln(msecs); sum2.writeln; }
Re: Functional vs simple code
On Tuesday, 2 October 2012 at 20:48:31 UTC, ixid wrote: Without optimization the range and algorithm method takes about 10 times as long as the simple code below it, with no array bounds checking and optimization it takes six times as long. Why is the difference so huge? I'd expect a moderate overhead but that's a big difference. module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.peek.msecs.writeln(msecs); sum2.writeln; } I realised I was making the functional version more complicated than necessary. This version is faster but still four times slower than the simple version: MAX.iota.reduce!a + b * b.writeln;
Re: Functional vs simple code
On 10/02/2012 10:48 PM, ixid wrote: Without optimization the range and algorithm method takes about 10 times as long as the simple code below it, with no array bounds checking and optimization it takes six times as long. Why is the difference so huge? I'd expect a moderate overhead but that's a big difference. module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.peek.msecs.writeln(msecs); sum2.writeln; } $ cat ixidbench.d module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.stop; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.reset; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.stop; sw.peek.msecs.writeln(msecs); sum2.writeln; } $ ldmd2 -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 6528msecs 7032546979563742720 7518msecs 7032546979563742720
Re: Functional vs simple code
On 10/03/2012 12:11 AM, Timon Gehr wrote: ... $ cat ixidbench.d module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.stop; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.reset; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.stop; sw.peek.msecs.writeln(msecs); sum2.writeln; } $ ldmd2 -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 6528msecs 7032546979563742720 7518msecs 7032546979563742720 $ gdmd -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 11250msecs 7032546979563742720 11233msecs 7032546979563742720
Re: Functional vs simple code
On Tuesday, 2 October 2012 at 22:13:10 UTC, Timon Gehr wrote: On 10/03/2012 12:11 AM, Timon Gehr wrote: ... $ cat ixidbench.d module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.stop; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.reset; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.stop; sw.peek.msecs.writeln(msecs); sum2.writeln; } $ ldmd2 -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 6528msecs 7032546979563742720 7518msecs 7032546979563742720 $ gdmd -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 11250msecs 7032546979563742720 11233msecs 7032546979563742720 Yes, I think it was just the compiler and compiler options rather than anything inherent in the method, DMD produced much slower code than GDC for the functional version. It's interesting that it's significantly faster in the functional style with LDC.
zip.map.reduce at CT?
Do you know if here the problem is in Phobos or if I'm asking Phobos to do something too much hard? import std.algorithm: map, reduce; import std.range: zip; struct S {} alias bool function(S) F; F foo(T)(T) { return p = true; } F bar(F r1, F r2) { return p = true; } F spam(S[] ps) { return zip(ps, ps).map!foo().reduce!bar(); } const r1 = spam([S(), S()]); // Error void main() { const r2 = spam([S(), S()]); // OK } Output: ...\dmd2\src\phobos\std\conv.d(3393): Error: cannot dereference invalid pointer *result ...\dmd2\src\phobos\std\range.d(3714):called from here: emplace(addr,front(this.ranges._field_field_0)) ...\dmd2\src\phobos\std\algorithm.d(428):called from here: this._input.front() ...\dmd2\src\phobos\std\algorithm.d(428):called from here: foo(this._input.front()) ...\dmd2\src\phobos\std\algorithm.d(697):called from here: _param_0.front() test.d(12):called from here: reduce(map(zip(ps,ps))) test.d(14):called from here: spam([S(),S()]) Bye, bearophile
how to call std_stdio_static_this from a dynamically loaded shared library (osx)
How do I call std_stdio_static_this() in std.stdio from a dynamically loaded shared library (osx) ? I need to do this in my scenario: 1) main program is launched 2) dynamic library is created 3) dynamic library is loaded and a function from it is called 4) everything works fine until a writeln(0) is called from a function inside the dynamic lib, at which point it crashes. But by calling std_stdio_static_this2 (see below) BEFORE any call to writeln (and similar functions), everything works fine. When I call std_stdio_static_this from another module, I'm pretty sure that code doesn't get called, because when I add a printf or assert(0) statement inside std_stdio_static_this, nothing happens. My current (working!) workaround is shown below, but I was hoping for a solution that didn't involve modifying std.stdio. void std_stdio_static_this2(T=void)() { //copy contents of std_stdio_static_this() function here: //putting assert(0); here WILL crash, as expected; but it won't if the signature is std_stdio_static_this2(). //Bind stdin, stdout, stderr __gshared File.Impl stdinImpl; stdinImpl.handle = core.stdc.stdio.stdin; .stdin.p = stdinImpl; // stdout __gshared File.Impl stdoutImpl; stdoutImpl.handle = core.stdc.stdio.stdout; .stdout.p = stdoutImpl; // stderr __gshared File.Impl stderrImpl; stderrImpl.handle = core.stdc.stdio.stderr; .stderr.p = stderrImpl; }
Re: Functional vs simple code
On Tuesday, 2 October 2012 at 22:13:10 UTC, Timon Gehr wrote: On 10/03/2012 12:11 AM, Timon Gehr wrote: ... $ cat ixidbench.d module main; import std.stdio, std.algorithm, std.range, std.datetime; enum MAX = 10_000_000_000UL; void main() { StopWatch sw; sw.start; auto sum1 = MAX.iota.map!(x = x * x).reduce!a + b; sw.stop; sw.peek.msecs.writeln(msecs); sum1.writeln; sw.reset; sw.start; ulong sum2 = 0; foreach(i;0..MAX) sum2 += i * i; sw.stop; sw.peek.msecs.writeln(msecs); sum2.writeln; } $ ldmd2 -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 6528msecs 7032546979563742720 7518msecs 7032546979563742720 $ gdmd -O -release -inline ixidbench.d -ofixidbench $ ./ixidbench 11250msecs 7032546979563742720 11233msecs 7032546979563742720 While fiddling with this I came across something that seems odd in the behaviour of reduce and wondered if it's intended. It rather limits the usefulness of reduce with UFCS to a + b and a - b. Reduce works correctly when provided with a seed argument: reduce!a + b + 2(0, [1,1,1]).writeln; // == 9 as expected With UFCS I see no elegant way to reduce a chain with a more sophisticated reduce argument than the two simple ones listed above because the operation is not carried out on the first array element, used as the seed. This means: [1,1,1].reduce!a + b + 2.writeln; // == 7 which is useless and could easily trip people up because the intuitive expectation is that it will act like the seed example. If I am wrong in that expectation what is a use case for the seedless behaviour? Is there a way of writing the operation to give the same answer as the seed answer? The element in position 0 should surely have +2 added to itself, it's only being the seed out of convenience isn't it? Instead we get 1 + (1 + 2) + (1 + 2). The order of reduce's arguments, (seed, range) prevent it being used with UFCS properly. If it were (range, seed) then there would be no problem: [1,1,1].reduce!a + b + 2(0).writeln; // == 9
Re: Functional vs simple code
On Wednesday, 3 October 2012 at 01:21:38 UTC, ixid wrote: If it were (range, seed) then there would be no problem: [1,1,1].reduce!a + b + 2(0).writeln; // == 9 My thoughts exactly.
Re: Functional vs simple code
While fiddling with this I came across something that seems odd in the behaviour of reduce and wondered if it's intended. It rather limits the usefulness of reduce with UFCS to a + b and a - b. Reduce works correctly when provided with a seed argument: reduce!a + b + 2(0, [1,1,1]).writeln; // == 9 as expected With UFCS I see no elegant way to reduce a chain with a more sophisticated reduce argument than the two simple ones listed above because the operation is not carried out on the first array element, used as the seed. This means: [1,1,1].reduce!a + b + 2.writeln; // == 7 which is useless and could easily trip people up because the intuitive expectation is that it will act like the seed example. If I am wrong in that expectation what is a use case for the seedless behaviour? The fact that it does something different than the seeded version does not make the seedless version useless - in fact, that's what makes it useful. A typical use case is to find the maximum of a range (there is an example of this in the documentation at http://dlang.org/phobos/std_algorithm.html#reduce). If you don't know the highest possible value of elements, then you couldn't come up with an appropriate seed for this case. I agree that the difference between the two versions of reduce can be a bit confusing. Maybe it would be better if they were named differently. Is there a way of writing the operation to give the same answer as the seed answer? In general, no (apart from the silly reduce!f(chain([seed], range))). If you want the behavior of the seeded version, use the seeded version. The element in position 0 should surely have +2 added to itself, it's only being the seed out of convenience isn't it? No, reduce!f(r) is not merely a syntactic sugar for reduce!f(0, r) (you could say it's a syntactic sugar for reduce!f(r.front, r.drop(1), though). Making reduce!f(r) be the same as reduce!f(0, r) doesn't really make any sense - would you expect [1, 2, 3].reduce!a * b to return 0? I wouldn't. Instead we get 1 + (1 + 2) + (1 + 2). The order of reduce's arguments, (seed, range) prevent it being used with UFCS properly. If it were (range, seed) then there would be no problem: [1,1,1].reduce!a + b + 2(0).writeln; // == 9 This would be better, yes. Reduce was written before there was UFCS, so they couldn't take this into account. I don't know if it is possible for this to be changed now, as it would definitely break some code.
Re: Functional vs simple code
A typical use case is to find the maximum of a range (there is an example of this in the documentation at http://dlang.org/phobos/std_algorithm.html#reduce). If you don't know the highest possible value of elements, then you couldn't come up with an appropriate seed for this case. Fixing unseeded reduce would not remove that use case though, it just happens to be a case that's not broken by the way unseeded reduce works, why couldn't unseeded reduce compare a (the first datum) to itself? That would discover a isn't greater than a so leave a in position 0 and compare with all of the other elements. It would also avoid breaking uses like a + b + 2 and a + b * 2 as well as a raft of more complex uses that reduce should be able to do but requires map and then reduce at present. Walter Bright has a subtle bug in his code (the combined sum and square reduce) in his latest Dr Dobbs due to the behaviour of unseeded reduce. I'd call that more broken than unintuitive. int[] arr = [1,2,3,4,5]; auto r = arr.reduce!((a,b) = a + b, (a,b) = a + b * b); writefln(sum = %s, sum of squares = %s, r[0], r[1]); If you change the value of the first number to 2 the square sum is an incorrect 56 when it should be 58.
[Issue 8741] wrong code for struct member initialized using struct constructor
http://d.puremagic.com/issues/show_bug.cgi?id=8741 Don clugd...@yahoo.com.au changed: What|Removed |Added Keywords||wrong-code CC||clugd...@yahoo.com.au Summary|[CTFE] Incorrect static |wrong code for struct |array assign results in |member initialized using |constructor |struct constructor --- Comment #1 from Don clugd...@yahoo.com.au 2012-10-02 00:04:08 PDT --- Was CTFE: Incorrect static array assign results in constructor This doesn't involve CTFE, it's a semantic error. It is deciding if Vec2(0) is a struct literal or a constructor, before it has worked out that Vec2 even has a constructor. So it decides (incorrectly) that it's a struct literal. It doesn't require static arrays, either. The constructor just doesn't get called at all. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8741] wrong code for struct member initialized using struct constructor
http://d.puremagic.com/issues/show_bug.cgi?id=8741 Don clugd...@yahoo.com.au changed: What|Removed |Added Keywords||pull --- Comment #2 from Don clugd...@yahoo.com.au 2012-10-02 00:26:26 PDT --- https://github.com/D-Programming-Language/dmd/pull/1157 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8745] floating point comparison (is vs ==) inconsistency (on 32)
http://d.puremagic.com/issues/show_bug.cgi?id=8745 Don clugd...@yahoo.com.au changed: What|Removed |Added CC||clugd...@yahoo.com.au --- Comment #1 from Don clugd...@yahoo.com.au 2012-10-02 01:03:51 PDT --- The idea that for floating point, 'is' and '==' should be the same, is wrong. See bug 3632 for further discussion. I suspect this is a duplicate of the issues raised there. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8745] floating point comparison (is vs ==) inconsistency (on 32)
http://d.puremagic.com/issues/show_bug.cgi?id=8745 --- Comment #2 from monarchdo...@gmail.com 2012-10-02 01:19:17 PDT --- (In reply to comment #1) The idea that for floating point, 'is' and '==' should be the same, is wrong. See bug 3632 for further discussion. I suspect this is a duplicate of the issues raised there. I read the thread, it mostly relates to how comparison is done in regards to NaN and 0. Here, we are dealing with a normal float. It mentions doing an isIdentical call if you really want binary comparison: // void main() { writeln(isIdentical(getFloat(), getFloat())); writeln(getFloat() is getFloat()); writeln(getFloat() == getFloat()); } // true true false // :/ So, to get this straight, I got a and b. a is b and a is is identical to b but a != b ? (!) Is that really the intended behavior? If so, can you explain what I am seeing? I'm more confused than trying to request a change of behavior, really. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #5 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 02:25:42 PDT --- (In reply to comment #4) void rehash() { memo = null; } Maybe do you mean something like this? void rehash() { memo.rehash; } void clear() { memo = null; } Absolutely. I've used the wrong term here. Here's the snippet: module test; import std.stdio; import std.traits; import std.typecons; import std.datetime; template isClassStruct(alias fun) { enum bool isClassStruct = (is(fun == class) || is(fun == struct)); } mixin template memoize(alias fun, uint maxSize = uint.max) if (isClassStruct!(__traits(parent, fun))) { ReturnType!fun[Tuple!(ParameterTypeTuple!fun)] memo; void rehash() { memo.rehash(); } void clear() { memo = null; } ReturnType!fun opCall(ParameterTypeTuple!fun args) { auto t = tuple(args); auto p = t in memo; if (p) return *p; static if (maxSize != uint.max) { if (memo.length = maxSize) memo = null; } mixin(auto r = this. ~ __traits(identifier, fun) ~ (args);); memo[t] = r; return r; } } class A { int field; int slowFunc(int a, int b) { int result; foreach (_; 0 .. 1024) { result += a; result += b; } return result + field; } mixin memoize!slowFunc fastFunc; } enum CallCount = 2048; void main() { A a = new A; int z = a.fastFunc(100, 100); writeln(z); a.field = 50; a.fastFunc.clear(); z = a.fastFunc(100, 100); writeln(z); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #6 from bearophile_h...@eml.cc 2012-10-02 02:54:21 PDT --- (In reply to comment #5) enum bool isClassStruct = (is(fun == class) || is(fun == struct)); No need for extra parentheses: enum bool isClassStruct = is(fun == class) || is(fun == struct); void rehash() { memo.rehash(); } I think () aren't needed, even with -property. int slowFunc(int a, int b) If the arguments are constant it doesn't work: int slowFunc(in int a, in int b) mixin memoize!slowFunc fastFunc; This mixin template is useful. A disadvantage is that it doesn't follow the API (usage) of the Phobos memoize. So maybe it needs a different name, like memoizeMethod, or something. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8746] New: rehash AA property doesn't work with constant Tuple
http://d.puremagic.com/issues/show_bug.cgi?id=8746 Summary: rehash AA property doesn't work with constant Tuple Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: andrej.mitrov...@gmail.com --- Comment #0 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 03:05:24 PDT --- import std.typecons; void main() { int[Tuple!(const int)] hash; hash.rehash; } D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\object.di(521): Error: can only initialize const member key inside constructor This was found while trying to implement Issue 8743. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #8 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 03:08:44 PDT --- (In reply to comment #6) This mixin template is useful. A disadvantage is that it doesn't follow the API (usage) of the Phobos memoize. So maybe it needs a different name, like memoizeMethod, or something. Yes. I couldn't make it have the same syntax because of the requirement of the `this` reference. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #7 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 03:05:48 PDT --- (In reply to comment #6) If the arguments are constant it doesn't work: int slowFunc(in int a, in int b) Seems to be a new bug related to Tuple: Issue 8746 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #9 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 03:12:47 PDT --- (In reply to comment #8) (In reply to comment #6) This mixin template is useful. A disadvantage is that it doesn't follow the API (usage) of the Phobos memoize. So maybe it needs a different name, like memoizeMethod, or something. Yes. I couldn't make it have the same syntax because of the requirement of the `this` reference. Also I'm unsure about recursive calls. Existing memoize allows you to recursively call a memoized function. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8743] Add support for memoizing class methods
http://d.puremagic.com/issues/show_bug.cgi?id=8743 --- Comment #10 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 03:17:42 PDT --- (In reply to comment #9) (In reply to comment #8) (In reply to comment #6) This mixin template is useful. A disadvantage is that it doesn't follow the API (usage) of the Phobos memoize. So maybe it needs a different name, like memoizeMethod, or something. Yes. I couldn't make it have the same syntax because of the requirement of the `this` reference. Also I'm unsure about recursive calls. And I think I've uncovered yet another bug: class A { int slowFunc(int a, int b) { int result; /* Error: function expected before (), not mixin memoize!(slowFunc) fastFunc; */ if (a 1) return fastFunc(a-1, b); return result; } mixin memoize!slowFunc fastFunc; } If I replace 'return fastFunc(a-1, b);' with 'return this.fastFunc(a-1, b)' it works. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8575] Lambda expression causes compilation error with template function
http://d.puremagic.com/issues/show_bug.cgi?id=8575 Kenji Hara k.hara...@gmail.com changed: What|Removed |Added Keywords||pull, rejects-valid --- Comment #1 from Kenji Hara k.hara...@gmail.com 2012-10-02 03:57:08 PDT --- https://github.com/D-Programming-Language/dmd/pull/1158 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8745] floating point comparison (is vs ==) inconsistency (on 32)
http://d.puremagic.com/issues/show_bug.cgi?id=8745 Rainer Schuetze r.sagita...@gmx.de changed: What|Removed |Added CC||r.sagita...@gmx.de --- Comment #3 from Rainer Schuetze r.sagita...@gmx.de 2012-10-02 11:16:06 PDT --- I haven't checked the disassembly, but I guess the problem of the failing comparison is caused by storing one value to memory as double (and doing some rounding on it along the way), while the other is still available on the FPU stack with real-precision. You might get different results when enabling optimizations. The is comparison is a bitwise comparison, so it will probably actually write both values to memory before the comparison, applying the same rounding to both results. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8655] bitfields and Typedef don't mix
http://d.puremagic.com/issues/show_bug.cgi?id=8655 --- Comment #1 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 16:04:02 PDT --- (In reply to comment #0) import std.typecons; import std.bitmanip; static import core.stdc.config; alias Typedef!(core.stdc.config.c_ulong) c_ulong; struct Foo { mixin(bitfields!( c_ulong, NameOffset, 31, c_ulong, NameIsString, 1 )); } void main() { } This is a problem with mixin template Proxy(alias a). It uses a template dispatch but doesn't take into account type properties (min, max, init..). Although this can be fixed another issue pops up: Error: e2ir: cannot cast result of type uint to type Typedef!(int,0) Here's the hackish temporary workaround of Proxy.opDispatch: template opDispatch(string name) { static if (canFind([min, max, init, sizeof, nan, mangleof, stringof, alignof, infinity, dig, epsilon, mant_dig, max_10_exp, max_exp, min_10_exp, min_exp, min_normal, re, im, classinfo], name)) { mixin(enum opDispatch = typeof(a). ~ name ~ ;); } else static if (is(typeof(__traits(getMember, a, name)) == function)) { // non template function auto ref opDispatch(this X, Args...)(Args args) { return mixin(a.~name~(args)); } } else static if (is(typeof(mixin(a.~name))) || __traits(getOverloads, a, name).length != 0) { // field or property function @property auto ref opDispatch(this X)(){ return mixin(a.~name);} @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin(a.~name~ = v); } } else { // member template template opDispatch(T...) { auto ref opDispatch(this X, Args...)(Args args){ return mixin(a.~name~!T(args)); } } } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8544] Expose cArgs in druntime
http://d.puremagic.com/issues/show_bug.cgi?id=8544 --- Comment #1 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 16:53:34 PDT --- I'd like to fix this myself. But I'm not sure how this should be exposed in the Runtime struct. Should it be two properties, 'argc' and 'argv', or a single property such as the following, in core.runtime: extern (C) CArgs rt_cArgs(); static @property string[] cArgs() { return rt_cArgs(); } and in src\rt\dmain2.d: struct CArgs { int argc char** argv; } __gshared CArgs _cArgs = null; extern (C) string[] rt_cArgs() { return _cArgs; } extern (C) int main(int argc, char** argv) { _cArgs.argc = argc; _cArgs.argv = argv; ... } Thoughts? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8544] Expose cArgs in druntime
http://d.puremagic.com/issues/show_bug.cgi?id=8544 --- Comment #2 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-10-02 16:54:34 PDT --- (In reply to comment #1) I'd like to fix this myself. But I'm not sure how this should be exposed in the Runtime struct. Should it be two properties, 'argc' and 'argv', or a single property such as the following, in core.runtime: extern (C) CArgs rt_cArgs(); static @property string[] cArgs() { return rt_cArgs(); } That should be: static @property CArgs cArgs() and extern (C) CArgs rt_cArgs() Obviously I'm just pseudocoding. :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 8544] Expose cArgs in druntime
http://d.puremagic.com/issues/show_bug.cgi?id=8544 Alex R�nne Petersen a...@lycus.org changed: What|Removed |Added CC||a...@lycus.org --- Comment #3 from Alex R�nne Petersen a...@lycus.org 2012-10-03 02:00:47 CEST --- I suppose it wouldn't be a problem to have a cArgs property on the Runtime struct. I'd prefer returning a struct over two separate properties. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---