Re: Win Headers
On 12/12/2013 4:44 PM, frustrated2 wrote: thanks for your reply. its a shame that the language does not supply ready to use headers. i can live with missing libraries, but not with incomplete or non working bare minimal prerequisites to use it with an os. that is a sad and sorry state! I don't see why. Win32 bindings aren't shipped with Java or Python and several other languages. Even C and C++, except for maybe one of the MinGW distros. Even with VC, you still have to download the Windows SDK separately. Should DMD ship with X-Windows bindings, too? What about Cocoa on OS X? I would be content if DMD did not ship Win32 bindings at all, except for the minimal needed to implement cross-platform stuff in Phobos. As it stands, the static libs for the Win32 API that ship with DMD are old and don't include a good number of modern functions anyway. IMO, complete OS API bindings *should* be separate. I wouldn't expect them with the compiler. --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
Re: Win Headers
Mike Parker: I would be content if DMD did not ship Win32 bindings at all, except for the minimal needed to implement cross-platform stuff in Phobos. As it stands, the static libs for the Win32 API that ship with DMD are old and don't include a good number of modern functions anyway. IMO, complete OS API bindings *should* be separate. I wouldn't expect them with the compiler. I prefer languages with more batteries included. Bye, bearophile
Re: File Picker
On Thursday, 12 December 2013 at 03:17:29 UTC, Malkierian wrote: On Tuesday, 10 December 2013 at 03:42:10 UTC, Malkierian wrote: On Tuesday, 10 December 2013 at 02:05:12 UTC, Jeremy DeHaan wrote: On Monday, 9 December 2013 at 16:49:04 UTC, Malkierian wrote: On Monday, 9 December 2013 at 08:57:16 UTC, Jeremy DeHaan wrote: On Monday, 9 December 2013 at 06:32:06 UTC, Malkierian wrote: *sigh* No dice. And I can't get GtkD to work either, because of entry point errors... I've gotten GtkD to work for me, though it has been a while. If I am able to find some time soon I will see if I can do some kind of example for you. Well, in the mean time, have you ever heard of this error before? The procedure entry point gdk_frame_clock_begin_updating could not be located in the dynamic link library libgdk-3-0.dll. I've also gotten a similar error with some other entry point in libgdk_pixbuf-2.0-0.dll, but then I copied that file from the Gtk 3.6.4 release into my bin folder and it went away. Copying the the libgdk-3-0.dll from the same release did nothing to fix this error. This is getting ridiculous. I don't know if this is your problem exactly, but the Gtk+ installer on the GtkD website(http://gtkd.org/download.html) is for 3.8.1, so maybe something has been updated since then? You could also open an issue on GtkD's github repo(https://github.com/gtkd-developers/GtkD) if you continue to experience problems with it. LOL, that was the version I was replacing with the 3.6.4 stuff XD. And I already made a post on their forum about it. So guess what? I just recently was trying to troubleshoot GtkD, and in the process I removed the bin folders for the 64-bit versions of TortoiseGit and TortioseSVN from my PATH, and when I switch back over to my other source set (the one with the file chooser from here) suddenly the windows generic chooser works fine. I had to remove those two bin folders from the path because, despite it being a 32-bit application, it was apparently loading (or trying to load) a specific driver from those folders that was messing everything up. So is this 32/64-bit crossover thing a bug in D, or is it just a phantom random weird thing that was happening with my setup? Mixing 32 bit code with 64 bit libraries, or vice versa, is (from what I have read) not usually a good thing and is not specific to the D language. If your program found a dll with the same name for one it is looking for I think it just goes for it. I have no idea if Windows can or does try to verify how many bits a library has before it loads it.
Re: Question about function aliases
On Thursday, 12 December 2013 at 00:51:56 UTC, dnewbie wrote: On Wednesday, 11 December 2013 at 23:42:44 UTC, Gary Willoughby wrote: For example i have some C code like this: typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp)); void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); I intend on converted this to D thus: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); Is it correct keeping the * with the Tcl_InterpDeleteProc parameter or do i remove it? Is the alias above a function pointer? To call this function can i use a function literal for the Tcl_InterpDeleteProc parameter? or do i need to pass an address of the function? It's a function pointer. Test: import std.stdio; alias extern(C) void function(void*) Callback; void Call(Callback c) { c(c); } extern(C) void callback(void* v) { writefln(v: %04X, v); } void main() { Callback c = callback; Call(c); writefln(c: %04X, c); } So i guess i need to remove the * after the Tcl_InterpDeleteProc parameter from the C declaration when porting it? Using the * my tests show an error which i guess is caused by the declaration expecting a pointer to a function pointer. Here is my test: import std.stdio; // Function pointer type. alias void function(string text, int level) Tcl_InterpDeleteProc; // A function that uses the function pointer type for a parameter. void test(Tcl_InterpDeleteProc func) // -- no * { (*func)(Hello, 100); } // A callback that going to be used as the parameter. void callback(string text, int level) { writefln(text : %s, text); writefln(level: %d, level); } // test. void main(string[] args) { // Use address of function. test(callback); // Function literal passed as pointer. test(function(string text, int level){ writefln(text : %s, text); writefln(level: %d, level); }); } After testing i've decided on the following code for the port. Would you agree this is correct? alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData);
Re: How to handle nested structs when converting C headers?
On Thu, 12 Dec 2013 00:04:07 -, H. S. Teoh hst...@quickfur.ath.cx wrote: On Thu, Dec 12, 2013 at 12:54:58AM +0100, Gary Willoughby wrote: On Wednesday, 11 December 2013 at 23:38:13 UTC, Adam D. Ruppe wrote: On Wednesday, 11 December 2013 at 23:35:04 UTC, Gary Willoughby wrote: static union internalRep try static union InternalRep { /* note the capital letter */ /* snip */ } InternalRep internalRep;; // still need a decl Right. But why use the static keyword here? Because nested structs by default carry a pointer to the containing struct (or scope), which means it adds extra baggage and you can't create the nested without also having an instance of the containing struct. I would stop nesting the struct definition. I think that is both cleaner and closer to the original intent - the only reason it is nested in C is because C allows definition and declaration that way, and D does not. Then you don't need static at all. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Win Headers
On Wednesday, 11 December 2013 at 09:04:32 UTC, frustrated2 wrote: Are there complete windows headers and if yes where can i find them and will they work for 64bit? I've also generated from Mingw64 windows static binding[1]. So it definitely will work with Windows 7 64bit. However I've only tested some of the GDI parts for DOOGLE. So its kinda don't count on it. [1] https://github.com/rikkimax/DOOGLE/tree/master/source/WindowsAPI
Re: How to handle nested structs when converting C headers?
Regan Heath: I would stop nesting the struct definition. I think that is both cleaner and closer to the original intent - the only reason it is nested in C is because C allows definition and declaration that way, and D does not. Then you don't need static at all. It's mostly a matter of style, but here I prefer a little more the nested form. It's syntactically closer to the original C file, for a D programmer static struct has a known and clear meaning, and putting the structs inside the other keeps the global namespace clean of those inner names. Like with nested functions putting names inside other scoped helps the programmer see they are just needed there. Bye, bearophile
Re: Win Headers
On Thu, 12 Dec 2013 08:18:51 -, Mike Parker aldac...@gmail.com wrote: On 12/12/2013 4:44 PM, frustrated2 wrote: thanks for your reply. its a shame that the language does not supply ready to use headers. i can live with missing libraries, but not with incomplete or non working bare minimal prerequisites to use it with an os. that is a sad and sorry state! I don't see why. Win32 bindings aren't shipped with Java or Python and several other languages. Even C and C++, except for maybe one of the MinGW distros. Even with VC, you still have to download the Windows SDK separately. I don't believe this last statement is true. I am fairly certain that upon installing VC you have everything you need to call/use Win32 functions. The only reason to download/install a separate SDK is if your VC version is older and you want a newer SDK/API. Should DMD ship with X-Windows bindings, too? What about Cocoa on OS X? How big are they? If we're just talking about D header files then I am all for it, the more the merrier. It's not like internet bandwidth or hard disk space is currently an issue and it will only become less of an issue the more time rolls on. If people are really anxious about this, why not have a separate download for windows and the various flavours of UNIX.. wait a minute, we already do. :) I would be content if DMD did not ship Win32 bindings at all, except for the minimal needed to implement cross-platform stuff in Phobos. This is more or less the current situation right? Last time I tried to do any Win32 stuff in D there were enormous gaps.. this is one reason I don't have any current projects using D. As it stands, the static libs for the Win32 API that ship with DMD are old and don't include a good number of modern functions anyway. IMO, complete OS API bindings *should* be separate. I wouldn't expect them with the compiler. Sure, if we're talking about DLL/LIB files then I agree, we don't want to be shipping these with the compiler. They should be obtained from official channels i.e. downloading the windows SDK. However.. Does DMD support the M$ dll/lib format or is that still an issue? I know there is a conversion tool, but IIRC you have to pay for that.. this hassle was another reason I stopped using D for my personal projects. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Win Headers
I prefer languages with more batteries included - for sure. its a nice compiler, love the language, but i do not want to waste the time to do everything myself. even basic compilers (yuck) offer more tools, windows programming and db stuff than D. On Thursday, 12 December 2013 at 09:49:31 UTC, bearophile wrote: Mike Parker: I would be content if DMD did not ship Win32 bindings at all, except for the minimal needed to implement cross-platform stuff in Phobos. As it stands, the static libs for the Win32 API that ship with DMD are old and don't include a good number of modern functions anyway. IMO, complete OS API bindings *should* be separate. I wouldn't expect them with the compiler. I prefer languages with more batteries included. Bye, bearophile
Re: Question about function aliases
Gary Willoughby: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); With recent D compilers I prefer the alias with = and a more aligned colums formatting of the arguments when they don't fit well in a line: alias Tcl_InterpDeleteProc = void function(ClientData clientData, Tcl_Interp* interp); extern(C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); Also, can't you add some const in those arguments? Is your C function pure? It should be nothrow. Bye, bearophile
Re: Question about function aliases
On Thursday, 12 December 2013 at 11:11:55 UTC, bearophile wrote: Gary Willoughby: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); With recent D compilers I prefer the alias with = and a more aligned colums formatting of the arguments when they don't fit well in a line: alias Tcl_InterpDeleteProc = void function(ClientData clientData, Tcl_Interp* interp); extern(C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); Also, can't you add some const in those arguments? Is your C function pure? It should be nothrow. Bye, bearophile I guess alias also should include extern(C) declaration i.e. the right way is alias Tcl_InterpDeleteProc = extern(C) void function(ClientData clientData, Tcl_Interp* interp) nothrow; So your callback on D side must have C-linkage too. Lack of extern(C) in alias probably will not cause problem on Linux, but in my experience, Windows requires it otherwise you will get seg fault.
Re: Win Headers
On Thursday, 12 December 2013 at 11:08:41 UTC, Regan Heath wrote: Does DMD support the M$ dll/lib format or is that still an issue? I know there is a conversion tool, but IIRC you have to pay for that.. this hassle was another reason I stopped using D for my personal projects. with -m64 DMD using MS toolchain, but x86 uses optlink and probably never support COFF libs. what payment do you talking about? i mean there is two tools - coffimplib(you can get it from digital mars ftp) and something like implib(i don't remember its name correctly), both are free afaik.
Re: Win Headers
On 12/12/2013 8:20 PM, frustrated2 wrote: I prefer languages with more batteries included - for sure. its a nice compiler, love the language, but i do not want to waste the time to do everything myself. even basic compilers (yuck) offer more tools, windows programming and db stuff than D. I appreciate that some people prefer the batteries included approach. I was basically responding to your remark that it's a sad and sorry state. I felt that was a bit extreme, given that more complete Windows API bindings do exist.
Re: Win Headers
On 12/12/2013 8:08 PM, Regan Heath wrote: MinGW distros. Even with VC, you still have to download the Windows SDK separately. I don't believe this last statement is true. I am fairly certain that upon installing VC you have everything you need to call/use Win32 functions. The only reason to download/install a separate SDK is if your VC version is older and you want a newer SDK/API. Oh, I was sure I had to install the SDK when I installed the VC Express. But I see now that it is included. Should DMD ship with X-Windows bindings, too? What about Cocoa on OS X? How big are they? If we're just talking about D header files then I am all for it, the more the merrier. It's not like internet bandwidth or hard disk space is currently an issue and it will only become less of an issue the more time rolls on. If people are really anxious about this, why not have a separate download for windows and the various flavours of UNIX.. wait a minute, we already do. :) It's not the bandwidth or disk size that bothers me. It's mostly a matter of maintenance. I appreciate the batteries included approach as far as Phobos is concerned, but given that DMD aims to be a cross-platform compiler, I don't think platform-specific API bindings should fall into that category. I mean, all these years and the Win32 bindings are still incomplete, while there are a couple of complete (or mostly complete) third-party bindings out there that do a good job of staying relevant. Why is that? Because Win32 bindings are not a priority for the DMD team. If they aren't a priority, then why ship them? Maintenance is going to depend on community members anyway. Much more efficient, IMO, as a user to use the third-party bindings. It would be different if DMD were Windows-centric, or if it didn't have a platform abstraction in the form of Phobos. Platform API bindings basically provide system functions and GUI functions. IMO, let Phobos abstract away the system and third-party libs abstract away the GUI. Beyond that, I can't imagine that those needing direct API access beyond a handful of functions will be more than a minority. So for them, let third-parties handle the API bindings too. I haven't done any straight-up Win32 development in years and when I do need a Win32 function, it's usually one that isn't available in the ancient libs DMD ships so I have to prototype it and load it manually anyway. But if I do need more of the Win32 API, then I have no problem using an external lib for it. Especially if that lib supports dub. I would be content if DMD did not ship Win32 bindings at all, except for the minimal needed to implement cross-platform stuff in Phobos. This is more or less the current situation right? Last time I tried to do any Win32 stuff in D there were enormous gaps.. this is one reason I don't have any current projects using D. From what I can tell, there's more in there than what Phobos actually uses. But because it's incomplete, it's essentially useless. As it stands, the static libs for the Win32 API that ship with DMD are old and don't include a good number of modern functions anyway. IMO, complete OS API bindings *should* be separate. I wouldn't expect them with the compiler. Sure, if we're talking about DLL/LIB files then I agree, we don't want to be shipping these with the compiler. They should be obtained from official channels i.e. downloading the windows SDK. The static libs for DMC need to be shipped for 32-bit programs. There's just no way around that. But they desperately need updating. I believe they don't include anything beyond Windows XP. With the dependence on VC for 64-bit, that goes away for 64-bit apps. But you still have the problem of maintaining compatibility between 32- and 64-bit versions if that's a priority. At any rate, it's not going to kill me if all of the platform API bindings are included. As long as they're complete and well-maintained, then no big deal.
Re: can clone a thread?
Am Wed, 11 Dec 2013 11:04:29 +0100 schrieb Gianni Pisetta pisetta.gia...@alice.it: On Wednesday, 11 December 2013 at 08:54:18 UTC, Marco Leise wrote: Am Wed, 11 Dec 2013 09:10:09 +0100 schrieb Gianni Pisetta pisetta.gia...@alice.it: No, i think fork or something similar is the way i prefer to go. I'm working on a simple top-down parser, so i save all the data references in the context of the function and at the end of it i create the syntax tree object with all his childrens. So i have the already allocated objects in the tls and the info on the realtionships of these objects plus the parser state in the call stack. I want to duplicate the parser because i want all the possible syntax trees as a result and when the tokenizer will find in the input two or more possible tokens, it must fork and return for each thread one token from the possible ones. At the end if one or more threads made to the end, each thread copy his syntax tree on a shared array and the main thread then can work on the results. Another way to solve this is to move all the info from the call stack to a stack managed by me, have a standard procedure that fills the stack. When i must duplicate the thread i can create a new one, make a deep copy of the objects in the stack and the stack itself, then call the standard procedure again. But i think this is a bottom-up parser and a major change in the application design. For now i will stick with fork, if in the future a similar function is implemented in core.thread, i will use it. Alright, fork is optimized for this kind of stuff and it should work fine. Personally I would likely have tried a manged stack instead of cloning the whole application. How do you write back the results from the child processes? Do you use pipes or shared memory? I also like the managed stack idea, but i think the main problem with that is that it is harder to understand what's going on when you have to debug. I'm not at the point yet of passing the results to the main thread, but i think at the end i will make the entire tree immutable(or maybe already create it with immutable) and add the reference to a shared array or use a message passing pattern like the one in std.concurrency. Gianni Pisetta Then wait a second! fork() creates a new _process_, not a thread. The two options I gave are pretty much the only ones available for communication between local processes. Maybe add a TCP socket connection to that... Shared arrays and std.concurrency work only for _threads_ inside the same process. -- Marco
Re: Performance of ranges verses direct
Am Wed, 11 Dec 2013 17:40:39 +0100 schrieb Joseph Rushton Wakeling joseph.wakel...@webdrake.net: On 11/12/13 11:10, John Colvin wrote: A lot of the performance loss is down to missed optimisations, in particular inlining. Simple example: foreach(i; iota(0, 10)) { ... } should be as fast as foreach(i; 0 .. 10) { ... } but isn't. I remember Andrei noting that this ought to be easily fixable [*], but I don't know if that actually happened, because I haven't compared the two recently. As far as I remember it *is* the same speed using GDC or LDC. But as long as this issue remains with DMD I'm confident that foreach_reverse(i; 0 .. 10) will stay :) -- Marco
Re: Type inference and overloaded functions
I created a separate branch for the syntax Type[$] and auto[$]: https://github.com/Dgame/dmd/commit/438a519d28d1683086083e673b2630a64c269f5f Example: int[$] arr_a1 = [54, 74, 90, 2010]; assert(is(typeof(arr_a1) == int[4])); assert(arr_a1 == [54, 74, 90, 2010]); int[$] arr_a2 = [2010, 90, 74, 54]; assert(is(typeof(arr_a2) == int[4])); assert(arr_a2 == [2010, 90, 74, 54]); int[] dyn_arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; int[$] stat_arr = dyn_arr[3 .. 6]; assert(is(typeof(stat_arr) == int[3])); auto[$] a_arr1 = [1, 2, 3]; assert(is(typeof(a_arr1) == int[3])); auto[$] a_arr2 = dyn_arr[4 .. 8]; /// Sadly not possible for me //int s = 2, e = 7; //int[$] stat_arr2 = dyn_arr[s .. e]; /// fails //int[$] stat_arr3 = dyn_arr[]; /// fails Sadly I don't know how I could deduce the type of: auto[$] a_arr2 = dyn_arr[4 .. 8]; /// Sadly not possible for me I will try this again before I open a pull request. Maybe some of you know how to do this?
Re: Type inference and overloaded functions
Namespace: Sadly I don't know how I could deduce the type of: auto[$] a_arr2 = dyn_arr[4 .. 8]; /// Sadly not possible for me It seems a valid use case. Bye, bearophile
Re: Type inference and overloaded functions
I presume the situation with this code is not changed by your patches: string[3] a = [redgreen,blue]; void main() {} Bye, bearophile
Re: How to handle nested structs when converting C headers?
On 2013-12-11 23:45, Gary Willoughby wrote: How to handle nested structs when converting C headers? In the following snippet i'm currently converting, how would you convert the nested typed union and structures? Would you declare them separately then use their types in the Tcl_Obj struct? or is there a nice way in D to nest them like C? Convert using DStep[1] and see what happens :) [1] https://github.com/jacob-carlborg/dstep -- /Jacob Carlborg
Re: Type inference and overloaded functions
string[3] a = [redgreen,blue]; void main() {} I suggested to support such incomplete literals only with this extra syntax: int[3] a = [1, 2, ...]; void main() {} Bye, bearophile
A good advertisement for 'static if'
I am not sure if this belongs in D.learn, but it might be of interest. I was writing some C++ code for a project at work and have a class that stores image data from a file. The image data can be in just about any numeric (int/float/complex) type, so I wanted a 'wrapper' class/struct that could hold any type of data without being 'parameterized' (we use templates for image access). My class contains a union ( called 'data') with every possible type of pointer and parameter for indicating the data type. However, at some point code eventually needs to get at the data, so I have the following beauty of a template method, (calling the image structure RAWImageDataStore was a bad design decision on my part, need to change that soon, its very Java-esque): template class T RAWImageDataStoreT* getBandData( ) { T t; //Check struct data type vs template type. if( datatype == TYPE_8u typeid(t) == typeid(uint8_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t8u ); } else if ( datatype == TYPE_16s typeid(t) == typeid(int16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t16s ); } //a number of types left out, I am sure you get the idea. //but you need to see the complex types, they are beautiful. else if ( datatype == TYPE_C16s typeid(t) == typeid(std::complexint16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.tC16s ); } \\OK, you only really needed to see one of the complex types :o) else if( datatype == TYPE_UNKNOWN ) { std::cerr Cannot access band with unknown data type. std::endl; return 0; } //+ a bit more error handling code. Initially this didn't compile because I was missing the reinterpret_cast statements. They effectively do nothing. If the template type is int8_t then I return the data.t8u pointer, which is a RAWImageDataStoreint8_t*, but have to cast it to RAWImageDataStoreint8_t*. I must do this because when I call the method type int16_t my return data.t8u returns the wrong type of pointer for the method, even though I know that if the type is int16_t this statement can never be reached. I know there was some debate in the C++ community about whether they should adopt D-like static if, which would have solved this problem, since it would compile the illegal code right out of existence. Maybe there is a better way to do this in C++, but I thought I would post here as a case-study in the usefulness of 'static if'. Craig
Re: Performance of ranges verses direct
On Wednesday, 11 December 2013 at 16:40:48 UTC, Joseph Rushton Wakeling wrote: [* If I recall right, it's achievable by special-casing iota when the increment is 1, but don't quote me on that.] That shouldn't be necessary if the iota operations are inlined (which, if their not, is a much greater concern!). The increment is then known to be a particular compile-time constant and code generated appropriately. Also, on x86 the gcc and llvm backends both prefer to use add 1 instead of inc, so you wouldn't even expect to see any difference at that level.
Re: Type inference and overloaded functions
On 12/11/2013 05:09 PM, bearophile wrote: Ali Çehreli: int[] arr2 = [7, 8, 9]s; assert(is(typeof(arr2) == int[3])); That looks very confusing. The left-hand side looks like a slice, which I can append elements to but its type is a static array? No, the type of the literal is of a fixed-side array, but it gets assigned to a dynamic array, so it's a slice. No problem there. I am not sure but I Think arr2 data is allocated on the stack. Although important, I wasn't considering that point at all. It looks a little confusing, but I think it contains a rule we can learn. But look at the assertion: the type of the *slice* arr2 is int[3]. :) Bye, bearophile Ali
Re: Win Headers
On Thu, 12 Dec 2013 12:16:57 -, Mike Parker aldac...@gmail.com wrote: On 12/12/2013 8:08 PM, Regan Heath wrote: MinGW distros. Even with VC, you still have to download the Windows SDK separately. I don't believe this last statement is true. I am fairly certain that upon installing VC you have everything you need to call/use Win32 functions. The only reason to download/install a separate SDK is if your VC version is older and you want a newer SDK/API. Oh, I was sure I had to install the SDK when I installed the VC Express. But I see now that it is included. Ah, and I hadn't thought of Express as I've only used Professional etc. Good to know. Should DMD ship with X-Windows bindings, too? What about Cocoa on OS X? How big are they? If we're just talking about D header files then I am all for it, the more the merrier. It's not like internet bandwidth or hard disk space is currently an issue and it will only become less of an issue the more time rolls on. If people are really anxious about this, why not have a separate download for windows and the various flavours of UNIX.. wait a minute, we already do. :) It's not the bandwidth or disk size that bothers me. It's mostly a matter of maintenance. I appreciate the batteries included approach as far as Phobos is concerned, but given that DMD aims to be a cross-platform compiler, I don't think platform-specific API bindings should fall into that category. I mean, all these years and the Win32 bindings are still incomplete, while there are a couple of complete (or mostly complete) third-party bindings out there that do a good job of staying relevant. Why is that? Because Win32 bindings are not a priority for the DMD team. If they aren't a priority, then why ship them? Maintenance is going to depend on community members anyway. Much more efficient, IMO, as a user to use the third-party bindings. It would be different if DMD were Windows-centric, or if it didn't have a platform abstraction in the form of Phobos. Platform API bindings basically provide system functions and GUI functions. IMO, let Phobos abstract away the system and third-party libs abstract away the GUI. Beyond that, I can't imagine that those needing direct API access beyond a handful of functions will be more than a minority. So for them, let third-parties handle the API bindings too. I haven't done any straight-up Win32 development in years and when I do need a Win32 function, it's usually one that isn't available in the ancient libs DMD ships so I have to prototype it and load it manually anyway. But if I do need more of the Win32 API, then I have no problem using an external lib for it. Especially if that lib supports dub. Fair enough, I hadn't thought of it from that perspective. I agree, maintenance would not, and should not be a high priority for the maintainers of D/MD. The issue for me is then one of perception and hassle. If I am a new windows based D user and I download the installation and immediately struggle to interface with Win32 I might make the effort to go looking for these third-party bindings, I might find one which has what I need, and I might manage to get it working but that is a lot more hassle than it could be, it is enough hassle that some people might simply give up at this point - especially existing C/C++ users who have it easy currently. There is a totally different mentality in the windows world, we are far too used to everything just working out of the box. I absolutely detest the (I suspect somewhat less common than last time I had to do this) UNIX-land practice of having to download and compile dependency after dependency just to get something simple working. The same perception applies to programming languages and libraries, tho programmers are more likely to stick at it if for nothing other than the challenge it represents. So.. I think D ought to give it's blessing to one third-party Win32 library and link it prominently on the download page at the very least (apologies if this is not already the case but I haven't looked in a while), even better would be a mechanism where the installation itself would automatically obtain the library (using dub perhaps) if selected by the user. The same argument applies to other platforms and SDKs, in an ideal world they would all be downloaded/installed by the DMD installation if selected by the user. The same applies to GUI libraries, I think a vanilla Win32 GUI library needs to exist and be prominently linked or included via the installation. I think many new D users are turned off by the task of trying to piece all this together right off the bat. I realise this is a fair bit of work, but I think lowering the bar for entry should be a very high priority as the more people we can get on board the better and the sooner the better. More people means more exposure and more
Re: Type inference and overloaded functions
Ali Çehreli: But look at the assertion: the type of the *slice* arr2 is int[3]. :) I didn't notice that. It looks strange... I don't understand it. Bye, bearophile
Re: Type inference and overloaded functions
On Thursday, 12 December 2013 at 15:35:52 UTC, bearophile wrote: Ali Çehreli: But look at the assertion: the type of the *slice* arr2 is int[3]. :) I didn't notice that. It looks strange... I don't understand it. Bye, bearophile I already pointed out why it was that way AND that it's fixed now. ;)
Ranges: is it ok if front is a data member?
Consider the following: struct JustZeroes { int front = 0; enum bool = false; void popFront() {} } Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged?
Re: Ranges: is it ok if front is a data member?
I'd expect http://dlang.org/phobos/std_range.html#.isInputRange to be standard answer to this question (== yes, it is ok).
Re: Ranges: is it ok if front is a data member?
On Thu, Dec 12, 2013 at 05:19:28PM +0100, Adam D. Ruppe wrote: Consider the following: struct JustZeroes { int front = 0; enum bool = false; void popFront() {} } Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? I do this with my own ranges sometimes. Sometimes, it's more performant to precompute the value of .front and store it (as .front), and have .popFront compute the next value, than to have .front compute the value every time. AFAICT, this is perfectly fine and should work with Phobos seamlessly. The power of ducktyping! T -- Quack!
Re: Ranges: is it ok if front is a data member?
Adam D. Ruppe: Consider the following: struct JustZeroes { int front = 0; enum bool = false; void popFront() {} } Is that guaranteed to work as an input range? It seems similar to 0.repeat When you are not sure add a static assert below the range, to verify it is the kind of range you want. Bye, bearophile
updating druntime
Hello, when I try to compile something with dmd, I get following message: /usr/include/dmd/phobos/std/bitmanip.d(416): Error: undefined identifier '_xopCmp' Error: ICE: _xopCmp not found in object module. You must update druntime How to 'update druntime' ?
Re: Ranges: is it ok if front is a data member?
On 12/12/2013 08:19 AM, Adam D. Ruppe wrote: Consider the following: struct JustZeroes { int front = 0; enum bool = false; You meant empty = false; void popFront() {} } Is that guaranteed to work as an input range? Yes it is perfectly fine. And if it works for empty it should work for front. ;) The presence of std.range.hasLvalueElements is another indicator that it fine. Finally, if std.range.isInputRange returns true, it is an InputRange. Ali
Re: Ranges: is it ok if front is a data member?
On 12/12/13 17:19, Adam D. Ruppe wrote: Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? Isn't the issue here not whether or not it will work in terms of your type being a range, and more that it means that users can overwrite the value of front? It seems to me that it would be OK for personal projects where you control 100% of the code, but it wouldn't be acceptable for stuff that's intended to be used by other people.
Re: Ranges: is it ok if front is a data member?
On 12/12/13 17:51, Joseph Rushton Wakeling wrote: Isn't the issue here not whether or not it will work in terms of your type being a range, and more that it means that users can overwrite the value of front? ... if OTOH the idea is that front never changes, then I'd suggest an enum, as is already common for empty (e.g. in RNGs, you typically get enum bool empty = false).
Re: Ranges: is it ok if front is a data member?
On Thursday, 12 December 2013 at 16:52:12 UTC, Joseph Rushton Wakeling wrote: and more that it means that users can overwrite the value of front? Yeah, that's what I meant by the lvalue thing, though most the time I don't think it is even that big of a deal if it gets overwritten since the main use of ranges for me is foreach loops anyway. But yeah, that is a good point.
Re: Ranges: is it ok if front is a data member?
On Thursday, 12 December 2013 at 16:45:05 UTC, H. S. Teoh wrote: I do this with my own ranges sometimes. Sometimes, it's more performant to precompute the value of .front and store it (as .front) Yeah, that's exactly what I was doing here. My question was mostly on if there's the chance that someone will call front() but looks like that isn't supposed to happen and is wrong if it does, so cool.
Is file.rename() atomic?
void rename(in char[] from, in char[] to); Rename file from to to. If the target file exists, it is overwritten. Throws: FileException on error. Just wanted to know if this operation is atomic? or does it depend on the underlying file system? In short, in the file nanoseconds/milliseconds that this operation is occurring is it possible for someone else to be reading the same file and get a dirty read (i.e. with only half of the contents overriden, etc)? Thanks
Re: A good advertisement for 'static if'
On Thursday, 12 December 2013 at 14:55:28 UTC, Craig Dillabaugh wrote: I am not sure if this belongs in D.learn, but it might be of interest. I was writing some C++ code for a project at work and have a class that stores image data from a file. The image data can be in just about any numeric (int/float/complex) type, so I wanted a 'wrapper' class/struct that could hold any type of data without being 'parameterized' (we use templates for image access). My class contains a union ( called 'data') with every possible type of pointer and parameter for indicating the data type. However, at some point code eventually needs to get at the data, so I have the following beauty of a template method, (calling the image structure RAWImageDataStore was a bad design decision on my part, need to change that soon, its very Java-esque): template class T RAWImageDataStoreT* getBandData( ) { T t; //Check struct data type vs template type. if( datatype == TYPE_8u typeid(t) == typeid(uint8_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t8u ); } else if ( datatype == TYPE_16s typeid(t) == typeid(int16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.t16s ); } //a number of types left out, I am sure you get the idea. //but you need to see the complex types, they are beautiful. else if ( datatype == TYPE_C16s typeid(t) == typeid(std::complexint16_t) ) { return reinterpret_cast RAWImageDataStoreT* ( data.tC16s ); } \\OK, you only really needed to see one of the complex types :o) else if( datatype == TYPE_UNKNOWN ) { std::cerr Cannot access band with unknown data type. std::endl; return 0; } //+ a bit more error handling code. Initially this didn't compile because I was missing the reinterpret_cast statements. They effectively do nothing. If the template type is int8_t then I return the data.t8u pointer, which is a RAWImageDataStoreint8_t*, but have to cast it to RAWImageDataStoreint8_t*. I must do this because when I call the method type int16_t my return data.t8u returns the wrong type of pointer for the method, even though I know that if the type is int16_t this statement can never be reached. I know there was some debate in the C++ community about whether they should adopt D-like static if, which would have solved this problem, since it would compile the illegal code right out of existence. Maybe there is a better way to do this in C++, but I thought I would post here as a case-study in the usefulness of 'static if'. Craig In C++ you can use partial specialization to achieve what you want. class Storage { public: union { float* fdata; int* idata; } data; }; templatetypename T T* get(Storage stor) { return 0; //or throw exception } template float* getfloat(Storage stor) { return stor.data.fdata; } template int* getint(Storage stor) { return stor.data.idata; } int main() { Storage stor; float* fdata = getfloat(stor); return 0; }
Re: A good advertisement for 'static if'
With some improvements you also can provide compile-time error about instantiation of non-specialized function (i.e. which has T as parameter), but I'm not sure what's good way to do it in C++.
Re: Type inference and overloaded functions
Namespace: Your gig: https://github.com/D-Programming-Language/dmd/pull/2952#discussion_r8288045 This is part of the thread there: Furhtermore, what if we indeed want to pass a dynamic array ? Kenji Use cast. In real world, if overloaded function takes both int[] and int[3], normally int[3] version would provide specialized implementation for 3 length arrays (eg. unroll the loop to operate each elements of the given array). Therefore force to invoke int[] version with array literal is not usual situation. Cast will fit in such case. If I have a function foo that takes a slice as input, and I want to pass it two arrays, the first time allocated on the heap and the second on the stack, I have to use an auxiliary variable: void foo(int[]) {} void main() { foo([1, 2, 3]); int[3] tmp = [4, 5, 6]; foo(tmp); } DMD generates: __Dmain comdat L0: pushEBX mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ push3 pushEAX callnear ptr __d_arrayliteralTX mov EBX,EAX mov dword ptr [EAX],1 xor EAX,EAX mov dword ptr 4[EBX],2 mov dword ptr 8[EBX],3 add ESP,8 pop EBX ret With the []s syntax it should become: void foo(int[]) {} void main() { foo([1, 2, 3]); foo([4, 5, 6]s); } But I don't know how much common is such need. In the Rust language when you write an array literal you always prefix it with a symbol, to tell the compiler where you want to allocate it. So I think it's not so useless :-) Bye, bearophile
Re: updating druntime
On Thursday, 12 December 2013 at 16:44:28 UTC, Benji wrote: Hello, when I try to compile something with dmd, I get following message: /usr/include/dmd/phobos/std/bitmanip.d(416): Error: undefined identifier '_xopCmp' Error: ICE: _xopCmp not found in object module. You must update druntime How to 'update druntime' ? how did you install dmd/druntime/phobos originally?
Re: Ranges: is it ok if front is a data member?
On Thursday, 12 December 2013 at 16:52:12 UTC, Joseph Rushton Wakeling wrote: On 12/12/13 17:19, Adam D. Ruppe wrote: Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? Isn't the issue here not whether or not it will work in terms of your type being a range, and more that it means that users can overwrite the value of front? It seems to me that it would be OK for personal projects where you control 100% of the code, but it wouldn't be acceptable for stuff that's intended to be used by other people. Being able to assign to front is a feature of an output range.
Re: Is file.rename() atomic?
On Thursday, 12 December 2013 at 17:08:13 UTC, Jacek Furmankiewicz wrote: void rename(in char[] from, in char[] to); Rename file from to to. If the target file exists, it is overwritten. Throws: FileException on error. Just wanted to know if this operation is atomic? or does it depend on the underlying file system? In short, in the file nanoseconds/milliseconds that this operation is occurring is it possible for someone else to be reading the same file and get a dirty read (i.e. with only half of the contents overriden, etc)? Thanks Here's the implementation,as you can see it's just c function calls, no work is done in D: void rename(in char[] from, in char[] to) { version(Windows) { enforce(MoveFileExW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), MOVEFILE_REPLACE_EXISTING), new FileException( text(Attempting to rename file , from, to , to))); } else version(Posix) cenforce(core.stdc.stdio.rename(toStringz(from), toStringz(to)) == 0, to); } On a posix compliant system, I'm pretty sure this is guaranteed to be atomic as far as any other process is concerned. On windows, I don't know. A quick google suggests that there may have been a C or filesystem bug on OSX with regards to this.
Re: updating druntime
On Thursday, 12 December 2013 at 19:11:03 UTC, John Colvin wrote: On Thursday, 12 December 2013 at 16:44:28 UTC, Benji wrote: Hello, when I try to compile something with dmd, I get following message: /usr/include/dmd/phobos/std/bitmanip.d(416): Error: undefined identifier '_xopCmp' Error: ICE: _xopCmp not found in object module. You must update druntime How to 'update druntime' ? how did you install dmd/druntime/phobos originally? As it is mentioned in installation instructions to the dmd (linux-ubuntu)
Re: Ranges: is it ok if front is a data member?
On Thu, Dec 12, 2013 at 08:12:50PM +0100, Jesse Phillips wrote: On Thursday, 12 December 2013 at 16:52:12 UTC, Joseph Rushton Wakeling wrote: On 12/12/13 17:19, Adam D. Ruppe wrote: Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? Isn't the issue here not whether or not it will work in terms of your type being a range, and more that it means that users can overwrite the value of front? It seems to me that it would be OK for personal projects where you control 100% of the code, but it wouldn't be acceptable for stuff that's intended to be used by other people. Being able to assign to front is a feature of an output range. Really?? I thought the defining feature of an output range is the .put method. T -- Тише едешь, дальше будешь.
Re: Ensuring template argument is descendant of class
On Thursday, 12 December 2013 at 21:51:14 UTC, Ross Hays wrote: if (cast(Asset)T) Try this instead: if(is(T : Asset)) the is thing checks types. You can do is(T == Asset) for the specific class, or is(T : Asset) which means it implicitly converts to it - in otherworts, if T is Asset or a child of Asset.
Re: Ranges: is it ok if front is a data member?
On 12/12/2013 12:06 PM, H. S. Teoh wrote: On Thu, Dec 12, 2013 at 08:12:50PM +0100, Jesse Phillips wrote: On Thursday, 12 December 2013 at 16:52:12 UTC, Joseph Rushton Wakeling wrote: On 12/12/13 17:19, Adam D. Ruppe wrote: Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? Isn't the issue here not whether or not it will work in terms of your type being a range, and more that it means that users can overwrite the value of front? It seems to me that it would be OK for personal projects where you control 100% of the code, but it wouldn't be acceptable for stuff that's intended to be used by other people. Being able to assign to front is a feature of an output range. Really?? I thought the defining feature of an output range is the .put method. T The third condition that is checked to determine whether it is an OutputRange is indeed assignment to front. http://dlang.org/phobos/std_range.html#.put That condition is what makes a slice an OutputRange, which causes the super confusing state of output range losing elements after put'ting: :) import std.range; void main() { auto s = [ 1, 2, 3 ]; s.put(10); assert(s.length == 2); // PASSES! :p } Ali
Re: Ensuring template argument is descendant of class
On Thursday, 12 December 2013 at 21:53:20 UTC, Adam D. Ruppe wrote: On Thursday, 12 December 2013 at 21:51:14 UTC, Ross Hays wrote: if (cast(Asset)T) Try this instead: if(is(T : Asset)) the is thing checks types. You can do is(T == Asset) for the specific class, or is(T : Asset) which means it implicitly converts to it - in otherworts, if T is Asset or a child of Asset. Okay thank you, that seems to clear up the error. I found http://dlang.org/expression.html#IsExpression and had no idea is could be used with that syntax. The more D I learn the more counter-intuitive I find some aspects of the language syntax. A shame, that was my main point to start using it. Oh well! Thanks
Re: Ranges: is it ok if front is a data member?
On 12/12/13 22:55, Ali Çehreli wrote: That condition is what makes a slice an OutputRange, which causes the super confusing state of output range losing elements after put'ting: :) import std.range; void main() { auto s = [ 1, 2, 3 ]; s.put(10); assert(s.length == 2); // PASSES! :p } Ouch!! I see why it happens, but I really, really don't like that. Isn't there a case here for an override to put specifically for arrays? Or are there some benefits to it working like this?
Re: Ensuring template argument is descendant of class
On Thursday, 12 December 2013 at 22:05:17 UTC, Ross Hays wrote: http://dlang.org/expression.html#IsExpression and had no idea is could be used with that syntax. The more D I learn the more counter-intuitive I find some aspects of the language syntax. Yeah, the is expression is one of the strangest things in D. Especially if you use it to deconstruct arrays and templates! But between the two simpler forms of is(A == B) and is(A : B), and http://dlang.org/phobos/std_traits.html you can get a lot done and it isn't so bad looking.
Creating a class at a specific address in memory.
What i am looking for is something like the following. class Foo { int a, b, c; } void main() { void[] buffer = new void[1024]; auto foo = createAt!(Foo)(buffer.ptr); } Where the createAt!(Foo) creates a class of the type Foo at the specified pointer.
What is the common way of porting opaque types in C header files?
I have a lot of opaque types in C headers i'm porting to D. What is the best way to handle these? Would you just use void pointers? In the below example Tcl_AsyncHandler_ is not defined anywhere. C: typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler; D: alias void* Tcl_AsyncHandler;
Re: Creating a class at a specific address in memory.
On Thursday, 12 December 2013 at 22:54:26 UTC, TheFlyingFiddle wrote: What i am looking for is something like the following. class Foo { int a, b, c; } void main() { void[] buffer = new void[1024]; auto foo = createAt!(Foo)(buffer.ptr); } Where the createAt!(Foo) creates a class of the type Foo at the specified pointer. emplace() is what you are looking for (found inexplicably in std.conv). http://dlang.org/phobos/std_conv.html#.emplace
Re: Creating a class at a specific address in memory.
emplace() is what you are looking for (found inexplicably in std.conv). http://dlang.org/phobos/std_conv.html#.emplace Exactly what i wanted :) Thanks for the quick answer! And yeah... std.conv seems like a wierd place to have this functionallity.
Re: Ensuring template argument is descendant of class
On Thu, Dec 12, 2013 at 11:23:15PM +0100, Adam D. Ruppe wrote: On Thursday, 12 December 2013 at 22:05:17 UTC, Ross Hays wrote: http://dlang.org/expression.html#IsExpression and had no idea is could be used with that syntax. The more D I learn the more counter-intuitive I find some aspects of the language syntax. Yeah, the is expression is one of the strangest things in D. Especially if you use it to deconstruct arrays and templates! But between the two simpler forms of is(A == B) and is(A : B), and http://dlang.org/phobos/std_traits.html you can get a lot done and it isn't so bad looking. Yeah, is-expression syntax is one of the dark, ugly corners of D that unfortunately we're stuck with, because changing it now will totally break a LOT of code for merely cosmetic reasons. I honestly wish that one day this mess could be cleared up, though I'm not holding my breath for it. T -- Computer Science is no more about computers than astronomy is about telescopes. -- E.W. Dijkstra
Re: Type inference and overloaded functions
Why don't you discuss on github? And finally I did it: auto[$] a_arr2 = dyn_arr[4 .. 8]; assert(is(typeof(a_arr2) == int[4])); I will make a Pull Request tomorrow. Hope my code isn't that bad. :/
Implementing vector swizzle.
I would like to be able to do this. auto vector = vec4(1,2,3,4); vector.zxy += vec3(4,4,4); I'm currently able to do this: vector.zxy = vec3(4,4,4); Assigns 4 to the x,y and z components. and this auto other = vector.zxy; other is a vector3 with other.x == vector.z other.y == vector.x other.z == vector.y However implementing the +=, -=, *=, /= operators is tricky. How would i go about doing that?
Re: What is the common way of porting opaque types in C header files?
On 12/13/2013 7:52 AM, Gary Willoughby wrote: I have a lot of opaque types in C headers i'm porting to D. What is the best way to handle these? Would you just use void pointers? In the below example Tcl_AsyncHandler_ is not defined anywhere. C: typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler; D: alias void* Tcl_AsyncHandler; D: struct Tcl_AsyncHandler_; alias Tcl_AsyncHandler = Tcl_AsyncHandler_*;
Allowing string value with getopt without requiring it
Hello. I'm just getting into D (literally writing my first program), and I can't figure out how to do this with getopt: I want to have the option --log, which will enable logging (set a bool variable to true). However, I want the program to also accept --log=filename to allow the user to define custom log file. If --log is used without filename, a default file will be used. I tried this: getopt(args, log, log, log, logFile); Passing just --log to the program works fine, the boolean is set to true. However, using --log=test.log throws an exception, and seemingly getopt expects either true or false. How would I go about implementing this without creating another option like --log-file for custom file name?
Re: Type inference and overloaded functions
On Thursday, 12 December 2013 at 18:20:25 UTC, bearophile wrote: Namespace: Your gig: https://github.com/D-Programming-Language/dmd/pull/2952#discussion_r8288045 This is part of the thread there: Furhtermore, what if we indeed want to pass a dynamic array ? Kenji Use cast. In real world, if overloaded function takes both int[] and int[3], normally int[3] version would provide specialized implementation for 3 length arrays (eg. unroll the loop to operate each elements of the given array). Therefore force to invoke int[] version with array literal is not usual situation. Cast will fit in such case. If I have a function foo that takes a slice as input, and I want to pass it two arrays, the first time allocated on the heap and the second on the stack, I have to use an auxiliary variable: void foo(int[]) {} void main() { foo([1, 2, 3]); int[3] tmp = [4, 5, 6]; foo(tmp); } There's a known issue that the function foo takes the slice of stack allocated data. Today some peoples argue that it is unsafe operation and should be disallowed in @safe code. With the []s syntax it should become: void foo(int[]) {} void main() { foo([1, 2, 3]); foo([4, 5, 6]s); } But I don't know how much common is such need. In the Rust language when you write an array literal you always prefix it with a symbol, to tell the compiler where you want to allocate it. So I think it's not so useless :-) Bye, bearophile I'm afraid that allowing foo([4, 5, 6]s) would easily cause memory corruption. I don't want to hurt language future by the trivial syntactic sugar. Kenji Hara
segfault when using std.parallelism and std.process.executeShell
Hi, The following code dies with a segfault : import std.stdio, std.parallelism, std.process; void main() { auto a=[hello,world,goodbye]; foreach(s; parallel(a,1)) { auto ls=executeShell(echo ~s); writeln(ls.output); } } both in ldc and dmd. Removing either the parallel or running something other than executeShell (eg. just doing a writeln) works, which suggests to me that it's something about the way executeShell is interacting with parallel. Pulling it up in lldb, I get : * thread #2: tid = 0x16738e6, 0x000100039198 test`D3std7process7environFNbNdNeZxPPa + 20, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x000100039198 test`D3std7process7environFNbNdNeZxPPa + 20 Any thoughts on what might be going wrong? Is executeShell somehow not threadsafe? Thanks! -- Nikhil
Re: A good advertisement for 'static if'
On Thursday, 12 December 2013 at 17:34:13 UTC, FreeSlave wrote: On Thursday, 12 December 2013 at 14:55:28 UTC, Craig Dillabaugh wrote: I am not sure if this belongs in D.learn, but it might be of interest. I was writing some C++ code for a project at work and have a class that stores image data from a file. The image data can be in just about any numeric (int/float/complex) type, so I wanted a 'wrapper' class/struct that could hold any type of data without being 'parameterized' (we use templates for image access). clip Maybe there is a better way to do this in C++, but I thought I would post here as a case-study in the usefulness of 'static if'. Craig In C++ you can use partial specialization to achieve what you want. class Storage { public: union { float* fdata; int* idata; } data; }; templatetypename T T* get(Storage stor) { return 0; //or throw exception } template float* getfloat(Storage stor) { return stor.data.fdata; } template int* getint(Storage stor) { return stor.data.idata; } int main() { Storage stor; float* fdata = getfloat(stor); return 0; } Thanks for this suggestion, it avoids the reinterpret cast nicely. I've used template specialization in other cases, but it didn't occur to me in this case (plus adding the 'reinterpret_cast' required less refactoring on my part at the time). However, I may switch my code to use this method since the resulting executable should be smaller/faster since the big if ... else statement isn't inserted with every template instantiation. However neither solution is as nice as 'static if' in D. The benefits of having all my type checks in one space, and the 'dead' code is eliminated in the instantiations. Cheers, Craig
Re: Implementing vector swizzle.
On Friday, 13 December 2013 at 00:53:17 UTC, TheFlyingFiddle wrote: I would like to be able to do this. auto vector = vec4(1,2,3,4); vector.zxy += vec3(4,4,4); I'm currently able to do this: vector.zxy = vec3(4,4,4); Assigns 4 to the x,y and z components. and this auto other = vector.zxy; other is a vector3 with other.x == vector.z other.y == vector.x other.z == vector.y However implementing the +=, -=, *=, /= operators is tricky. How would i go about doing that? i think gl3n[1] have implemented full GLSL-like swizzle. i haven't much used it, but you can look how it's done here. [1] https://github.com/Dav1dde/gl3n
Re: Ensuring template argument is descendant of class
Yeah, is-expression syntax is one of the dark, ugly corners of D that unfortunately we're stuck with, because changing it now will totally break a LOT of code for merely cosmetic reasons. I honestly wish that one day this mess could be cleared up, though I'm not holding my breath for it. T I know this is probably obvious, but if D were allowed to just make one big breaking change for D3 or something, and fix every dark corner it has. Would that really be so bad? I know it would break things but... I kind of long for it.
Re: Ensuring template argument is descendant of class
On Friday, 13 December 2013 at 05:22:26 UTC, Ross Hays wrote: Yeah, is-expression syntax is one of the dark, ugly corners of D that unfortunately we're stuck with, because changing it now will totally break a LOT of code for merely cosmetic reasons. I honestly wish that one day this mess could be cleared up, though I'm not holding my breath for it. T I know this is probably obvious, but if D were allowed to just make one big breaking change for D3 or something, and fix every dark corner it has. Would that really be so bad? I know it would break things but... I kind of long for it. I'm sympathetic to this POV, or something similar. For example, a multiyear plan to deprecate the 'is' syntax and replace it with something better, in the current D. I'm not a fan of gratuitous changes which make the language unstable, but if there were a pleasing design to replace 'is' I'd like to think that D users could change the relevant sources given a long enough deprecation window. Changing every dark corner and every poor choice is too much. For instance, a lot of people think that immutability and 'nothrow' should have been the default, but changing that would be dramatic and probably will have to wait for a D3 or new language. -- Brian
Re: Ensuring template argument is descendant of class
On Fri, Dec 13, 2013 at 06:42:26AM +0100, Brian Rogoff wrote: On Friday, 13 December 2013 at 05:22:26 UTC, Ross Hays wrote: Yeah, is-expression syntax is one of the dark, ugly corners of D that unfortunately we're stuck with, because changing it now will totally break a LOT of code for merely cosmetic reasons. I honestly wish that one day this mess could be cleared up, though I'm not holding my breath for it. T I know this is probably obvious, but if D were allowed to just make one big breaking change for D3 or something, and fix every dark corner it has. Would that really be so bad? I know it would break things but... I kind of long for it. I'm sympathetic to this POV, or something similar. For example, a multiyear plan to deprecate the 'is' syntax and replace it with something better, in the current D. I'm not a fan of gratuitous changes which make the language unstable, but if there were a pleasing design to replace 'is' I'd like to think that D users could change the relevant sources given a long enough deprecation window. I vote for this. Good luck convincing Walter, though. Changing every dark corner and every poor choice is too much. For instance, a lot of people think that immutability and 'nothrow' should have been the default, but changing that would be dramatic and probably will have to wait for a D3 or new language. [...] Not to mention such a big change (or such numerous fundamental changes) would probably introduce new dark corners that then need fixing. :) Language design ain't easy. T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. Chesterton
Re: Type inference and overloaded functions
On Friday, 13 December 2013 at 04:13:04 UTC, Kenji Hara wrote: On Thursday, 12 December 2013 at 18:20:25 UTC, bearophile wrote: If I have a function foo that takes a slice as input, and I want to pass it two arrays, the first time allocated on the heap and the second on the stack, I have to use an auxiliary variable: void foo(int[]) {} void main() { foo([1, 2, 3]); int[3] tmp = [4, 5, 6]; foo(tmp); } There's a known issue that the function foo takes the slice of stack allocated data. Today some peoples argue that it is unsafe operation and should be disallowed in @safe code. Kenji Hara I think there is consensus that in @safe code this should be blocked.
Re: Type inference and overloaded functions
On Friday, December 13, 2013 07:19:50 Maxim Fomin wrote: On Friday, 13 December 2013 at 04:13:04 UTC, Kenji Hara wrote: On Thursday, 12 December 2013 at 18:20:25 UTC, bearophile wrote: If I have a function foo that takes a slice as input, and I want to pass it two arrays, the first time allocated on the heap and the second on the stack, I have to use an auxiliary variable: void foo(int[]) {} void main() { foo([1, 2, 3]); int[3] tmp = [4, 5, 6]; foo(tmp); } There's a known issue that the function foo takes the slice of stack allocated data. Today some peoples argue that it is unsafe operation and should be disallowed in @safe code. Kenji Hara I think there is consensus that in @safe code this should be blocked. Slicing a static array is exactly the same as taking the address of a local variable, except that you then have a length in addition to the address. If that slice is assigned to anything which has a lifetime greater than that of the static array that was sliced, then the slice will be referring to invalid memory. That's clearly @system, and I don't see how anyone could even argue otherwise. Yes, there is plenty of code which is currently considered @safe by the compiler which will break once slicing a static array is considered @system like it needs to be (especially because static arrays are unfortunately automatically sliced when they're passed to a function which takes a dynamic array - I really wish that that were'n the case), but that can't be avoided. So, yes, changing it so that slicing a static array is @system will cause annoying code breakage, but I don't see any way around it without breaking what @safe means and does. - Jonathan M Davis
Re: Ranges: is it ok if front is a data member?
On Thursday, December 12, 2013 17:19:28 Adam D. Ruppe wrote: Consider the following: struct JustZeroes { int front = 0; enum bool = false; void popFront() {} } Is that guaranteed to work as an input range? I ask because I've so often written: T current; @property T front() { return current; } that it just seems silly to me to write the extra lines when current == front. I realize there is a small difference there, in that front is not an lvalue here, but is when it is a direct member, but other than that, is this an acceptable form? Or does the lvalue thing mean it is strongly discouraged? It's perfectly fine as far as isInputRange goes. template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = void; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } All that's required with regards to front is auto h = r.front; That works perfectly fine with a variable. The primary reason to avoid it is encapsulation, but if you aren't worried about that, then it should work just fine to have front as a public member variable. - Jonathan M Davis
Re: Ranges: is it ok if front is a data member?
On Thursday, 12 December 2013 at 21:55:20 UTC, Ali Çehreli wrote: The third condition that is checked to determine whether it is an OutputRange is indeed assignment to front. http://dlang.org/phobos/std_range.html#.put That condition is what makes a slice an OutputRange, which causes the super confusing state of output range losing elements after put'ting: :) import std.range; void main() { auto s = [ 1, 2, 3 ]; s.put(10); assert(s.length == 2); // PASSES! :p } Ouch. That surely is confusing. Why don't arrays provide .put which appends the element?
Re: Ranges: is it ok if front is a data member?
On Friday, 13 December 2013 at 07:28:57 UTC, qznc wrote: Ouch. That surely is confusing. Why don't arrays provide .put which appends the element? Basically, when you're using an array as an output range, you're saying Hey, here's a slice of memory to put the results in. You're _not_ saying hey, here's a bit of memory that I have already, so put it on the end of it. The behavior is technically correct, but output ranges probably aren't being described as well as they could be. That said, the concept is a bit unusual and strange to me as well. I love the concept of InputRanges but I'd really like to see more coverage on OutputRanges and how to work effectively with them (and, especially, arrays as OutputRanges).
Re: Ensuring template argument is descendant of class
I remember seeing some posts about D and how the way it sounded was that D kind of filled the role of C++, without all the burden of years of full backwards comparability. I wouldn't dare say it is that bad, but this is how the problem starts I feel. I would love to see a release cycle like you mentioned. Something like OpenGL deprecating would be great but I could see issues for things like keywords (IsExpression for example). But what do I know. I've never written a programming language. I just hope the end result isn't wait for another! Ross