Re: dmd 2.063 released with 260 bugfixes and enhancements
On Sat, 2013-06-01 at 09:36 -0700, Ellery Newcomer wrote: On 06/01/2013 02:31 AM, Russel Winder wrote: On Fri, 2013-05-31 at 13:50 -0700, Ellery Newcomer wrote: […] just tried it on ubuntu 12.10, and it does the same. are you using -defaultlib=libphobos2.so I suspect I may be doing different things from you as I never use an option of that sort. Perhaps we should agree a code and command to make the tests. the way I build is detailed in the makefile here: https://bitbucket.org/ariovistus/pyd/src/296ef002750411331ec9a3bcb14aed345b65d8d5/examples/misc/dmd_sharedlibs?at=default I cloned PyD – I have been intending to do this for ages to try D for Python extensions – and ran make in the directory you mentioned: | make gcc -c -fPIC so_ctor.c -o so_ctor.o dmd -unittest -fPIC -defaultlib=libphobos2.so -shared test1.d boilerplate.d so_ctor.o -oflibtest1.so #dmd -c -unittest -fPIC test1.d boilerplate.d -oftemp.o #dmd -shared -defaultlib=phobos2so temp.o so_ctor.o -oflibtest1.so gcc test1.c `pwd`/libtest1.so -o test1.x ./test1.x initing yawn. stretch. lets test this donut. foo(2)=6 dniting yawn. z -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: [Somewhat OT] Textadept 6.6 released
Looks good. Definitely will try.
Re: dmd 2.063 released with 260 bugfixes and enhancements
Am Sun, 2 Jun 2013 07:40:27 +0200 schrieb Marco Leise marco.le...@gmx.de: For some reason I still cannot build dmd 2.063 from the zip release. I mentioned it before the release on the beta and internals mailing lists and maybe I'm just overlooking something trivial, but when I run make I get: make: *** Keine Regel vorhanden, um das Target »irstate.h«, benötigt von »irstate.o«, zu erstellen. Schluss. irstate.c is there, but irstate.h is missing. Is that like last time when VERSION was missing? Ok, a pull request about that got merged. Let's see if it ends up in the .zip ;) -- Marco
Re: DConf 2013 Day 2 Talk 3: C# to D by Adam Wilson
On 2013-06-02 00:49, Adam Wilson wrote: Indeed, but since I was comparing to vanilla C# 4.0 and .NET I figured it was only fair to compare to DMD 2.062 and Phobos. Once you start comparing and contrasting third party libraries the scope of the topic quickly balloons in size. The biggest problem I had in putting this talk together was deciding what to cut. I ended up leaving about 60% of my originally planned content on the cutting room floor... I really wanted to give you guys more! Yes, sure, for the talk. But if you are actually going to port C# code to D I assume, and hope, you would take a practically approach. That is, using third party libraries if needed and not saying something like If it's not in Phobos we cannot use it. -- /Jacob Carlborg
Re: DConf 2013 Day 2 Talk 3: C# to D by Adam Wilson
On 2013-06-01 23:11, Jonathan M Davis wrote: There are quite a few things that Phobos is still missing, but this isn't one of them. We have std.datetime.StopWatch (which will probably end up in std.benchmark when that's finally complete). I haven't looked in std.datetime lately but I though I heard in the talk it was missing. If not, my mistake. -- /Jacob Carlborg
Re: dmd 2.063 released with 260 bugfixes and enhancements
On Sun, 2013-06-02 at 11:23 -0700, Ellery Newcomer wrote: […] who packages your dmd? Normally I would use the one from APT-D, but as this not at 2.063 as yet I used the deb downloaded from the D download page. This necessitates removing all packages from APT-D since they depend on exactly a given DMD version. I have this installed GtkD from master/HEAD and not got Vibe.d just at the minute. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
simpledisplay.d now works on as 64 bit on X
I know someone here was asking about my simpledisplay.d on 64 bit a while ago.. I don't remember who so here's a general announcement. I got it working for at least the parts I tried (display image, get keyboard input) compiled with -m64: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/simpledisplay.d Quite a hassle, my xlib binding was apparently almost completely wrong, and it worked on 32 bit just by sheer luck. Many of the structs were the wrong sizes even there! General tip to C porters: do a static assert(S.sizeof) and make sure it matches what your C program gives. I got snagged in part here because unsigned long in X is apparently 64 bit. I thought it was the same as D's uint in all cases. The file it also depends on color.d from the same repo. Another minor change is the key event used to take a delegate (int key){}. Now it takes (int key, bool pressed) instead. There's a static assert with a reminder message too, so just compile and if you need it, it will tell you. The (dchar){} event remains the same as before. Been a few random bug fixes in the last few months too, timer events now work right on windows and linux is the big one that comes to mind.
Re: dmd 2.063 released with 260 bugfixes and enhancements
On 06/02/2013 11:48 AM, Russel Winder wrote: On Sun, 2013-06-02 at 11:23 -0700, Ellery Newcomer wrote: […] who packages your dmd? Normally I would use the one from APT-D, but as this not at 2.063 as yet I used the deb downloaded from the D download page. This necessitates removing all packages from APT-D since they depend on exactly a given DMD version. I have this installed GtkD from master/HEAD and not got Vibe.d just at the minute. so we are using the same package. ?? oh. dpkg -L just doesn't list it. but it's definitely missing from the rpm.
Re: dmd 2.063 released with 260 bugfixes and enhancements
On Sun, 2013-06-02 at 12:48 -0700, Ellery Newcomer wrote: […] so we are using the same package. ?? oh. dpkg -L just doesn't list it. Symbolic links aren't in the deb, they are created by the post install script once the shared library is installed. but it's definitely missing from the rpm. Perhaps RPMs should have a post install script? -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: dmd 2.063 released with 260 bugfixes and enhancements
On 06/02/2013 12:56 PM, Russel Winder wrote: On Sun, 2013-06-02 at 12:48 -0700, Ellery Newcomer wrote: […] so we are using the same package. ?? oh. dpkg -L just doesn't list it. Symbolic links aren't in the deb, they are created by the post install script once the shared library is installed. but it's definitely missing from the rpm. Perhaps RPMs should have a post install script? you can package relative links in rpm. https://bitbucket.org/ariovistus/rpm-buildscripts/src/21921c736116a51f60db4ab9cb5852fc0ae0b63c/dmd-git2rpm?at=default#cl-293
Re: DConf 2013 Day 2 Talk 3: C# to D by Adam Wilson
On Sun, 02 Jun 2013 02:34:39 -0700, Jacob Carlborg d...@me.com wrote: On 2013-06-02 00:49, Adam Wilson wrote: Indeed, but since I was comparing to vanilla C# 4.0 and .NET I figured it was only fair to compare to DMD 2.062 and Phobos. Once you start comparing and contrasting third party libraries the scope of the topic quickly balloons in size. The biggest problem I had in putting this talk together was deciding what to cut. I ended up leaving about 60% of my originally planned content on the cutting room floor... I really wanted to give you guys more! Yes, sure, for the talk. But if you are actually going to port C# code to D I assume, and hope, you would take a practically approach. That is, using third party libraries if needed and not saying something like If it's not in Phobos we cannot use it. In real life I would absolutely use third party libraries where available. I would definitely recommend people do the same. In retrospect I probably should've said something to that effect in the closing of my talk ... So many things I would say differently! -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Re: DConf 2013 Day 2 Talk 3: C# to D by Adam Wilson
On Sun, 02 Jun 2013 02:35:37 -0700, Jacob Carlborg d...@me.com wrote: On 2013-06-01 23:11, Jonathan M Davis wrote: There are quite a few things that Phobos is still missing, but this isn't one of them. We have std.datetime.StopWatch (which will probably end up in std.benchmark when that's finally complete). I haven't looked in std.datetime lately but I though I heard in the talk it was missing. If not, my mistake. Most of System.Timers is missing from Phobos. There is a LOT more than just a stopwatch in it. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Re: simpledisplay.d now works on as 64 bit on X
I'm sorry to hear that you ran into the unsigned long problem. I noticed it in time and asked about it on the NG and was told that the difference is between Windows and Posix. One takes long as int32, the other as the native machine word size on 64-bit. We do the same stupid mistakes over and over. :p Also eventually we should generate X bindings for all platforms (including Windows) from the XML definitions like XCB does. That means a small core written in D that enables RPC to the X Server and a generator tool that creates functions, structs and DDoc from what is the XML files. (See /usr/share/xcb.) -- Marco
Re: simpledisplay.d now works on as 64 bit on X
On 6/2/13, Marco Leise marco.le...@gmx.de wrote: I'm sorry to hear that you ran into the unsigned long problem. This is why we have core.std.config: import core.stdc.config : c_long, c_ulong;
Re: D at University of Minnesota
This is awesome! I'm sure I speak on behalf of the entire community that we'd be happy to help with anything you need. There is, perhaps, a need for a short technical document bringing TDPL up to date, i.e. consistent with the currently accepted view of the definition of D (wherever that resides). No doubt this is not necessary and the course will go fine without it, but it would be useful, as well as being encouraging to those students who exercise some initiative.
Re: D at University of Minnesota
On Monday, June 03, 2013 00:29:09 Carl Sturtivant wrote: This is awesome! I'm sure I speak on behalf of the entire community that we'd be happy to help with anything you need. There is, perhaps, a need for a short technical document bringing TDPL up to date, i.e. consistent with the currently accepted view of the definition of D (wherever that resides). No doubt this is not necessary and the course will go fine without it, but it would be useful, as well as being encouraging to those students who exercise some initiative. And what about TDPL is so out of date? Its description of pure is that of strongly pure and thus is not fully correct, but from what I recall, almost everything in it that's not correct (aside from actually errors in the original text - which are covered by the errata) simply hasn't been implemented yet (e.g. multiple alias thises) and was not any more correct when TDPL was released than it is now. So, AFAIK, very little in TDPL is incorrect or actually needs to be updated, and almost all of what's incorrect is supposed to be corrected by the feature in question actually being implemented. - Jonathan M Davis
Re: simpledisplay.d now works on as 64 bit on X
On Sunday, 2 June 2013 at 22:16:57 UTC, Andrej Mitrovic wrote: This is why we have core.std.config: import core.stdc.config : c_long, c_ulong; I would never have thought to look in config for types! Well, hopefully I'll remember for next time.
Re: simpledisplay.d now works on as 64 bit on X
On Sunday, 2 June 2013 at 21:53:56 UTC, Marco Leise wrote: Also eventually we should generate X bindings for all platforms (including Windows) from the XML definitions like XCB does. hmm I don't see an xml file for Xlib.h on my system, do you know if there is supposed to be one? Though I'm pretty sure I have most of it correct now, so I guess it isn't really necessary. I know everybody says Xlib is dying but I still use it. It is simple enough and gets the job done without having to learn a whole thing library...
Re: simpledisplay.d now works on as 64 bit on X
Andrej Mitrovic: This is why we have core.std.config: import core.stdc.config : c_long, c_ulong; Why isn't that linked in this page? http://dlang.org/phobos/std_stdint.html I'd like to open a little documentation enhancement request for that. Bye, bearophile
Re: simpledisplay.d now works on as 64 bit on X
On 6/2/13 7:10 PM, bearophile wrote: Andrej Mitrovic: This is why we have core.std.config: import core.stdc.config : c_long, c_ulong; Why isn't that linked in this page? http://dlang.org/phobos/std_stdint.html I'd like to open a little documentation enhancement request for that. Bye, bearophile And while you are at it, please also contribute the corresponding pull request. Time to inaugurate bearophile's additions! Andrei
Re: simpledisplay.d now works on as 64 bit on X
Why isn't that linked in this page? http://dlang.org/phobos/std_stdint.html It seems it lacks some of them, this gives an import error: import core.stdc.config: c_ulonglong, c_longlong; Bye, bearophile
Re: simpledisplay.d now works on as 64 bit on X
On Sunday, 2 June 2013 at 23:19:18 UTC, bearophile wrote: It seems it lacks some of them, this gives an import error: It only defines c_long and c_ulong. I guess this is ok because the other types don't vary, though I kinda think it should do them all just so you can be consistent. Not long ago I thought int on 64 bit was 64 bit too, because int on 16 bit is 16 bit so I figured it just did that the whole way up. But no, C's int is always D's int. A nice c_int alias would make that mindless too, even though it isn't strictly necessary.
Re: simpledisplay.d now works on as 64 bit on X
Andrei Alexandrescu: And while you are at it, please also contribute the corresponding pull request. Time to inaugurate bearophile's additions! As my friend, please understand, I can't afford to get addicted to that :-) Hugs, bearophile
Re: simpledisplay.d now works on as 64 bit on X
On 6/3/13, bearophile bearophileh...@lycos.com wrote: Why isn't that linked in this page? http://dlang.org/phobos/std_stdint.html Because it's on this page: http://dlang.org/interfaceToC.html It seems it lacks some of them, this gives an import error: import core.stdc.config: c_ulonglong, c_longlong; Again see http://dlang.org/interfaceToC.html
Re: simpledisplay.d now works on as 64 bit on X
On Sunday, 2 June 2013 at 23:35:28 UTC, Andrej Mitrovic wrote: http://dlang.org/interfaceToC.html ah then what is this page doing there? http://dlang.org/htomodule.html The documentation could def use a lil cleanup.
Re: simpledisplay.d now works on as 64 bit on X
Andrej Mitrovic: Because it's on this page: http://dlang.org/interfaceToC.html It seems it lacks some of them, this gives an import error: import core.stdc.config: c_ulonglong, c_longlong; Again see http://dlang.org/interfaceToC.html Good, thank you. I missed that. Bye, bearophile
Re: simpledisplay.d now works on as 64 bit on X
On 6/3/13, Adam D. Ruppe destructiona...@gmail.com wrote: On Sunday, 2 June 2013 at 23:35:28 UTC, Andrej Mitrovic wrote: http://dlang.org/interfaceToC.html ah then what is this page doing there? http://dlang.org/htomodule.html The documentation could def use a lil cleanup. There's a bug report for everything: http://d.puremagic.com/issues/show_bug.cgi?id=7346 I'm like a handy little bugzilla bot. :p
Re: simpledisplay.d now works on as 64 bit on X
Am Mon, 03 Jun 2013 01:02:12 +0200 schrieb Adam D. Ruppe destructiona...@gmail.com: On Sunday, 2 June 2013 at 21:53:56 UTC, Marco Leise wrote: Also eventually we should generate X bindings for all platforms (including Windows) from the XML definitions like XCB does. hmm I don't see an xml file for Xlib.h on my system, do you know if there is supposed to be one? Though I'm pretty sure I have most of it correct now, so I guess it isn't really necessary. XCB is generated from these XML files. They have nothing to do with Xlib. You can find the XML files here: http://cgit.freedesktop.org/xcb/proto/tree/src A generator tool for the target language (C in this case) parses them and creates include files from them that define all the remote procedure calls to the X Server. Internally those calls rely on a small generic set of functions that serializes the requests for transmission. What is needed are those generic functions written in D to establish the connection to the server and handling serialization, probably relying on std.socket. And then an XML parser that would write out .d files for the different modules of the X Server, like xrandr, xkb and so on, which are all available as separate XML files. This is what a RPC from glx.xml looks like: request name=GenTextures opcode=145 field type=CONTEXT_TAG name=context_tag / field type=INT32 name=n / reply pad bytes=1 / pad bytes=24 / list type=CARD32 name=data fieldreflength/fieldref /list /reply /request In general they also include documentation tags which can be made available through DDoc automatically and displayed in IDEs like Mono-D already does. I know everybody says Xlib is dying but I still use it. It is simple enough and gets the job done without having to learn a whole thing library... The big deal about it is asynchronous RCP especially over internet connections to X Servers, since with Xlib you have to way for each response before the next request. -- Marco
Re: D at University of Minnesota
Maybe stuff added to the language? User-defined attributes, for instance. LMB On Sun, Jun 2, 2013 at 7:45 PM, Jonathan M Davis jmdavisp...@gmx.com wrote: On Monday, June 03, 2013 00:29:09 Carl Sturtivant wrote: This is awesome! I'm sure I speak on behalf of the entire community that we'd be happy to help with anything you need. There is, perhaps, a need for a short technical document bringing TDPL up to date, i.e. consistent with the currently accepted view of the definition of D (wherever that resides). No doubt this is not necessary and the course will go fine without it, but it would be useful, as well as being encouraging to those students who exercise some initiative. And what about TDPL is so out of date? Its description of pure is that of strongly pure and thus is not fully correct, but from what I recall, almost everything in it that's not correct (aside from actually errors in the original text - which are covered by the errata) simply hasn't been implemented yet (e.g. multiple alias thises) and was not any more correct when TDPL was released than it is now. So, AFAIK, very little in TDPL is incorrect or actually needs to be updated, and almost all of what's incorrect is supposed to be corrected by the feature in question actually being implemented. - Jonathan M Davis
Re: D at University of Minnesota
On Sunday, June 02, 2013 21:56:30 Leandro Motta Barros wrote: Maybe stuff added to the language? User-defined attributes, for instance. Sure, there's stuff that TDPL doesn't describe, but TDPL never described everything (for instance, it doesn't go into a detailed explanation of the various types of is expressions). But that's different from it being incorrect due to language changes, which seems to be what Carl is saying is happening. I'm sure that we'll get another edition of TDPL at some point, but as far as I can tell, aside from the errata (which indicates errors in the original text as opposed to anything that's changed in the language since), there are very few things in there that are wrong at this point, and almost all of them relate to features that have never been fully implemented and thus were as incorrect when TDPL was published as they are now (but hopefully won't be incorrect in the future). And even that list isn't very long. The only two that I can come up with off the top of my head is having multiple aliases thises and having synchronized classes instead of synchronized functions. - Jonathan M Davis
Re: simpledisplay.d now works on as 64 bit on X
On Monday, 3 June 2013 at 00:15:20 UTC, Marco Leise wrote: all the remote procedure calls to the X Server. Internally those calls rely on a small generic set of functions that serializes the requests for transmission. I see. I just skimmed an xcb tutorial and it isn't all that different than xlib so maybe I'll spend a weekend on it at some point and make it work in D. There's a few things we can do to make the async stuff pretty too, thanks to delegates and the sort. And perhaps I can add a concept of a sprite to simplediplay. This represents an XPixmap - distinct from an XImage in that it is on the server - or on Windows, we can probably just us an HBITMAP. These wouldn't offer direct pixel manipulation like simplediplay's current Image (which is an XImage and HBITMAP in implementation) but would be able to avoid transferring a lot of data to the X server. And lastly (optionally, like with terminal.d) tie it into my generic eventloop.d. Then we'll really be cooking with gas! It'll have to wait a while though, hacking on this stuff doesn't make my house payments :(
Re: Why is D slower than LuaJIT?
Am Wed, 22 Dec 2010 17:04:21 -0500 schrieb Andreas Mayer s...@bacon.eggs: To see what performance advantage D would give me over using a scripting language, I made a small benchmark. It consists of this code: auto L = iota(0.0, 1000.0); auto L2 = map!a / 2(L); auto L3 = map!a + 2(L2); auto V = reduce!a + b(L3); It runs in 281 ms on my computer. The same code in Lua (using LuaJIT) runs in 23 ms. That's about 10 times faster. I would have expected D to be faster. Did I do something wrong? Actually D is 1.5 times faster on my computer*: LDC** 18 ms GDC*** === 25 ms LuaJIT 2.0.0 b7 27 ms DMD = 93 ms All compilers based on DMD 2.062 front-end. * 64-bit Linux, 2.0 Ghz Mobile Core 2 Duo. ** based on LLVM 3.2 *** based on GCC 4.7.2 I modified the iota template to more closely reflect the one used in the original Lua code: - import std.algorithm; import std.stdio; import std.traits; auto iota(B, E)(B begin, E end) if (isFloatingPoint!(CommonType!(B, E))) { alias CommonType!(B, E) Value; static struct Result { private Value start, end; @property bool empty() const { return start = end; } @property Value front() const { return start; } void popFront() { start++; } } return Result(begin, end); } void main() { auto L = iota(0.0, 1000.0), L2 = map!(a = a / 2)(L), L3 = map!(a = a + 2)(L2), V = reduce!((a, b) = a + b)(L3); writefln(%f, V); } -- Marco
Re: A Small Contribution to Phobos
On Sunday, 2 June 2013 at 04:10:15 UTC, Jonathan M Davis wrote: On Sunday, June 02, 2013 04:57:53 Meta wrote: The callable bit won't work. It'll just call front. You'd have to do something like static if(isCallable!(ElementType!R)) r.front()(); Also, if front were pure, then calling it and doing nothing with its return value would result in a compilation error. The same goes if the element type is a pure callable. Calling front is kind of the point of exhaust(), otherwise you'd use takeNone(). You wouldn't use this if front were pure because the only reason you'd want exhaust is if you were (ab)using side effects (like I was the other day on D.learn). Having it error out if you were using it on a range with pure front() is actually a good thing because you've made some error in your reasoning if you think you want exhaust() to run in that situation. processSideEffects() is probably too long of name. And even if this did work exactly as you intended. I think that assuming that someone exhausting the range would would what front returns to be called is a bad idea. Maybe they do, maybe they don't, I'd expect that in most cases, they wouldn't. If that's what they want, they can call map before calling exhaust. Sticking a map before exhaust without it calling front() would accomplish nothing. I know this because my own little toy eat() just called popFront() originally on a Map range and nothing happened. You'd be skipping map's function if you don't call front.
Re: Labels as values and threaded-code interpretation
Am 02.06.2013 06:49, schrieb Walter Bright: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. I always have fun in public forums making people aware that what they think is C or C++ code is actually compiler defined behaviour. Not much people seem to care to read language standards. :) -- Paulo
Re: A Small Contribution to Phobos
For reference type ranges and input ranges which are not forward ranges, this will consume the range and return nothing. I originally wrote it to accept forward ranges and use save, but I wanted to make it as inclusive as possible. I guess I overlooked the case of ref ranges. As for ranges that aren't forward ranges, consider a simple input range. struct InputRange { int[] arr = [1, 2, 3, 4, 5]; int front() { return arr.front; } bool empty() { return arr.empty; } void popFront() { return arr.popFront; } } writeln(isForwardRange!InputRange); //False Range() .each!(n = write(n, )) .map!(n = n * n) .writeln; This outputs 1 2 3 4 5 [1, 4, 9, 16, 25], so each is not returning an empty range. I believe this is because r in this case is a value type range, and the foreach loop makes a copy of it. This does still leave the problem of reference type ranges. Also, range-based functions should not be strict (i.e. not lazy) without good reason. And I don't see much reason to make this strict. It's not lazy because it's intended to perform some mutating or otherwise side-effectful operation. Map doesn't play well with side effects, partially because of its laziness. A very contrived example: auto arr = [1, 2, 3, 4].map!(n = n.writeln); //Now what? It's not clear now what to do with the result. You could try a for loop: foreach (n; arr) n(); //Error: n cannot be of type void But that doesn't work. A solution would be to modify the function you pass to map: auto arr = [1, 2, 3, 4].map!((n) { n.writeln; return n; }); foreach (n; arr) {} //Prints 1 2 3 4 But that's both ugly and verbose. each also has the advantage of being able to return the original range (possibly modified), whereas map must return a MapResult due to its laziness, and you need that extra array call to bludgeon it into the correct form. each is also more efficient in that it doesn't need to return a copy of the data passed to it. It simply mutates it in-place. Also, it's almost the same thing as map. Why not just use map? The predicate can simply return the same value after it's operated on it. See above. There are some cases where map is clunky to work with due to it being non-strict. If we did add this, I'd argue that transform is a better name, but I'm still inclined to think that it's not worth adding. I chose the name each because it's a common idiom in a couple of other languages (Javascript, Ruby and Rust off the top of my head), and because I think it underlines the fact that each is meant to perform side-effectful operations. exhaust iterates a range until it is exhausted. It also has the nice feature that if range.front is callable, exhaust will call it upon each iteration. Range exhaust(Range)(Range r) if (isInputRange!(Unqual!Range)) { while (!r.empty) { r.front(); r.popFront(); } return r; } //Writes www.dlang.org. x is an empty MapResult range. auto x = www.dlang.org .map!((c) { c.write; return false; }) .exhaust; //Prints [] [1, 2, 3].exhaust.writeln; The callable bit won't work. It'll just call front. You'd have to do something like static if(isCallable!(ElementType!R)) r.front()(); I was having some trouble with writing exhaust and forgot all about ElementType. I'll change that. Also, if front were pure, then calling it and doing nothing with its return value would result in a compilation error. The same goes if the element type is a pure callable. Is this true for all pure functions? That seems like kind of strange behaviour to me, and doesn't really make sense given the definition of functional purity. And even if this did work exactly as you intended. I think that assuming that someone exhausting the range would would what front returns to be called is a bad idea. Maybe they do, maybe they don't, I'd expect that in most cases, they wouldn't. If that's what they want, they can call map before calling exhaust. I think the original reason that somebody wanted exhaust was because map is lazy and they wanted a function which could take the result of map and consume it while calling front each time. Otherwise, there wouldn't be much reason to have this, as there is takeNone and popFrontN. So, you want to have a function which you pass something (including a range) and then returns that same value after calling some other function? Does this really buy you much over just splitting up the expression - you're already giving a multline example anyway. It gives you the advantage of not having to split your UFCS chain up, which I personally find valuable, and I think other people would as well. I think it's quite similar to the various side-effectful monads in Haskell, which don't do anything with their argument other than return it, but perform some operation with side-effects in the process. I'll try to think up a better example for this, because I think
Re: Labels as values and threaded-code interpretation
On 6/1/13 9:49 PM, Walter Bright wrote: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. Also, such a construct could not be made @safe. The trouble is you could pass those addresses anywhere, and goto them from anywhere. While you're technically correct, every major compiler in the unix world support it with the same syntax. It's entered into defacto standard status.
Re: Slow performance compared to C++, ideas?
On 2 June 2013 01:19, Paulo Pinto pj...@progtools.org wrote: Am 01.06.2013 16:24, schrieb Benjamin Thaut: Am 01.06.2013 01:30, schrieb Manu: On 1 June 2013 09:15, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: On 1 June 2013 01:12, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: Frankly, this is a textbook example of why STL is the spawn of satan. For some reason people are TAUGHT that it's reasonable to write code like this. There are many kinds of D code, not everything is a high performance ray-tracer or 3D game. So I'm sure there are many many situations where using the C++ STL is more than enough. As most tools, you need to know where and when to use them. So it's not a Satan-spawn :-) So why are we having this conversation at all then if faster isn't better in this instance? Faster is better in this instance. What's wrong is your thinking that the STL as the spawn of Satan in general. Ah, but that's because it is ;) Rule of thumb: never use STL in tight loops. problem solved (well, mostly)... I have to agree here. Whenever you have a codebase that has to work on 9 platforms and 6 compilers the S in STL vanishes. Also the implementations are so varying in quality that you might get really good performance on one platform but really bad on another. It seems like everyone in the games industry avoids STL like the plague. Kind Regards Benjamin Thaut I used to have that experience even with C, when I started using it around 1994. C++ was even worse between CFront, ARM and ongoing standardization work. As for STL, I can assure that HPC guys are huge fans of STL and Boost. The funny thing about HPC guys though, at least in my experience (a bunch of researchers from Cambridge who I often give _basic_ optimisation tips), is they don't write/run 'high performance software', they're actually pretty terrible programmers and have a tendency to write really low performing software, but run it on super high performance computers, and then call the experience high performance computing... It bends my mind to see them demand an order of magnitude more computing power to run an algorithm that's hamstrung by poor choices of containers or algorithms that probably cost them an order of magnitude in performance ;) And then the Universities take their demands seriously and deliver them more hardware! O_O At least when I did my traineeship at CERN (2003-2004) that was the case. I hope CERN has better software engineers than Cambridge University ;) Most of these guys are mathematicians and physicists first, and programmers second.
Re: Labels as values and threaded-code interpretation
Am 02.06.2013 09:25, schrieb Brad Roberts: On 6/1/13 9:49 PM, Walter Bright wrote: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. Also, such a construct could not be made @safe. The trouble is you could pass those addresses anywhere, and goto them from anywhere. While you're technically correct, every major compiler in the unix world support it with the same syntax. It's entered into defacto standard status. If your world is only UNIX then yeah, there are still lots of non UNIX os out there if you look outside the desktop computers. Of course, one could always question if they matter at all.
Re: Labels as values and threaded-code interpretation
On 6/2/13 12:33 AM, Paulo Pinto wrote: Am 02.06.2013 09:25, schrieb Brad Roberts: On 6/1/13 9:49 PM, Walter Bright wrote: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. Also, such a construct could not be made @safe. The trouble is you could pass those addresses anywhere, and goto them from anywhere. While you're technically correct, every major compiler in the unix world support it with the same syntax. It's entered into defacto standard status. If your world is only UNIX then yeah, there are still lots of non UNIX os out there if you look outside the desktop computers. Of course, one could always question if they matter at all. I agree. I said unix primarily to mean most except for msvc. Many if not most of those non-unix platforms use gcc, which is included in the set of compilers that does support it. The point is, which you didn't change, is that's it's a defacto standard even if not technically in the c or c++ language specs.
Re: Slow performance compared to C++, ideas?
On Saturday, 1 June 2013 at 21:14:43 UTC, Marco Leise wrote: Does it really change anything? Today people forget the final keyword and tomorrow they forget the virtual keyword? :D What you prefer here depends on what languages you are used to do (e.g. C++, Java), how much you use OOP for anything, your use of unittesting and mock objects, your need for speed etc. I actually use that quite a lot. Additionally compiler technology exists now to finalize methods that aren't overriden. It is also possible to generate code that replace the virtual dispatch by an simple if if only 2 overrides exists, or even provide a fast path for the most common override, only conditionally doing the virtual dispatch. In other terms, as long as the compiler know about all the overrides, it can do better than the programmer manually annotating final/virtual.
Re: What exactly does @safe mean?
On Saturday, 1 June 2013 at 22:15:00 UTC, Jonathan M Davis wrote: On Saturday, June 01, 2013 23:41:32 monarch_dodra wrote: OK. But by that standard, can't (mostly) anything be trusted? What about something that writes garbage, to a memory location it was *asked* to write to? Or if wrong usage of the function can lead to an inconsistence memory state, but without out of bounds accesses? When a programmer marks a function as @trusted, they are saying that they guarantee that the function will not do anything to corrupt memory. So, yes, a programmer could mark absolutely anything as @trusted - including stuff that is blatantly unsafe and will do all kinds of nasty stuff - but that's the programmer's fault. Well, by mostly, I did mean stuff that's not blatantly wrong. I don't usually write stuff with the express objective of clobbering memory. But given the previous answers, I think I see why anything that should work can't be marked @safe. But still, if I were to give emplace an already constructed object, it will happily clobber that object for me, leaking the destructor, and possibly putting the program in an invalid memory state. Now, it was *my* fault for calling emplace with an already built object, but it was the (@trusted) emplace that clobbered-it. Well, given that the safety of the operation relies on what's being passed in, the operation itself can't reasonably be marked as @safe, because you can't guarantee that the operation isn't going to corrupt memory. But isn't that exactly the same as my void foo(int* p) @safe{*p = 0} example ? That relies on what is being passed in to guarantee safety :/ @confused
Re: Slow performance compared to C++, ideas?
On Friday, 31 May 2013 at 09:43:05 UTC, Manu wrote: - Require explicitly export when you want to create shared objects. This one is an enabler for an optimizer to finalize virtual method. With this mechanism in place, the compile knows all the override and can finalize many calls during LTO. I especially like that one as it allow for stripping many symbols at link time and allow for other LTO in general (for instance, the compiler can choose custom calling conventions for some methods, knowing all call sites). The explicit export one have my preference, however, ti require that symbol used in shared lib are explicitly declared export. I think we shouldn't break the virtual by default behavior, but we still need to figure out a way to make thing more performant on this point. You're concerned about the magnitude of breakage introducing an explicit virtual requirement. This would seem to be a much much bigger breakage to me, and I don't think it's intuitive. Officially, we are just starting to support shared object. I know you use them, and that this is a breakage to you. However, I think it is reasonable to expect that most people do not. Still, the migration should be carefully handled. This change is actually a fairly big deal as it empower the optimizer quite a lot, and not only for virtual functions. It can do way more than the dev could manually annotating any function. This is proven technology, not the sufficiently smart compiler here. Ti be fair, I'd push for this change even if final was the default, as it enable for many other optimizations. As the example shown, manually annotating everything isn't going to provide 5% to 7%, which irrelevant in most code path, and when a compiler could improve the situation significantly automatically.
Re: DMD under 64-bit Windows 7 HOWTO
The last issue is the announcement that VS 2012 update 3 is the last one and developers will need to buy VS.Next for the remaining C++11 updates and the by side updates are actually not going to happen. I think they will start a new release circle of product, but compiler tools will remain free as beer.
Re: Slow performance compared to C++, ideas?
Am 02.06.2013 08:33, schrieb Manu: On 2 June 2013 01:19, Paulo Pinto pj...@progtools.org mailto:pj...@progtools.org wrote: [...] At least when I did my traineeship at CERN (2003-2004) that was the case. I hope CERN has better software engineers than Cambridge University ;) Most of these guys are mathematicians and physicists first, and programmers second. I was on the Atlas group that does real time processing from the data coming out of the particle accelerator, as a way to filter out uninteresting data. And also offline multicore clustered data analysis of the saved data. They even rewrote the network stack to bypass the latency introduced by IP protocols. You are right on the guys backgrounds, but on our case we had monthly meetings about performance of the whole stack, to look for spots worth improving. -- Paulo
Re: What exactly does @safe mean?
On Sunday, June 02, 2013 09:59:08 monarch_dodra wrote: On Saturday, 1 June 2013 at 22:15:00 UTC, Jonathan M Davis wrote: On Saturday, June 01, 2013 23:41:32 monarch_dodra wrote: Now, it was *my* fault for calling emplace with an already built object, but it was the (@trusted) emplace that clobbered-it. Well, given that the safety of the operation relies on what's being passed in, the operation itself can't reasonably be marked as @safe, because you can't guarantee that the operation isn't going to corrupt memory. But isn't that exactly the same as my void foo(int* p) @safe{*p = 0} example ? That relies on what is being passed in to guarantee safety :/ @confused I don't know. The function isn't doing anything unsafe in and of itself. foo _can_ be marked as @safe, because none of the operations that it's doing are unsafe. The problem is when the caller does something unsafe. So, maybe that's the answer. It's the caller which can't be marked as @safe, because it's doing something stupid. foo isn't doing anything unsafe, so it _can_ be @safe. I think that part of the problem is the fact that @safety is generally viewed with the idea that unsafe stuff is called by safe stuff and not that unsafe stuff is called by safe stuff. And these cases under discussion are cases where the safe stuff ends up corrupting stuff if called from unsafe stuff. So, maybe emplace should be marked as @trusted (assuming that it can't corrupt anything if called from an @safe function and that its safety does not depend on its arguments). It _is_ a bit of a tough topic though. - Jonathan M Davis
Re: Labels as values and threaded-code interpretation
01-Jun-2013 20:13, Timon Gehr пишет: On 06/01/2013 07:29 AM, Alex Rønne Petersen wrote: Hi, I'm sure this has been brought up before, but I feel I need to bring it up again (because I'm going to be writing a threaded-code interpreter): http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html This is an incredibly important extension. The final switch statement is not a replacement because it doesn't allow the programmer to store a label address directly into a code stream, which is what's essential to write a threaded-code interpreter. I'd also like to see this. Same here. Though I believe a way to force tail-call can support the same use case also helping functional programming. Say: goto Call-Expression; //forced tail call instead of: return Call-Expression; -- Dmitry Olshansky
Re: Labels as values and threaded-code interpretation
On Saturday, 1 June 2013 at 05:29:28 UTC, Alex Rønne Petersen wrote: Hi, I'm sure this has been brought up before, but I feel I need to bring it up again (because I'm going to be writing a threaded-code interpreter): http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html This is an incredibly important extension. The final switch statement is not a replacement because it doesn't allow the programmer to store a label address directly into a code stream, which is what's essential to write a threaded-code interpreter. The Erlang folks went through hell just to use this feature; see the 5th Q at: http://www.erlang.org/doc/installation_guide/INSTALL-WIN32.html#Frequently-Asked-Questions It would also solve the problem with IASM and being unable to address the labels in iasm I noticed the problem when I tried to address the db'ed bytes. http://dpaste.dzfl.pl/36bbd7d3 Commented out //mov dword ptr RAX, meh; ??? illustrates the problem. Jumping to labels in IASM blocks seems to work ( http://dpaste.dzfl.pl/d9e47f70 ). I guess we could have two chickens backed on the same fire ;)
Re: Slow performance compared to C++, ideas?
On 06/01/2013 04:58 PM, finalpatch wrote: However I retested on a windows 7 machine with GDC compiler and the results were very different. orignal: 545ms * the first 2 optimizations which helped the most on OSX with LDC has almost zero effect * hand unroll overloaded vector arithmetic operators - 280ms (265ms improvment) * final to all class methods - 200ms (80ms improvment) What flags were you using with each compiler?
Re: Slow performance compared to C++, ideas?
Hi Joseph, The flags I used OSX LDC: -O3 -release WIN GDC: -O3 -fno-bounds-check -frelease Joseph Rushton Wakeling joseph.wakel...@webdrake.net writes: On 06/01/2013 04:58 PM, finalpatch wrote: However I retested on a windows 7 machine with GDC compiler and the results were very different. orignal: 545ms * the first 2 optimizations which helped the most on OSX with LDC has almost zero effect * hand unroll overloaded vector arithmetic operators - 280ms (265ms improvment) * final to all class methods - 200ms (80ms improvment) What flags were you using with each compiler? -- finalpatch
Re: Runtime reflection idea
I think this is a very good idea. The only question is how complete this RTTI should be. This again highly depends on what it will be used for. For some users it might be ok to do a full RTTI, which will increase the executable size significantly. Other users might prefer a minimal RTTI or even no RTTI at all depending on the use case. The RTInfo template is very usefull for many different tasks, the question is if we shouldn't make the concept more generic so that you can have multiple templates which behave like the RTInfo template. I'm currently also using it for RTTI info see: http://3d.benjamin-thaut.de/?p=25 -- Kind Regards Benjamin Thaut
Re: Labels as values and threaded-code interpretation
On 2 June 2013 17:25, Brad Roberts bra...@puremagic.com wrote: On 6/1/13 9:49 PM, Walter Bright wrote: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. Also, such a construct could not be made @safe. The trouble is you could pass those addresses anywhere, and goto them from anywhere. While you're technically correct, every major compiler in the unix world support it with the same syntax. It's entered into defacto standard status. MSVC doesn't support it, which is really annoying.
Re: Slow performance compared to C++, ideas?
On 2013-06-01 23:08, Jonathan M Davis wrote: If you don't need polymorphism, then in general, you shouldn't use a class (though sometimes it might make sense simply because it's an easy way to get a reference type). Where it becomes more of a problem is when you need a few polymorphic functions and a lot of non-polymorphic functions (e.g. when a class has a few methods which get overridden and then a lot of properties which it makes no sense to override). In that case, you have to use a class, and then you have to mark a lot of functions as final. This is what folks like Manu and Don really don't like, particularly when they're in environments where the extra cost of the virtual function calls actually matters. If a reference type is needed but not a polymorphic type, then a final class can be used. -- /Jacob Carlborg
Re: Slow performance compared to C++, ideas?
On Sunday, June 02, 2013 11:53:26 Jacob Carlborg wrote: On 2013-06-01 23:08, Jonathan M Davis wrote: If you don't need polymorphism, then in general, you shouldn't use a class (though sometimes it might make sense simply because it's an easy way to get a reference type). Where it becomes more of a problem is when you need a few polymorphic functions and a lot of non-polymorphic functions (e.g. when a class has a few methods which get overridden and then a lot of properties which it makes no sense to override). In that case, you have to use a class, and then you have to mark a lot of functions as final. This is what folks like Manu and Don really don't like, particularly when they're in environments where the extra cost of the virtual function calls actually matters. If a reference type is needed but not a polymorphic type, then a final class can be used. Yes. The main problem is when you have a class with a few methods which should be virtual and a lot that don't. You're forced to mark a large number of functions as final. That burden can be lessened by using final with a colon rather than marking them individually, but rather what seems to inevitably happen is that programmers forget to mark any of them as final (Manu can rant quite a bit about that, as he's had to deal with it at work, and it's cost him quite a bit of time, as he has to go through every function which wasn't marked as final and determine whether it's actuallly supposed to be virtual or not). Having non-virtual be the default makes functions efficient by default. - Jonathan M Davis
Re: Slow performance compared to C++, ideas?
On 06/02/2013 11:32 AM, finalpatch wrote: The flags I used OSX LDC: -O3 -release WIN GDC: -O3 -fno-bounds-check -frelease Does adding -inline make a difference to initial performance (i.e. before your manual interventions)? I guess it's already covered by -O3 in both cases, but a while back I did notice some differences in default LDC and GDC performance that seemed to relate to inlining.
Re: Slow performance compared to C++, ideas?
On 2 June 2013 12:05, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 06/02/2013 11:32 AM, finalpatch wrote: The flags I used OSX LDC: -O3 -release WIN GDC: -O3 -fno-bounds-check -frelease Does adding -inline make a difference to initial performance (i.e. before your manual interventions)? I guess it's already covered by -O3 in both cases, but a while back I did notice some differences in default LDC and GDC performance that seemed to relate to inlining. -O3 is covered in the GDC case (turns on -finline-functions). -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: Slow performance compared to C++, ideas?
On Sunday, 2 June 2013 at 07:32:10 UTC, Manu wrote: On 2 June 2013 01:19, Paulo Pinto pj...@progtools.org wrote: Am 01.06.2013 16:24, schrieb Benjamin Thaut: Am 01.06.2013 01:30, schrieb Manu: On 1 June 2013 09:15, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: On 1 June 2013 01:12, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: Frankly, this is a textbook example of why STL is the spawn of satan. For some reason people are TAUGHT that it's reasonable to write code like this. There are many kinds of D code, not everything is a high performance ray-tracer or 3D game. So I'm sure there are many many situations where using the C++ STL is more than enough. As most tools, you need to know where and when to use them. So it's not a Satan-spawn :-) So why are we having this conversation at all then if faster isn't better in this instance? Faster is better in this instance. What's wrong is your thinking that the STL as the spawn of Satan in general. Ah, but that's because it is ;) Rule of thumb: never use STL in tight loops. problem solved (well, mostly)... I have to agree here. Whenever you have a codebase that has to work on 9 platforms and 6 compilers the S in STL vanishes. Also the implementations are so varying in quality that you might get really good performance on one platform but really bad on another. It seems like everyone in the games industry avoids STL like the plague. Kind Regards Benjamin Thaut I used to have that experience even with C, when I started using it around 1994. C++ was even worse between CFront, ARM and ongoing standardization work. As for STL, I can assure that HPC guys are huge fans of STL and Boost. The funny thing about HPC guys though, at least in my experience (a bunch of researchers from Cambridge who I often give _basic_ optimisation tips), is they don't write/run 'high performance software', they're actually pretty terrible programmers and have a tendency to write really low performing software, but run it on super high performance computers, and then call the experience high performance computing... It bends my mind to see them demand an order of magnitude more computing power to run an algorithm that's hamstrung by poor choices of containers or algorithms that probably cost them an order of magnitude in performance ;) And then the Universities take their demands seriously and deliver them more hardware! O_O At least when I did my traineeship at CERN (2003-2004) that was the case. I hope CERN has better software engineers than Cambridge University ;) Most of these guys are mathematicians and physicists first, and programmers second. In my experience, physicists are terrible programmers. I should know, I am one! As soon as you step outside the realm of simple, 10kloc, pure procedural code, the supposed HPC guys don't generally have the first clue how to write something fast. CERN is responsible for the abomination that is ROOT, but to be fair to them there is a lot of good code from there too.
Re: Slow performance compared to C++, ideas?
On 06/02/2013 08:33 AM, Manu wrote: Most of these guys are mathematicians and physicists first, and programmers second. You've hit the nail on the head, but it's also a question of priorities. It's _essential_ that the maths or physics be understood and done right. It's essential that the programs correctly reflect that maths or physics. It's merely _desirable_ that the programs run as fast as possible, or be well designed from a maintenance point of view, or any of the other things that matter to trained software developers. (In my day job I have to continually force myself to _not_ refactor or optimize my code, even though I'd get a lot of pleasure out of doing so, because it's working adequately and my work priority is to get results out of it.) That in turn leads to a hiring situation where the preference is to have mathematicians or physicists who can program, rather than programmers who can learn the maths. It doesn't help that because of the way academic funding is made available, the pay scales mean that it's not really possible to attract top-level developers (unless they have some kind of keen moral desire to work on academic research); in addition, you usually have to hire them as PhD students or postdocs or so on (I've also seen masters' students roped in to this end), which obviously constrains the range of people that you can hire and the range of skills that will be available, and also the degree of commitment these people can put into long-term vision and maintenance of the codebase. There's also a training problem -- in my experience, most physics undergraduates are given a crash course in C++ in their first year and not much in the way of real computer science or development training. In my case as a maths undergraduate the first opportunity to learn programming was in the 3rd year of my degree course, and it was a crash course in a very narrow subset of C dedicated towards numerical programming. And if (like me) you then go on into research, you largely have to self-teach, which can lead to some very idiosyncratic approaches. I hope that this will change, because programming is now an absolutely essential part of just about every avenue of scientific research. But as it stands, it's a serious problem.
Re: Slow performance compared to C++, ideas?
Am 02.06.2013 13:08, schrieb John Colvin: On Sunday, 2 June 2013 at 07:32:10 UTC, Manu wrote: On 2 June 2013 01:19, Paulo Pinto pj...@progtools.org wrote: Am 01.06.2013 16:24, schrieb Benjamin Thaut: Am 01.06.2013 01:30, schrieb Manu: On 1 June 2013 09:15, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: On 1 June 2013 01:12, bearophile bearophileh...@lycos.com mailto:bearophileHUGS@lycos.**com bearophileh...@lycos.com wrote: Manu: Frankly, this is a textbook example of why STL is the spawn of satan. For some reason people are TAUGHT that it's reasonable to write code like this. There are many kinds of D code, not everything is a high performance ray-tracer or 3D game. So I'm sure there are many many situations where using the C++ STL is more than enough. As most tools, you need to know where and when to use them. So it's not a Satan-spawn :-) So why are we having this conversation at all then if faster isn't better in this instance? Faster is better in this instance. What's wrong is your thinking that the STL as the spawn of Satan in general. Ah, but that's because it is ;) Rule of thumb: never use STL in tight loops. problem solved (well, mostly)... I have to agree here. Whenever you have a codebase that has to work on 9 platforms and 6 compilers the S in STL vanishes. Also the implementations are so varying in quality that you might get really good performance on one platform but really bad on another. It seems like everyone in the games industry avoids STL like the plague. Kind Regards Benjamin Thaut I used to have that experience even with C, when I started using it around 1994. C++ was even worse between CFront, ARM and ongoing standardization work. As for STL, I can assure that HPC guys are huge fans of STL and Boost. The funny thing about HPC guys though, at least in my experience (a bunch of researchers from Cambridge who I often give _basic_ optimisation tips), is they don't write/run 'high performance software', they're actually pretty terrible programmers and have a tendency to write really low performing software, but run it on super high performance computers, and then call the experience high performance computing... It bends my mind to see them demand an order of magnitude more computing power to run an algorithm that's hamstrung by poor choices of containers or algorithms that probably cost them an order of magnitude in performance ;) And then the Universities take their demands seriously and deliver them more hardware! O_O At least when I did my traineeship at CERN (2003-2004) that was the case. I hope CERN has better software engineers than Cambridge University ;) Most of these guys are mathematicians and physicists first, and programmers second. In my experience, physicists are terrible programmers. I should know, I am one! As soon as you step outside the realm of simple, 10kloc, pure procedural code, the supposed HPC guys don't generally have the first clue how to write something fast. CERN is responsible for the abomination that is ROOT, but to be fair to them there is a lot of good code from there too. There was an office there that had the sentence You can program Fortran in any language on the door. :) -- Paulo
Re: A Small Contribution to Phobos
Meta: perform is pretty badly named, but I couldn't come up with a better one. It can be inserted in a UFCS chain and perform some operation with side-effects. It doesn't alter its argument, just returns it for the next function in the chain. T perform(alias dg, T)(ref T val) { dg(); return val; } //Prints Mapped: 2 4 [1, 2, 3, 4, 5] .filter!(n = n 3) .map!(n = n * n) .perform!({write(Mapped: );}) .each!(n = write(n, )); I'd like something like this in Phobos, but I'd like it to have a better name. But in most (all?) cases what I want to put inside such perform is a printing function, so I have opened this: http://d.puremagic.com/issues/show_bug.cgi?id=9882 exhaust iterates a range until it is exhausted. It also has the nice feature that if range.front is callable, exhaust will call it upon each iteration. Range exhaust(Range)(Range r) if (isInputRange!(Unqual!Range)) { while (!r.empty) { r.front(); r.popFront(); } return r; } //Writes www.dlang.org. x is an empty MapResult range. auto x = www.dlang.org .map!((c) { c.write; return false; }) .exhaust; //Prints [] [1, 2, 3].exhaust.writeln; I's also like this in Phobos, for debugging purposes. But I'd like it to return nothing, so you are forced to use it only at the end of a chain. (So I appreciate 2 of your 4 proposals. I have proposed both of them in D.learn time ago.) - Brad Anderson: Andrei didn't care for the tap() you propose but loved the idea of a tap() function that works like unix tee. Something like this Python itertool? def tee(iterable, n=2): it = iter(iterable) deques = [collections.deque() for i in range(n)] def gen(mydeque): while True: if not mydeque: # when the local deque is empty newval = next(it) # fetch a new value and for d in deques:# load it to all the deques d.append(newval) yield mydeque.popleft() return tuple(gen(d) for d in deques) Bye, bearophile
Re: Slow performance compared to C++, ideas?
Joseph, IIRC -inline is a DMD specific switch. Adding this to gdc command line produces this: gdc.exe: error: unrecognized command line option '-inline' Besides, the improvements mainly come from unrolling short loops not from inlining. Joseph Rushton Wakeling joseph.wakel...@webdrake.net writes: On 06/02/2013 11:32 AM, finalpatch wrote: The flags I used OSX LDC: -O3 -release WIN GDC: -O3 -fno-bounds-check -frelease Does adding -inline make a difference to initial performance (i.e. before your manual interventions)? I guess it's already covered by -O3 in both cases, but a while back I did notice some differences in default LDC and GDC performance that seemed to relate to inlining. -- finalpatch
Re: A Small Contribution to Phobos
On 6/2/13 1:58 AM, Meta wrote: For reference type ranges and input ranges which are not forward ranges, this will consume the range and return nothing. I originally wrote it to accept forward ranges and use save, but I wanted to make it as inclusive as possible. I guess I overlooked the case of ref ranges. [snip] Thanks for sharing your ideas. I think consuming all of a range evaluating front and doing nothing should be the role of reduce with only one parameter (the range). That overload would take the range to be exhausted and return void. Thus your example becomes: [1, 2, 3, 4].map!(n = n.writeln).reduce; Andrei
Error after installing DMD v2.063
Hi, I get the following error while running a simple hello world program compiled with the new v2.063 compiler. This is on Ubuntu 12.04. error while loading shared libraries: libphobos2.so.0.63: cannot open shared object file: No such file or directory
Re: Slow performance compared to C++, ideas?
But avoiding heap allocations for array literals is a change that needs to be discussed. In the meantime I have written a small ER regarding escape analysis for dynamic arrays: http://d.puremagic.com/issues/show_bug.cgi?id=10242 Bye, bearophile
Re: A Small Contribution to Phobos
Andrei Alexandrescu: [1, 2, 3, 4].map!(n = n.writeln).reduce; I have to shot this down for many reasons: I think it's better to give that final function a different name (like consume or something like that) because it's used for very different purposes and it returns nothing. Re-using the name reduce doesn't reduce the amount of Phobos lines of code, it doesn't make the user code simpler to understand, it's more obscure because it's more semantically overloaded, and it's not more easy to find in the documentation by the future D users. Function names are not language keywords, packing different purposes in the same name as static doesn't give any advantage, and only disadvantages. And using map with a lambda that returns nothing is not a style I like :-( It's probably better to encourage D programmers to give pure lambdas to map/filter, for several reasons (safety, cleanness, code style, future D front-end optimizations done on those higher order functions, to allow a better debuggability, and to avoid Phobos bugs like http://d.puremagic.com/issues/show_bug.cgi?id=9674 ). So I think it's better to introduce a new Phobos function like tap() that accepts a function/delegate with side effects that takes no input arguments. Bye, bearophile
Re: Runtime reflection idea
On 02.06.2013 11:33, Benjamin Thaut wrote: I think this is a very good idea. The only question is how complete this RTTI should be. This again highly depends on what it will be used for. For some users it might be ok to do a full RTTI, which will increase the executable size significantly. Other users might prefer a minimal RTTI or even no RTTI at all depending on the use case. The RTInfo template is very usefull for many different tasks, the question is if we shouldn't make the concept more generic so that you can have multiple templates which behave like the RTInfo template. I'm currently also using it for RTTI info see: http://3d.benjamin-thaut.de/?p=25 As a number of use cases show up for the RTInfo template (the precise GC also uses it), I think a simple approach for not stepping on each other toes would be to declare a struct type RTInfoData, and add each implementation as a member to this struct (not checked whether this actually compiles): struct RTInfoData { immutable(RuntimeReflection)* rr; immutable(thMemberInfo)* th; immutable(PreciseGCData)* gc; } template RTInfo(T) { immutable(RTInfoData) data = RTInfoData(genRuntimeReflection!T, genMemberInfo!T, genGCData!T); enum RTInfo = data; } and TypeInfo.rtInfo() would then return a pointer to RTInfoData instead of void*. This doesn't make it modifiable from outside object.di, but I have no idea how that could be possible to begin with (without recompiling the runtime library). Unfortunately the compiler sometimes doesn't force the generation of RTInfo, but sets the m_rtInfo to 0 or 1 depending on whether the Type contains pointers or not. I always wanted to figure out why that happens...
Re: Error after installing DMD v2.063
I've just run: sudo ln -s /usr/lib/x86_64-linux-gnu/libphobos2.so /usr/lib/x86_64-linux-gnu/libphobos2.so.0.63 for now but i've never had to do that before. Is this a problem with the installer?
Re: Slow performance compared to C++, ideas?
On 2 June 2013 19:53, Jacob Carlborg d...@me.com wrote: On 2013-06-01 23:08, Jonathan M Davis wrote: If you don't need polymorphism, then in general, you shouldn't use a class (though sometimes it might make sense simply because it's an easy way to get a reference type). Where it becomes more of a problem is when you need a few polymorphic functions and a lot of non-polymorphic functions (e.g. when a class has a few methods which get overridden and then a lot of properties which it makes no sense to override). In that case, you have to use a class, and then you have to mark a lot of functions as final. This is what folks like Manu and Don really don't like, particularly when they're in environments where the extra cost of the virtual function calls actually matters. If a reference type is needed but not a polymorphic type, then a final class can be used. I've never said that virtuals are bad. The key function of a class is polymorphism. But the reality is that in non-tool or container/foundational classes (which are typically write-once, use-lots; you don't tend to write these daily), a typical class will have a couple of virtuals, and a whole bunch of properties. The majority of functions in OO code (in the sorts of classes that you tend to write daily, ie, the common case) are trivial accessors or properties. The cost of forgetting to type 'final' is severe, particularly so on a property, and there is absolutely nothing the compiler can do to help you. There's no reasonable warning it can offer either, it must presume you intended to do that. Coders from at least C++ and C# are trained by habit to type virtual explicitly, so they will forget to write 'final' all the time. I can tell from hard experience, that despite training programmers that they need to write 'final', they have actually done so precisely ZERO TIMES EVER. People don't just forget the odd final here or there, in practise, they've never written it yet. The problem really goes pear shaped when faced with the task of opportunistic de-virtualisation - that is, de-virtualising functions that should never have been virtual in the first place, but are; perhaps because code has changed/evolved, but more likely, because uni tends to output programmers that are obsessed with the possibility of overriding everything ;) It becomes even worse than what we already have with C++, because now in D, I have to consider every single method and manually attempt to determine whether it should actually be virtual or not. A time consuming and certainly dangerous/error-prone task when I didn't author the code! In C++ I can at least identify the methods I need to consider by searching for 'virtual', saving maybe 80% of that horrible task by contrast. But there are other compelling reasons too, for instance during conversations with Daniel Murphy and others, it was noted that it will enhance interoperation with C++ (a key target for improvement being flagged recently), and further enabled the D DFE. I also think with explicit 'override' a requirement, it's rather non-orthogonal to not require explicit 'virtual' too. So, consider this reasonably. At least Myself and Don have both made strong claims to this end... and we're keen to pay for it with fixing broken base classes. Is it REALLY that much of an inconvenience to people to be explicit with 'virtual' (as they already are with 'override')? Is catering to that inconvenience worth the demonstrable cost? I'm not talking about minor nuisance, I'm talking about time and money.
Arch AUR DMD missing?
What happened to the DMD package in Arch AUR? New name or something? Does anyone have a link to the package?
Re: Slow performance compared to C++, ideas?
On 2 June 2013 20:16, Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday, June 02, 2013 11:53:26 Jacob Carlborg wrote: On 2013-06-01 23:08, Jonathan M Davis wrote: If you don't need polymorphism, then in general, you shouldn't use a class (though sometimes it might make sense simply because it's an easy way to get a reference type). Where it becomes more of a problem is when you need a few polymorphic functions and a lot of non-polymorphic functions (e.g. when a class has a few methods which get overridden and then a lot of properties which it makes no sense to override). In that case, you have to use a class, and then you have to mark a lot of functions as final. This is what folks like Manu and Don really don't like, particularly when they're in environments where the extra cost of the virtual function calls actually matters. If a reference type is needed but not a polymorphic type, then a final class can be used. Yes. The main problem is when you have a class with a few methods which should be virtual and a lot that don't. You're forced to mark a large number of functions as final. That burden can be lessened by using final with a colon rather than marking them individually, but rather what seems to inevitably happen is that programmers forget to mark any of them as final (Manu can rant quite a bit about that, as he's had to deal with it at work, and it's cost him quite a bit of time, as he has to go through every function which wasn't marked as final and determine whether it's actuallly supposed to be virtual or not). Having non-virtual be the default makes functions efficient by default. Aye. This, and maybe even a more important result is it makes it _explicit_ by default. Ie, it was intended by the author. You can tell just by looking how the interface is intended to be used, and the intent of the programmer who wrote it. No more guessing, or lengthy searches through all derived classes to find out if it actually is overridden. And what if your interface is public...? Making a function virtual is a one-way trip, it can never be revoked. Making it virtual-by-default eliminates the possibility of revoking that permission to override ever in the future. The converse isn't true, a non-virtual can safely become virtual at any later time if it becomes a requirement, or is requested by a customer. There's some correctness advantages too. A function that's not marked virtual was obviously not intended to be overridden by design; the author of the class may have never considered the possibility, and the class might not even work if someone unexpectedly overrides it somewhere. If virtual is requested/added at a later time, the author, when considering if it's a safe change, will likely take the time to validate that the new usage (which he obviously didn't consider when designing the class initially) is sound against the rest of the class... this is a good thing if you ask me.
Re: Arch AUR DMD missing?
On Sunday, 2 June 2013 at 14:04:51 UTC, simendsjo wrote: What happened to the DMD package in Arch AUR? New name or something? Does anyone have a link to the package? It's in [community] now: https://www.archlinux.org/packages/?sort=q=dmdmaintainer=flagged=
Re: The non allocating D subset
So I tried to get moduleinfo looping working and found some success. If you use it with libc, it works. On bare metal, it works thanks to a linker script hack. It doesn't work on the minimal linux setup. I wasted a lot of hours trying to do it, but there seems to be some elf section magic going on that I can't figure out how to easily hook in to. But even with that working, I couldn't get module ctors working right. Meh time to move on. Here's the list of stuff I'm abandoning so far What doesn't work: 1) array concats. use the module memory.d instead (link failure) 2) module constructors and destructors (silent failure, they never run) 3) looping ModuleInfo without libc or bare metal (silent failure, returns empty list) 4) TLS variables. always use __gshared (runtime crash) 5) threads. 6) unittests (silent failure, they never run) Maybe I can figure out module constructors later, but for now I'm just going to abandon that.
Re: Slow performance compared to C++, ideas?
On 2 June 2013 21:46, Joseph Rushton Wakeling joseph.wakel...@webdrake.netwrote: On 06/02/2013 08:33 AM, Manu wrote: Most of these guys are mathematicians and physicists first, and programmers second. You've hit the nail on the head, but it's also a question of priorities. It's _essential_ that the maths or physics be understood and done right. Well this is another classic point actually. I've been asked by my friends at Cambridge to give their code a once-over for them on many occasions, and while I may not understand exactly what their code does, I can often spot boat-loads of simple functional errors. Like basic programming bugs; out-by-ones, pointer logic fails, clear lack of understanding of floating point, or logical structure that will clearly lead to incorrect/unexpected edge cases. And it blows my mind that they then run this code on their big sets of data, write some big analysis/conclusions, and present this statistical data in some journal somewhere, and are generally accepted as an authority and taken seriously! *brain asplode* I can tell you I usually offer more in the way of fixing basic logical errors than actually making it run faster ;) And they don't come to me with everything, just the occasional thing that they have a hunch should probably be faster than it is. I hope my experience there isn't too common, but I actually get the feeling it's more common that you'd like to think! This is a crowd I'd actually love to promote D to! But the tools they need aren't all there yet... It's essential that the programs correctly reflect that maths or physics. It's merely _desirable_ that the programs run as fast as possible, or be well designed from a maintenance point of view, or any of the other things that matter to trained software developers. (In my day job I have to continually force myself to _not_ refactor or optimize my code, even though I'd get a lot of pleasure out of doing so, because it's working adequately and my work priority is to get results out of it.) That in turn leads to a hiring situation where the preference is to have mathematicians or physicists who can program, rather than programmers who can learn the maths. It doesn't help that because of the way academic funding is made available, the pay scales mean that it's not really possible to attract top-level developers (unless they have some kind of keen moral desire to work on academic research); in addition, you usually have to hire them as PhD students or postdocs or so on (I've also seen masters' students roped in to this end), which obviously constrains the range of people that you can hire and the range of skills that will be available, and also the degree of commitment these people can put into long-term vision and maintenance of the codebase. There's also a training problem -- in my experience, most physics undergraduates are given a crash course in C++ in their first year and not much in the way of real computer science or development training. In my case as a maths undergraduate the first opportunity to learn programming was in the 3rd year of my degree course, and it was a crash course in a very narrow subset of C dedicated towards numerical programming. And if (like me) you then go on into research, you largely have to self-teach, which can lead to some very idiosyncratic approaches. Yeah, this is an interesting point. These friends of mine all write C code, not even C++. Why is that? I guess it's promoted, because they're supposed to be into the whole 'HPC' thing, but C is really not a good language for doing maths! I see stuff like this: float ***cubicMatrix = (float***)malloc(sizeof(float**)depth); for(int z=0; zwidth; z++) { cubicMatrix[z] = (float**)malloc(sizeof(float**)*height); for(int y=0; yheight; y++) { cubicMatrix[z][y] = (float*)malloc(sizeof(float*)*width); } } Seriously, float***. Each 1d row is an individual allocation! And then somewhere later on they want to iterate a column rather than a row, and get confused about the pointer arithmetic (well, maybe not precisely that, but you get the idea). I hope that this will change, because programming is now an absolutely essential part of just about every avenue of scientific research. But as it stands, it's a serious problem.
Re: The non allocating D subset
On Sunday, 2 June 2013 at 14:32:56 UTC, Adam D. Ruppe wrote: So I tried to get moduleinfo looping working and found some success. If you use it with libc, it works. On bare metal, it works thanks to a linker script hack. It doesn't work on the minimal linux setup. I wasted a lot of hours trying to do it, but there seems to be some elf section magic going on that I can't figure out how to easily hook in to. But even with that working, I couldn't get module ctors working right. Meh time to move on. Here's the list of stuff I'm abandoning so far What doesn't work: 1) array concats. use the module memory.d instead (link failure) 2) module constructors and destructors (silent failure, they never run) 3) looping ModuleInfo without libc or bare metal (silent failure, returns empty list) 4) TLS variables. always use __gshared (runtime crash) 5) threads. 6) unittests (silent failure, they never run) Maybe I can figure out module constructors later, but for now I'm just going to abandon that. How about a wiki page?
Re: The non allocating D subset
This is super-interesting research! Lessons learned here should attempt to be rolled back into the main compiler/libs if they are applicable. This sort of work is what may open D up to ' proper embedded' usage. I'd really like to see escape analysis and lowering of small dynamic arrays onto the stack where possible get some attention. Kenji's recently changes for array literal assignment are a long-awaited start! :) On 2 June 2013 00:40, Adam D. Ruppe destructiona...@gmail.com wrote: On Saturday, 1 June 2013 at 05:45:38 UTC, SomeDude wrote: Basically it is a non allocating D subset. Not necessarily nonallocating, but it doesn't use a gc. I just updated the zip: http://arsdnet.net/dcode/**minimal.ziphttp://arsdnet.net/dcode/minimal.zip If you make the program (only works on linux btw) and run it, you'll see a bunch of allocations fly by, but they are all done with malloc/free and their locations are pretty predictable. The file minimal.d is a test program and you can see a lot of D works, including features like classes, exceptions, templates, structs, and delegates. (Heap allocated delegates should be banned but aren't, so if you do one built in it will leak. The helper file, memory.d, though contains a HeapDelegate struct that refcounts and frees it, so the concept is still usable.) The other cool thing is since the library is so minimal, the generated executable is small too. Only about 30 KB with an empty main(), and no outside dependencies. A cool fact about that is you can compile it and run on bare metal (given a bootloader like grub) too, and it all just works. You can also make LIBC=yes and depend on the C library, which makes things work better - there's a real malloc function there! - and adds about 10kb to the executable. That's probably a more realistic way to use it on the desktop at least than totally standalone. But yeah, I haven't written any real code with this, but so far it seems to be pretty usable. I also talked a while on the reddit thread last night about this, so let me copy/paste that here too: Yes, certainly. And it wouldn't even necessarily be no array concats, just you wouldn't want to use the built-in ones. Some features that use the gc in the real druntime don't necessarily have to. You'll need to be aware of this most the time to free the memory in your app, but you can have a pretty good idea of when it will happen. One example is new class. If that mallocs, if you just match every new with a delete (or call to free_obj() or whatever), you'll be fine, just like C++. I played with one I wasn't sure would work earlier, but now think it can: heap closures. scope delegates are easy, since they don't allocate, but heap closures allocate automatically and don't give much indication that they do but, if you are careful with it, the rules can be followed (if it accesses an outside scope and has its address taken/reference copied or passed to a function, it will automatically allocate), and you can manually call free(dg.ptr); when you're done with it. I think it is probably safer to just disallow them, either by not implementing _d_allocmemory in druntime (thus if you accidentally use it, you'll get a linker error about the missing function), or, and this is tricky right now but not actually impossible, use compile time reflection to scan your methods and members for a non-scope delegate reference and throw an error. If we do the latter, a heap delegate can actually be allowed in a fairly safe way, by wrapping it in a struct. Usage of HeapDelegate!T will be pretty obvious, so you aren't going to accidentally use it the way you might the more sugary built in. I have a proof of concept implemented in my local copy of minimal.d that automatically refcounts the delegate, freeing it when the last reference goes out of scope. Array slices are ok the way I have them implemented now: the built in concat function is missing, so if you try a ~ b, it will be a linker error (including the source file and line number btw, easy enough to handle). No allocation there. The biggest risk is lifecycle management, and the rule there is you don't own slices (non-immutable ones at least). I'd like the compiler to implement a check on this, but right now it doesn't. Not a hard coding convention though. Built in new array[] is not implemented, meaning it is a linker error, because they are indistinguishable from slices type-wise. (In theory it could be like classes, where you just know to manually free them, but if you have a char[] member, are you sure that was new'd or is it holding a slice someone else owns? Let's just avoid it entirely.) But, this doesn't mean we can't have some of D's array convenience! In minimal.d, you can see a StackArray!T struct and maybe, not sure if I put it in that zip or not, a HeapArray!T struct. These types own their memory, stack of course going away with scope, and heap
Re: Runtime reflection idea
On Sunday, 2 June 2013 at 09:33:27 UTC, Benjamin Thaut wrote: I think this is a very good idea. The only question is how complete this RTTI should be. For now, I'm going for just a UDA based thing, so it is almost all opt-in. Though one downside of my idea here is it may be slow, since it pulls info from a list (I'm doing a linear array, but it could be a binary search of AA or something without much difficulty, but my guess is most entries will only be a handful of elements long anyway). Actually adding members to the rtinfo struct would avoid this cost, but I can't think of any way to do that without modifying object.d for each one. Perhaps we could have a userRtInfo template that works the same way, but that one is defined in the module that defines the type, instead of in object.d. The module would be responsible for casting the void* in typeinfo (a new method, urtInfo to complement rtInfo) back to the type they defined. I think that would be doable at least. The other thing I'm pondering is changing TypeInfo to be generated at compile time and include all kinds of functions like std.traits offers. This would only be builtin types, user structs and classes have RTInfo instead, so that limits the size somewhat, but it nevertheless does increase exe size and isn't easy to opt out of, since you'd have to recompile at least part of druntime to do it. Expanding typeinfo is arguably less useful since if you want that info, you can do it yourself in a template like std.variant, but one use I can see is the D style variadics. Instead of a list of types with code right there, you could just do typeid().is/getNumeric() or whatever. The RTInfo template is very usefull for many different tasks, the question is if we shouldn't make the concept more generic so that you can have multiple templates which behave like the RTInfo template. I'm currently also using it for RTTI info see: http://3d.benjamin-thaut.de/?p=25 very cool.
Re: The non allocating D subset
W dniu 01.06.2013 07:45, SomeDude pisze: Following this idea, I believe a fairly large chunk of Phobos could be ported to compile with this minimal D sublanguage, and that one could use the allocating D and its added sugar on top of it. So in the end, the user could decide between working with the non allocating language (mostly embedded programmers and game makers), or benefit from the GC and all the associated niceties (the rest of us). When I started using D, I thought that it's done this ways. This would make D the truely universal language it was intended to be. I'd love to see that! I think that Phobos code that makes allocations can be divided (duplicated) to manual and GC versions.
Re: A Small Contribution to Phobos
I think consuming all of a range evaluating front and doing nothing should be the role of reduce with only one parameter (the range). That overload would take the range to be exhausted and return void. Thus your example becomes: Maybe, then, it would be best to have a template that calls reduce in such a way, that makes it perfectly clear what is happening.
Re: Runtime reflection idea
On Sunday, 2 June 2013 at 13:28:28 UTC, Rainer Schuetze wrote: and TypeInfo.rtInfo() would then return a pointer to RTInfoData instead of void*. This doesn't make it modifiable from outside object.di, but I have no idea how that could be possible to begin with (without recompiling the runtime library). I think I have something figured out: use side: // i'll use this as a UDA struct InfoStruct { string info; } // and this as the template extension struct MoreRtInfo { string amazing; } @CustomInfo!(InfoStruct(info struct data)) // UDA style, goes into an array class RTTest { // template style, goes in a special member static template userRtInfo(This) { static __gshared i = MoreRtInfo(amazingness); enum userRtInfo = i; } } Retrieve: auto info = typeid(RTTest).rtInfo(); if(info is null) throw new Exception(wtf); auto urtInfo = info.userRtInfo; // this is from the template.. if(urtInfo is null) write(urtInfo == null\n); else { // it comes out as a void*, so we have to cast it back. auto urt = cast(immutable(MoreRtInfo)*) urtInfo; write(cool ,urt.amazing,\n); } // and this is fetching the CustomInfo UDA auto cd = info.getCustomInfo!InfoStruct; if(cd is null) // it returns a InfoStruct*, like AA's in operator write(InfoStruct is null\n); else write(cd.info, \n); And the implementation side in object.d: struct MoreTypeInfo { // other stuff druntime is free to declare hash_t hash; string stringOf; // holder for the template thing immutable(void)* userRtInfo; // holder for the UDA thing immutable(CustomTypeInfoExtension)[] customInfo; // helper for the UDA get immutable(T)* getCustomInfo(T)() immutable { auto hash = typeid(T); // typehash!T; foreach(ci; customInfo) { if(ci.typeOfData == hash) return cast(immutable(T)*) ci.data(); } return null; } } // instantiates the T.userRtInfo, if possible template urtInfo(T) { static if (__traits(compiles, { auto a = cast(immutable(void)*) T.userRtInfo!T; })) enum urtInfo = cast(immutable(void)*) T.userRtInfo!T; else enum urtInfo = null; } template RTInfo(T) { __gshared static immutable minfo = MoreTypeInfo( // stuff druntime is free to add typehash!T, T.stringof, // the user defined template urtInfo!T, // getting the UDA stuff getCustomInfoInternal!T); enum RTInfo = minfo; } // finally, helpers in getting the UDAs, I posted this before too struct CustomTypeInfoExtension { TypeInfo typeOfData; // ctfe complained when I tried to just do static_data // so instead this little function helper does it for us void* function() data; } immutable(CustomTypeInfoExtension)[] getCustomInfoInternal(T)() { if(__ctfe) { //bool[hash_t] seen; immutable(CustomTypeInfoExtension)[] ext; foreach(attr; __traits(getAttributes, T)) static if(is(typeof(attr) == CustomTypeInfoExtension)) { //auto hash = attr.typeOfData.rtInfo.hash; //if(hash in seen) //assert(0, repeated data); //seen[hash] = true; ext ~= cast(immutable) attr; } return ext; } else return null; } // this is the user uses: @CustomInfo!(something) template CustomInfo(alias T) { __gshared static data = T; void* getRaw() { return cast(void*) data; } enum CustomInfo = CustomTypeInfoExtension( typeid(typeof(data))/*typehash!(typeof(data))*/, getRaw); } Unfortunately the compiler sometimes doesn't force the generation of RTInfo, but sets the m_rtInfo to 0 or 1 depending on whether the Type contains pointers or not. I always wanted to figure out why that happens... weird
Re: A Small Contribution to Phobos
On Sunday, 2 June 2013 at 13:07:18 UTC, Andrei Alexandrescu wrote: On 6/2/13 1:58 AM, Meta wrote: For reference type ranges and input ranges which are not forward ranges, this will consume the range and return nothing. I originally wrote it to accept forward ranges and use save, but I wanted to make it as inclusive as possible. I guess I overlooked the case of ref ranges. [snip] Thanks for sharing your ideas. I think consuming all of a range evaluating front and doing nothing should be the role of reduce with only one parameter (the range). That overload would take the range to be exhausted and return void. Thus your example becomes: [1, 2, 3, 4].map!(n = n.writeln).reduce; Andrei One of the problems with using map for something such as this, is that the resulting object is not a range, since front now returns void, and a range *must* return a value. So that code will never compile (since reduce will ask for at least input range). Heck, I think we should make it so that map refuses to compile with an operator that returns void. It doesn't make much sense as-is. Usage has to be something like: map!((n) {n.writeln; return n;}) which is quite clunky. The idea of a tee range, that takes n, runs an operation on it, and then returns said n as is becomes really very useful (and more idiomatic). [1, 2, 3, 4].tee!(n = n.writeln). There! perfect :) I've dabbled in implementing such a function, but there are conceptual problems: If the user calls front twice in a row, then should fun be called twice? If user popsFront without calling front, should fun be called at all? Should it keep track of calls, to guarantee 1, and only 1, call on each element? I'm not sure there is a correct answer to that, which is one of the reasons I haven't actually submitted anything. I don't think argument-less reduce should do what you describe, as it would be a bit confusing what the function does. 1-names; 1-operation, IMO. Users might accidentally think they are getting an additive reduction :( I think a function called walk, in line with walkLength, would be much more appropriate, and make more sense to boot! But we run into the same problem... Should walk call front between each element? Both answers are correct, IMO.
Re: Slow performance compared to C++, ideas?
On Sunday, 2 June 2013 at 14:34:43 UTC, Manu wrote: On 2 June 2013 21:46, Joseph Rushton Wakeling Well this is another classic point actually. I've been asked by my friends at Cambridge to give their code a once-over for them on many occasions, and while I may not understand exactly what their code does, I can often spot boat-loads of simple functional errors. Like basic programming bugs; out-by-ones, pointer logic fails, clear lack of understanding of floating point, or logical structure that will clearly lead to incorrect/unexpected edge cases. And it blows my mind that they then run this code on their big sets of data, write some big analysis/conclusions, and present this statistical data in some journal somewhere, and are generally accepted as an authority and taken seriously! You're making this up. I'm sure they do a lot of data-driven tests or simulations that make most errors detectable. They may not be savvy programmers, and their programs may not be error-free, but boat-loads of errors? C'mon.
Re: Slow performance compared to C++, ideas?
On 06/02/2013 02:26 PM, finalpatch wrote: IIRC -inline is a DMD specific switch. Adding this to gdc command line produces this: gdc.exe: error: unrecognized command line option '-inline' GDC and LDC both have their own equivalent flags -- for GDC it's -finline-functions (which as Iain says is already covered by -O3), for LDC it's -enable-inlining. It probably won't make any difference for LDC either with -O3 enabled, but might be worth checking.
Re: Slow performance compared to C++, ideas?
On Sunday, 2 June 2013 at 15:59:38 UTC, Joseph Rushton Wakeling wrote: GDC and LDC both have their own equivalent flags -- for GDC it's -finline-functions (which as Iain says is already covered by -O3), for LDC it's -enable-inlining. It probably won't make any difference for LDC either with -O3 enabled, but might be worth checking. It doesn't affect behavior on -O2 and above. David
Re: Slow performance compared to C++, ideas?
On Sunday, 2 June 2013 at 15:53:58 UTC, Roy Obena wrote: On Sunday, 2 June 2013 at 14:34:43 UTC, Manu wrote: On 2 June 2013 21:46, Joseph Rushton Wakeling Well this is another classic point actually. I've been asked by my friends at Cambridge to give their code a once-over for them on many occasions, and while I may not understand exactly what their code does, I can often spot boat-loads of simple functional errors. Like basic programming bugs; out-by-ones, pointer logic fails, clear lack of understanding of floating point, or logical structure that will clearly lead to incorrect/unexpected edge cases. And it blows my mind that they then run this code on their big sets of data, write some big analysis/conclusions, and present this statistical data in some journal somewhere, and are generally accepted as an authority and taken seriously! You're making this up. I'm sure they do a lot of data-driven tests or simulations that make most errors detectable. They may not be savvy programmers, and their programs may not be error-free, but boat-loads of errors? C'mon. I really wish he was making it up. Sadly, he's not. A lot of HPC scientific code is, at best, horribly fragile.
Re: A Small Contribution to Phobos
On 6/2/13 9:20 AM, bearophile wrote: Andrei Alexandrescu: [1, 2, 3, 4].map!(n = n.writeln).reduce; I have to shot this down for many reasons: I think it's better to give that final function a different name (like consume or something like that) because it's used for very different purposes and it returns nothing. Re-using the name reduce doesn't reduce the amount of Phobos lines of code, it doesn't make the user code simpler to understand, it's more obscure because it's more semantically overloaded, and it's not more easy to find in the documentation by the future D users. Au contraire, there are many advantages. Using reduce leverages a well-understood notion instead of introducing a new one. There is less need for documentation, motivation, and explanations. Reduce with no function simply spans the entire range. Builds on an already-eager construct par excellence instead of adding a new one that must be remembered and distinguished from the lazy constructs. Actually my first thought when I saw consume() was to look up reduce, thinking, how do I reduce a range to nothing? Because that's the goal. Reduce is the obvious choice here. Function names are not language keywords, packing different purposes in the same name as static doesn't give any advantage, and only disadvantages. Strawman argument. Andrei
Re: A Small Contribution to Phobos
On Sunday, 2 June 2013 at 13:07:18 UTC, Andrei Alexandrescu wrote: On 6/2/13 1:58 AM, Meta wrote: For reference type ranges and input ranges which are not forward ranges, this will consume the range and return nothing. I originally wrote it to accept forward ranges and use save, but I wanted to make it as inclusive as possible. I guess I overlooked the case of ref ranges. [snip] Thanks for sharing your ideas. I think consuming all of a range evaluating front and doing nothing should be the role of reduce with only one parameter (the range). That overload would take the range to be exhausted and return void. Thus your example becomes: [1, 2, 3, 4].map!(n = n.writeln).reduce; Andrei map being lazy, this can really do all kind of different stuff.
Re: Slow performance compared to C++, ideas?
On 6/2/13 9:59 AM, Manu wrote: I've never said that virtuals are bad. The key function of a class is polymorphism. But the reality is that in non-tool or container/foundational classes (which are typically write-once, use-lots; you don't tend to write these daily), a typical class will have a couple of virtuals, and a whole bunch of properties. I've argued if no dispatch is needed just make those free functions. _Everything_ in a class is supposed to be overridable, unless inherited and explicitly finalized. It's sort of a historical accident that things got the way they are. But in D we know better because we have the module-level privacy model and UFCS. So we should break clean from history. Andrei
Re: Slow performance compared to C++, ideas?
On 6/2/13 12:16 PM, John Colvin wrote: A lot of HPC scientific code is, at best, horribly fragile. Reminds me of that internal joke at www.llnl.gov. If we make a mistake, millions of people will live. True story. Andrei
Re: Slow performance compared to C++, ideas?
On 06/02/2013 05:53 PM, Roy Obena wrote: You're making this up. I'm sure they do a lot of data-driven tests or simulations that make most errors detectable. They may not be savvy programmers, and their programs may not be error-free, but boat-loads of errors? C'mon. I don't think he's making this up. I would not want to make any assumptions about any particular institutions, and I would like to believe that institutions with large-scale, long-term computational projects have better practices, but I think that most people in maths and physics research have very limited experience of good code design and testing practices (working with D, and its unit-testing framework and contract guarantees, has certainly been an eye-opener for me). Generally speaking it's true that in maths and physics there are often either theoretical calculations or empirical data points for you to compare your computational results to, so you can usually confirm that your program is doing what it's supposed to, but not always. There may not be boat-loads of errors in terms of output, but I bet there are boat-loads of loopholes that will result in insane mistakes if the input were to step outside the use-cases or parameter constraints the researcher has considered. I don't exclude my own code from that criticism, and the reason it's tolerated is because it's often the quickest way to get to working code; you know that you have to constrain parameters in such-and-such a way for it to work, and you know that you _will_ constrain yourself accordingly. But of course it's easy to shoot yourself in the foot when you start tweaking things. D's assert() and enforce() functions, and contract checks, are very useful here.
Re: Labels as values and threaded-code interpretation
On 02-06-2013 08:44, Paulo Pinto wrote: Am 02.06.2013 06:49, schrieb Walter Bright: On 6/1/2013 7:35 PM, Alex Rønne Petersen wrote: On 01-06-2013 09:59, bearophile wrote: Recently the Python C interpreter was modified and speed up thanks to this non-standard feature. CPython source code has two versions, one with computed gotos and one without, to compile it even if your C compiler doesn't support them or their GNU-C syntax. I don't think there's any question as to the usefulness (and essentialness) of this feature. I'm very close to just writing most of the interpreter in C over a triviality like this. To be pedantic, C and C++ don't have that feature. Some compilers add it as an extension. I always have fun in public forums making people aware that what they think is C or C++ code is actually compiler defined behaviour. Not much people seem to care to read language standards. :) -- Paulo I am perfectly aware that it's a GNU C extension. -- Alex Rønne Petersen a...@alexrp.com / a...@lycus.org http://alexrp.com / http://lycus.org
Re: Labels as values and threaded-code interpretation
On 02-06-2013 10:52, Dmitry Olshansky wrote: 01-Jun-2013 20:13, Timon Gehr пишет: On 06/01/2013 07:29 AM, Alex Rønne Petersen wrote: Hi, I'm sure this has been brought up before, but I feel I need to bring it up again (because I'm going to be writing a threaded-code interpreter): http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html This is an incredibly important extension. The final switch statement is not a replacement because it doesn't allow the programmer to store a label address directly into a code stream, which is what's essential to write a threaded-code interpreter. I'd also like to see this. Same here. Though I believe a way to force tail-call can support the same use case also helping functional programming. Say: goto Call-Expression; //forced tail call instead of: return Call-Expression; I'm not sure that can support threaded-code interpretation. -- Alex Rønne Petersen a...@alexrp.com / a...@lycus.org http://alexrp.com / http://lycus.org
Re: A Small Contribution to Phobos
On 6/2/13 11:41 AM, monarch_dodra wrote: On Sunday, 2 June 2013 at 13:07:18 UTC, Andrei Alexandrescu wrote: [1, 2, 3, 4].map!(n = n.writeln).reduce; Andrei One of the problems with using map for something such as this, is that the resulting object is not a range, since front now returns void, and a range *must* return a value. So that code will never compile (since reduce will ask for at least input range). Heck, I think we should make it so that map refuses to compile with an operator that returns void. It doesn't make much sense as-is. Hm, interesting. I'm destroyed. Usage has to be something like: map!((n) {n.writeln; return n;}) which is quite clunky. The idea of a tee range, that takes n, runs an operation on it, and then returns said n as is becomes really very useful (and more idiomatic). [1, 2, 3, 4].tee!(n = n.writeln). There! perfect :) I've dabbled in implementing such a function, but there are conceptual problems: If the user calls front twice in a row, then should fun be called twice? If user popsFront without calling front, should fun be called at all? Should it keep track of calls, to guarantee 1, and only 1, call on each element? I'm not sure there is a correct answer to that, which is one of the reasons I haven't actually submitted anything. I think there is one answer that arguably narrows the design space appropriately: just like the Unix utility, tee should provide a hook that creates an exact replica of the (portion of the) range being iterated. So calling front several times is nicely out of the picture. The remaining tactical options are: 1. evaluate .front for the parent range once in its constructor and then every time right after forwarding popFront() to the parent range. This is a bit eager because the constructor evaluates .front even if the client never does. 2. evaluate .front for the parent range just before forwarding popFront() to parent. This will call front even though the client doesn't (which I think is fine). 3. keep a bool that is set by constructor and popFront() and reset by front(). The bool makes sure front() is called if and only if the client calls it. I started writing the options mechanically without thinking of the implications. Now that I'm done, I think 2 is by far the best. I don't think argument-less reduce should do what you describe, as it would be a bit confusing what the function does. 1-names; 1-operation, IMO. Users might accidentally think they are getting an additive reduction :( Good point. I think a function called walk, in line with walkLength, would be much more appropriate, and make more sense to boot! But we run into the same problem... Should walk call front between each element? Both answers are correct, IMO. That's why I'm thinking: the moment .front gets evaluated, we get into the realm of reduce. Andrei
Re: Runtime reflection idea
Am 02.06.2013 15:28, schrieb Rainer Schuetze: On 02.06.2013 11:33, Benjamin Thaut wrote: I think this is a very good idea. The only question is how complete this RTTI should be. This again highly depends on what it will be used for. For some users it might be ok to do a full RTTI, which will increase the executable size significantly. Other users might prefer a minimal RTTI or even no RTTI at all depending on the use case. The RTInfo template is very usefull for many different tasks, the question is if we shouldn't make the concept more generic so that you can have multiple templates which behave like the RTInfo template. I'm currently also using it for RTTI info see: http://3d.benjamin-thaut.de/?p=25 As a number of use cases show up for the RTInfo template (the precise GC also uses it), I think a simple approach for not stepping on each other toes would be to declare a struct type RTInfoData, and add each implementation as a member to this struct (not checked whether this actually compiles): struct RTInfoData { immutable(RuntimeReflection)* rr; immutable(thMemberInfo)* th; immutable(PreciseGCData)* gc; } template RTInfo(T) { immutable(RTInfoData) data = RTInfoData(genRuntimeReflection!T, genMemberInfo!T, genGCData!T); enum RTInfo = data; } and TypeInfo.rtInfo() would then return a pointer to RTInfoData instead of void*. This doesn't make it modifiable from outside object.di, but I have no idea how that could be possible to begin with (without recompiling the runtime library). Unfortunately the compiler sometimes doesn't force the generation of RTInfo, but sets the m_rtInfo to 0 or 1 depending on whether the Type contains pointers or not. I always wanted to figure out why that happens... That is the obvious solution to the problem. Maybe we should get something like this into drutime ASAP so that the RTInfo template remains extendable even if a percise GC is used. Kind Regards Benjamin Thaut
Re: Slow performance compared to C++, ideas?
On 06/01/2013 08:22 PM, Walter Bright wrote: On 5/30/2013 7:56 PM, Andrei Alexandrescu wrote: On 5/30/13 9:26 PM, finalpatch wrote: https://dl.dropboxusercontent.com/u/974356/raytracer.d https://dl.dropboxusercontent.com/u/974356/raytracer.cpp Manu's gonna love this one: make all methods final. I have another suggestion. class Sphere and class Ray should be structs. Neither class uses polymorphism in any way, so there's no reason to make them classes with virtual functions. I was about to write that too, but when the goal is to write a scenegraph polymorphism is what you want, i.e. Sphere is just one object and there is different lights. Ray already is a struct.
Re: Slow performance compared to C++, ideas?
On 05/31/2013 06:29 AM, Juan Manuel Cabo wrote: I just shaved 1.2 seconds trying with dmd by changing the dot function from: Yep, using -profile on the original code shows that 33% is spend in Sphere.intersect. And the asm for the dot product is horrible.
Re: Labels as values and threaded-code interpretation
02-Jun-2013 20:48, Alex Rønne Petersen пишет: On 02-06-2013 10:52, Dmitry Olshansky wrote: 01-Jun-2013 20:13, Timon Gehr пишет: On 06/01/2013 07:29 AM, Alex Rønne Petersen wrote: Hi, I'm sure this has been brought up before, but I feel I need to bring it up again (because I'm going to be writing a threaded-code interpreter): http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html This is an incredibly important extension. The final switch statement is not a replacement because it doesn't allow the programmer to store a label address directly into a code stream, which is what's essential to write a threaded-code interpreter. I'd also like to see this. Same here. Though I believe a way to force tail-call can support the same use case also helping functional programming. Say: goto Call-Expression; //forced tail call instead of: return Call-Expression; I'm not sure that can support threaded-code interpretation. Why not: alias OpCode = function void(); OpCode[] opcodes = [ opcode_1, ... ]; int pc; ... void opcode_1() { ... //pick operands do whatever pc = pc + num_operands; //skip over arguments OpCode next = cast(OpCode)bytecode[pc]; goto next(); //this is baked-in threaded dispatch } void opcode_2(){ ... } //say bytecode contains operands and addresses of fucntions void execute(size_t[] bytecode, int pc) { OpCode start = cast(OpCode)bytecode[pc]; pc++; goto start(); } One can get away without casting if data is in a separate array. Then this solution is perfectly safe in this limited form. Call would only point to a function hence no problem with jumping who knows where and less problems for optimizer. -- Dmitry Olshansky
Re: Labels as values and threaded-code interpretation
On 6/2/2013 12:49 AM, Brad Roberts wrote: Many if not most of those non-unix platforms use gcc, which is included in the set of compilers that does support it. The point is, which you didn't change, is that's it's a defacto standard even if not technically in the c or c++ language specs. The curious question is why it never gets into the newer C and C++ Standards.
Re: Labels as values and threaded-code interpretation
On 02-06-2013 19:43, Dmitry Olshansky wrote: 02-Jun-2013 20:48, Alex Rønne Petersen пишет: On 02-06-2013 10:52, Dmitry Olshansky wrote: 01-Jun-2013 20:13, Timon Gehr пишет: On 06/01/2013 07:29 AM, Alex Rønne Petersen wrote: Hi, I'm sure this has been brought up before, but I feel I need to bring it up again (because I'm going to be writing a threaded-code interpreter): http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html This is an incredibly important extension. The final switch statement is not a replacement because it doesn't allow the programmer to store a label address directly into a code stream, which is what's essential to write a threaded-code interpreter. I'd also like to see this. Same here. Though I believe a way to force tail-call can support the same use case also helping functional programming. Say: goto Call-Expression; //forced tail call instead of: return Call-Expression; I'm not sure that can support threaded-code interpretation. Why not: alias OpCode = function void(); OpCode[] opcodes = [ opcode_1, ... ]; int pc; ... void opcode_1() { ... //pick operands do whatever pc = pc + num_operands; //skip over arguments OpCode next = cast(OpCode)bytecode[pc]; goto next(); //this is baked-in threaded dispatch } void opcode_2(){ ... } //say bytecode contains operands and addresses of fucntions void execute(size_t[] bytecode, int pc) { OpCode start = cast(OpCode)bytecode[pc]; pc++; goto start(); } One can get away without casting if data is in a separate array. Then this solution is perfectly safe in this limited form. Call would only point to a function hence no problem with jumping who knows where and less problems for optimizer. The problem here is assuming the interpreter state can be global. Once you make it non-global (and thus have to pass it in the goto start(...) call) you get all the overhead of a regular function call. -- Alex Rønne Petersen a...@alexrp.com / a...@lycus.org http://alexrp.com / http://lycus.org
Re: Slow performance compared to C++, ideas?
On 6/2/2013 5:29 AM, Paulo Pinto wrote: There was an office there that had the sentence You can program Fortran in any language on the door. :) I think that joke is older than me!
Re: Labels as values and threaded-code interpretation
On 02-06-2013 19:44, Walter Bright wrote: On 6/2/2013 12:49 AM, Brad Roberts wrote: Many if not most of those non-unix platforms use gcc, which is included in the set of compilers that does support it. The point is, which you didn't change, is that's it's a defacto standard even if not technically in the c or c++ language specs. The curious question is why it never gets into the newer C and C++ Standards. That one's easy: It makes 'too many' assumptions about the capabilities of the target machine. Sort of like assuming signed integers overflow. In practice, though, any relevant target can support computed gotos. -- Alex Rønne Petersen a...@alexrp.com / a...@lycus.org http://alexrp.com / http://lycus.org
Re: Slow performance compared to C++, ideas?
On 6/2/2013 4:10 AM, Iain Buclaw wrote: -O3 is covered in the GDC case (turns on -finline-functions). The reason -inline is a separate switch is for debugging purposes (to set breakpoints on the function that would have been inlined), and also to generate profile statistics.