Re: D/Objective-C 64bit
I have a question regarding selectors. I wanted to set a double-click action in the tableview example. Currently i get the selector like this: objc.runtime.SEL doubleAction = cast(objc.runtime.SEL)AppDelegate.doubleClickAction ; demoTableView.setDoubleAction(doubleAction) ; Is this the recommended/right way to do it? Then the double-click action looks like this: void doubleClickAction(NSObject sender) { NSTableView tableView = cast(NSTableView)sender ; if (sender is demoTableView) { NSInteger clickedRow = demoTableView.clickedRow() ; Item item = cast(Item)_applications.objectAtIndex(clickedRow) ; NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) ; } } I would expect to be using an ObjcObject instead of an NSObject here, but this does not compile. The signature of the target action seems to be irrelevant, it may have no or more parameters. I guess this is just ok and the expected behavior. In Objective-C, if the action signature does not comply you will get warnings or errors.
Re: D/Objective-C 64bit
On 2014-11-03 09:51, Christian Schneider wrote: I have a question regarding selectors. I wanted to set a double-click action in the tableview example. Currently i get the selector like this: objc.runtime.SEL doubleAction = cast(objc.runtime.SEL)AppDelegate.doubleClickAction ; demoTableView.setDoubleAction(doubleAction) ; Is this the recommended/right way to do it? No, have a look at the tests for selectors [1]. I'm not sure if you need to cast it to SEL. Try just using auto: auto doubleAction = AppDelegate.doubleClickAction; Then the double-click action looks like this: void doubleClickAction(NSObject sender) { NSTableView tableView = cast(NSTableView)sender ; if (sender is demoTableView) { NSInteger clickedRow = demoTableView.clickedRow() ; Item item = cast(Item)_applications.objectAtIndex(clickedRow) ; NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) ; } } I would expect to be using an ObjcObject instead of an NSObject here, but this does not compile. The signature of the target action seems to be irrelevant, it may have no or more parameters. I guess this is just ok and the expected behavior. Hmm, that sounds strange. What exact errors do you get? [1] https://github.com/jacob-carlborg/dmd/blob/d-objc/test/runnable/objc/objc_selector.d -- /Jacob Carlborg
fitted kitchens uk
fitted kitchens uk. Thirty Ex Display Kitchens To Clear. w w w. e x d i s p l a y k i t c h e n s 1. c o. u k £ 595 Each with appliances.Tel 01616-694785
Re: Errors when compiling
On 11/3/2014 2:36 AM, James wrote: It's telling me that the libraries are in an invalid format. How can I get the correct ones ? I got those from the GLFW website Since you're compiling with -m64, make sure you have the 64-bit GLFW binaries and not the 32-bit. Also, you won't need your own copy of opengl32.lib if you've installed the Windows SDK along with your Visual Studio toolchain. If you were to use the DerelictGLFW3 [1] DerelictGL3 [2] bindings (preferably using DUB [3] to manage your project) then you would not have any link-time dependencies. With DUB, you don't even need to download the bindings, since it will manage it all for you. All you would need is the shared libraries (the DLLs). The Derelict bindings load the shared libraries at run time (see the README in the github repo for each project for details). You still have to make sure you're using the appropriate GLFW DLL (32-bit vs 64-bit). [1] https://github.com/DerelictOrg/DerelictGLFW3 [2] https://github.com/DerelictOrg/DerelictGL3 [3] http://code.dlang.org/download
Re: DIP66 v1.1 (Multiple) alias this.
On 11/2/14 6:55 AM, IgorStepanov wrote: http://wiki.dlang.org/DIP66 * At the AliasThis declaration semantic stage, the compiler can perform the initial checks and reject the obviously incorrect AliasThis declarations. - it might be simpler (for the sake of simplifying generic code) to just delay all error checking to the first use. I disagree with that. Current check is not recursive and prevent you code from a silly errors: struct X(T, V) { T t; V v; alias t this; alias v this; //Error if is(T == V). However this code is fundamentally broken, and this error should be raised as soon as possible. } The code is not fundamentally broken if alias this is never used. I agree rejecting the code compulsively is also sensible, ONLY if there is a simple way to write a static if condition to make the code work. Meaning: struct X(T, V) { T t; V v; static if (please_fill_this) alias t this; static if (please_fill_this_too) alias v this; } If the two conditions are too hard to write then it would be difficult to argue this point successfully. class A : B { B b; alias b this; //Error: super type (B) always hides aliasthised type B because base classes should be processed before alias this types. } That's fine to reject in all cases. * Regarding the lookup, opDispatch shouldn't come before alias this, or should come before base class lookup. Essentially alias this is subtyping so it should enjoy similar privileges to base classes. A different way to look at it is opDispatch is a last resort lookup mechanism, just one step above the UFCS lowering. I agree with this suggestion, however it breaks an existing code. Walter and I would agree to making the presence of BOTH alias this and opDispatch a compile-time error. That would break existing code but not change semantics silently. When alias this was introduced the decision of opDispatch vs. alias this was not deeply elaborated. In hindsight opDispatch should probably have come after because it's really a method not found catch-all whereas alias this is subtyping. That said, compelling arguments might come later the other direction. So making it an error for now would be sensible. It should only affect rather obscure code. opDispatch shouldn't come before base type lookup, because it will hide basic methods like toString. Agreed. opDispatch may come after alias this lookup, however it will fundamentally change program behaviour. Understood. Current (implemented is released compiler) behaviour: [snip] Understood. All: okay to make alias this + opDispach applicable to the same expression an error? And, TBH, this issue not relevant with multiple alias this :-) Agreed. It is, however, good to revisit the decision and tighten that screw properly now that we have the opportunity. * The DIP should specify the working of alias this as rewrites/lowerings, not pseudocode. Basically for each kth declaration alias symbolk this; the compiler rewrites obj.xyz as obj.symbolk.xyz and then does the usual lookup on that expression. That means the whole algorithms is applied again etc. If more than one rewrite typechecks, that's an ambiguity error. Ok. I've removed pseudocode. Is it better now? I'm flying now :o)... will take a look. * IMPORTANT: The DIP must discuss rvalue vs. lvalue cases. Done. I've added corresponding chapter to the DIP and commit to the PR. I'm sending this now with these points, will make one more pass through the DIP when I'm online again. Andrei
Re: std.experimental.logger formal review round 3
On 11/2/14 10:07 PM, Dicebot wrote: On Sunday, 2 November 2014 at 18:42:20 UTC, David Nadlinger wrote: Imagine somebody has a type that cannot be @trusted because of whatever reason. Maybe because it's legacy code, maybe it uses resources it does not manage, … If you forcibly make logf @safe, then this type cannot be used with logf without some crazy workaround (simply using to!string might produce an unneeded allocation if the type uses the sink-delegate signature for toString). Why not leave this up to the compiler and support more use cases without degrading the experience for @safe clients? David You mean something like user type toString() which is legitimately @system and can't be made @trusted? Yes, this makes sense. Will need to also add tests for that. Consider me convinced :) Fantastic, thanks! -- Andrei
Re: Programming Language for Games, part 3
On 11/2/14 11:11 PM, bearophile wrote: Andrei Alexandrescu: Is that a best-effort kind of approach? If so, that would be pretty bad... I don't exactly know how that Rust macro works, sorry, I am still rather ignorant about Rust. Then don't mention it in the first place. You either make points you can stand by on don't. Don't fumble around. -- Andrei
Re: toString refactor in druntime
On 11/3/14 8:45 AM, Manu via Digitalmars-d wrote: On 2 November 2014 04:15, Walter Bright via Digitalmars-d digitalmars-d@puremagic.com wrote: Why would templates make you nervous? They're not C++ templates! What do you mean? How are D templates any different than C++ templates in a practical sense? Probably about three times easier to read and write. I want a binary lib to be a binary lib. I don't think it's good form for the lowest level library in the language ecosystem to depend on templates (ie, client-side code generation). This is the fundamental lib that will be present in every D application there is. If it is not a binary lib, then it can't be updated. Consider performance improvements are made to druntime, which every application should enjoy. If the code is templates, then the old version at time of compiling is embedded into existing client software, the update will have no effect unless the client software is rebuilt. More important, what about security fixes in druntime... imagine a critical security problem in druntime (I bet there's lots!); if we can't update druntime, then *every* D application is an exploit. Very shaky foundation for an ecosystem... The same argument goes for all statically linked libraries. druntime is a fundamental ecosystem library. It should be properly semantically version-ed, and particularly for security reasons, I think this should be taken very very seriously. This argument could equally be applicable to phobos, and I've always been nervous about it too for the same reasons... but I'll draw a line there, in that phobos is not critical for an application to build and link, and so much of the API is already templates, it would be impossible to change that now. Within reason, most of the runtime and standard library ought to be generic so as to adapt best to application needs. Generics are a very powerful mechanism for libraries. Andrei
Re: toString refactor in druntime
On 11/2/2014 11:45 PM, Manu via Digitalmars-d wrote: On 2 November 2014 04:15, Walter Bright via Digitalmars-d digitalmars-d@puremagic.com wrote: Why would templates make you nervous? They're not C++ templates! What do you mean? How are D templates any different than C++ templates in a practical sense? They're much more straightforward to use, syntactically and semantically. I want a binary lib to be a binary lib. I don't think it's good form for the lowest level library in the language ecosystem to depend on templates (ie, client-side code generation). What's the problem with that? This is the fundamental lib that will be present in every D application there is. If it is not a binary lib, then it can't be updated. Have you ever looked at the C openssl.lib? The .h files with it are loaded with metaprogramming done with C macros. Yet I've never heard anyone complain about it. C .h files for DLLs are typically stuffed with C macros. Consider performance improvements are made to druntime, which every application should enjoy. If the code is templates, then the old version at time of compiling is embedded into existing client software, the update will have no effect unless the client software is rebuilt. More important, what about security fixes in druntime... imagine a critical security problem in druntime (I bet there's lots!); if we can't update druntime, then *every* D application is an exploit. Very shaky foundation for an ecosystem... The defense presents openssl as Exhibit A! (The templates really only present the interface to the dll, not the guts of it.) druntime is a fundamental ecosystem library. It should be properly semantically version-ed, and particularly for security reasons, I think this should be taken very very seriously. openssl!!! BTW, you should know that if a template is instantiated by the library itself, the compiler won't re-instantiate it and insert that in the calling code. It'll just call the instantiated binary.
Re: Programming Language for Games, part 3
Andrei Alexandrescu: Then don't mention it in the first place. You either make points you can stand by on don't. Don't fumble around. -- Andrei There's also a third option, offer the information I have, if it's valuable, even when it's not complete because others can get interested and find the full information themselves (note: this is how science works in laboratories). Bye, bearophile
Re: The cost of write barriers
On Sunday, 2 November 2014 at 10:36:13 UTC, Jonathan Barnard wrote: On Sunday, 2 November 2014 at 10:30:21 UTC, Araq wrote: And I think these are meaningless results. You can see here for instance what a write barrier can look like: http://psy-lob-saw.blogspot.de/2014/10/the-jvm-write-barrier-card-marking.html Btw, how are write barriers implemented in Go now? Would such an implementation also be possible in a language like Go or D with internal/'thin' pointers? Yes, however the compiler needs to know all the places where your code mutates pointers. That means you can't use memcpy to copy some data with pointers into an old object or array. And you can't mutate pointers from C code.
Re: The cost of write barriers
On Monday, 3 November 2014 at 11:50:57 UTC, thedeemon wrote: On Sunday, 2 November 2014 at 10:36:13 UTC, Jonathan Barnard wrote: On Sunday, 2 November 2014 at 10:30:21 UTC, Araq wrote: And I think these are meaningless results. You can see here for instance what a write barrier can look like: http://psy-lob-saw.blogspot.de/2014/10/the-jvm-write-barrier-card-marking.html Btw, how are write barriers implemented in Go now? Some information on the upcoming release notes. http://tip.golang.org/doc/go1.4#impl Would such an implementation also be possible in a language like Go or D with internal/'thin' pointers? Yes, however the compiler needs to know all the places where your code mutates pointers. That means you can't use memcpy to copy some data with pointers into an old object or array. And you can't mutate pointers from C code. Now it is officially forbidden to just give a Go pointer directly to a C function. It needs to be given as an uintptr, if I am not mistaken.
Re: `alias newSymbol = existingSymbol` or `alias existingSymbol newSymbol`
On Monday, 3 November 2014 at 02:43:03 UTC, David Nadlinger wrote: On Tuesday, 28 October 2014 at 08:29:22 UTC, Jonathan M Davis via Digitalmars-d wrote: I see no reason to say anything about the alias syntax in the style guide. Consistency, and thus less confusion/mental overhead. I don't think that you'll be able to make a strong case for Either it should be considered fine to use, or we should deprecate it. If we started with a clean slate today, there wouldn't be a good reason to include the old syntax. It is an outlier as we've generally moved away from C-style ordering of types/declarations, and also can't do inline templates. And if we agree that the new syntax is to be preferred – and it seems like except for you we pretty unambiguously do –, I don't see why we shouldn't put that out as an official recommendation. Of course, breaking legacy code over this by deprecating the old syntax might ultimately not be worth it. I don't see how this can be construed as an argument against putting it in the style guide, however. In fact, if we planned to deprecate it anyway, this would rather be a reason _not_ to to bother with putting it in the style guide first. To summarize why the new syntax is better than the old one: - It's more straightforward for newcomers, its order is the same as for basic assignments. If you somehow find that unnatural like you've claimed earlier, then you've merely trained your brain to read alias assignments backwards compared to assign expressions. - Arguably the new syntax also makes it easier to skim-read the code, as the most important part (the symbol introduced) is at the beginning of the line, not hidden after some potentially multi-line template instantiation. Granted, you might say that this is not very relevant, but I think you'd find it hard to argue that the syntax is _less_ readable. - The new syntax also has the advantage that it allows to easily declare template aliases, for example: --- alias Seq(T...) = T; --- By the way, using is regularly recommended for use in C++11 and up now instead of typedef for much the same reasons (just look at the CppCon talks for some data points). David I agree with basically everything you said. I only have one thing I want to say. The only reason the new syntax was introduced is because its an improvement on the old, it would never have been added otherwise. That alone should be reason enough for it to be prefered.
Re: bug in assigning to dynamic array element
On 11/1/14 8:04 AM, ketmar via Digitalmars-d wrote: On Sat, 01 Nov 2014 11:55:53 + anonymous via Digitalmars-d digitalmars-d@puremagic.com wrote: On Saturday, 1 November 2014 at 11:50:34 UTC, ketmar via Digitalmars-d wrote: this *IS* a bug. either compiler should error on this, or it shouldn't modify random memory. imagine the situation when old array contents not only collected by GC, but that memory was allocated to something completely different. The old array is still alive and kicking. The left-hand side still references it. It wasn't collected. You're not writing to random memory. so it's not only writes to the stale copy, but protects that copy from GC. what a great thing! and all this without even a small warning from compiler. i can expect such behavior from c or c++ with all their UB, but not from D. this is not only ugly, this is plainly wrong. No, it's not. It's exactly as you requested when you wrote that code :) Note, you can fix this by overloading opAssign in Info, and it should work as you expect. This will force a delay in the evaluation of which array is used until *after* the RHS is done. -Steve
Re: bug in assigning to dynamic array element
On 11/1/14 10:44 AM, Iain Buclaw via Digitalmars-d wrote: On 1 November 2014 14:19, ketmar via Digitalmars-d digitalmars-d@puremagic.com wrote: On Sat, 1 Nov 2014 13:56:49 + Iain Buclaw via Digitalmars-d digitalmars-d@puremagic.com wrote: if such assigns will be forbidden for any arrays... this is even worse. what? your shiny language can't do what even the simpliest C compiler can do? now try to convince me that D is not a toy. That - for sure - is where you're wrong. :-) i was talking about C, not that abomination. but if D will compete with C++ for the quirks... than C++ is a winner. ;-) besides, i clearly see 'list.ptr' there. i don't see 'dynArray.ptr' in D code. if i was using '.ptr' directly and it changes by the way... ok, it was my fault. but i never used '.ptr' in my sample! You can clearly see the 'list.length' though. You can't possibly go off the assumption that if you grow the size of a dynamic array, it's area in memory won't be relocated. I think his assumption is that an array reference should not *re-alias* into another array. This is the problem with calling them dynamic arrays -- they are slices of dynamic arrays. And altering the length of a slice can make it point at an entirely new dynamic array, with the original array (and in fact the original slice) still intact. If, for example, the array was an object, and it's *private* underlying storage moved, well then the opIndexAssign would use the new storage, and the array reference doesn't actually change. I don't think it's unreasonable to expect this, but that's based on an incorrect understanding of how D dynamic arrays work. There is a reason we get at least 1 question a week on how D arrays work. -Steve
Re: toString refactor in druntime
On 10/31/14 4:50 PM, Jonathan Marler wrote: I wrote a Windows CE app to run on our printers here at HP to test what the Microsoft ARM compiler does with virtual function calls. I had to do an operation with a global volatile variable to prevent the compiler from inlining the non-virtual function call but I finally got it to work. Calling the function 100 million times yielded the following times: Windows Compiler on ARM (Release) --- NonVirtual: 0.537000 seconds Virtual : 1.281000 seconds Windows Compiler on x86 (Release) --- NonVirtual: 0.226000 seconds Virtual : 0.226000 seconds Windows Compiler on x86 (Debug) --- NonVirtual: 2.94 seconds Virtual : 3.204000 seconds Here's the link to the code: http://marler.info/virtualtest.c Thanks, this is helpful. -Steve
Re: DIP66 v1.1 (Multiple) alias this.
* At the AliasThis declaration semantic stage, the compiler can perform the initial checks and reject the obviously incorrect AliasThis declarations. - it might be simpler (for the sake of simplifying generic code) to just delay all error checking to the first use. I disagree with that. Current check is not recursive and prevent you code from a silly errors: struct X(T, V) { T t; V v; alias t this; alias v this; //Error if is(T == V). However this code is fundamentally broken, and this error should be raised as soon as possible. } The code is not fundamentally broken if alias this is never used. I agree rejecting the code compulsively is also sensible, ONLY if there is a simple way to write a static if condition to make the code work. Meaning: struct X(T, V) { T t; V v; static if (please_fill_this) alias t this; static if (please_fill_this_too) alias v this; } If the two conditions are too hard to write then it would be difficult to argue this point successfully. This code can be rewritten as: struct X(T, V) { T t; V v; alias t this; static if (!is(V == T)) alias v this; } The code is not fundamentally broken if alias this is never used. I meant that when you say that X is a subtype of T and X is a subtype of V where you don't know what T and V are, it means you don't really know what you're doing. And that is an error and the compiler should inform you about it as soon as possible. However I may be mistaken. Understood. All: okay to make alias this + opDispach applicable to the same expression an error? I think it will be nice. I'm sending this now with these points, will make one more pass through the DIP when I'm online again. Ok, I'll wait. And please, answer the question about the is-expression.
Re: toString refactor in druntime
On 11/1/14 9:30 AM, Manu via Digitalmars-d wrote: On 31 October 2014 01:30, Steven Schveighoffer via Digitalmars-d Sorry, I meant future *D supported* platforms, not future not-yet-existing platforms. I'm not sure what you mean. I've used D on current and existing games consoles. I personally think it's one of D's most promising markets... if not for just a couple of remaining details. I don't think D officially supports these platforms. I could be wrong. Also, my suggestion will certainly perform better on all platforms. There is no platform that can benefit from the existing proposal of an indirect function call per write vs something that doesn't. Performance isn't the only consideration. In your case, it has a higher priority than ease of implementation, flexibility, or usability. But that's not the case everywhere. Consider the flip-side: on x86, your mechanism may be a hair faster than just having a delegate. Is it worth all the extra trouble for those folks to have to save some state or deal with reallocating buffers in their toString functions? Before we start ripping apart our existing APIs, can we show that the performance is really going to be so bad? I know virtual calls have a bad reputation, but I hate to make these choices absent real data. My career for a decade always seems to find it's way back to fighting virtual calls. (in proprietary codebases so I can't easily present case studies) But it's too late now I guess. I should have gotten in when someone came up with the idea... I thought it was new. At the moment, you are stuck with most toString calls allocating on the GC every time they are called. I think the virtual call thing should be a pleasant improvement :) But in all seriousness, I am not opposed to an alternative API, but the delegate one seems to find the right balance of flexibility and ease of implementation. I think we can use any number of toString APIs, and in fact, we should be able to build on top of the delegate version a mechanism to reduce (but not eliminate obviously) virtual calls. For instance, D's underlying i/o system uses FILE *, which is about as virtual as you can get. So are you avoiding a virtual call to use a buffer to then pass to a virtual call later? I do a lot of string processing, but it never finds it's way to a FILE*. I don't write console based software. Just an example. Point taken. A reentrant function has to track the state of what has been output, which is horrific in my opinion. How so? It doesn't seem that bad to me. We're talking about druntime here, the single most used library in the whole ecosystem... that shit should be tuned to the max. It doesn't matter how pretty the code is. Keep in mind that any API addition is something that all users have to deal with. If we are talking about a specialized, tuned API that druntime and phobos can use, I don't think it would be impossible to include this. But to say we only support horrible allocate-every-toString-call mechanism, and please-keep-your-own-state-machine mechanism is not good. The main benefit of the delegate approach is that it's easy to understand, easy to use, and reasonably efficient. It's a good middle ground. It's also easy to implement a sink. Both sides are easy, it makes the whole thing more approachable. The largest problem I see is, you may not know before you start generating strings whether it will fit in the buffer, and therefore, you may still end up eventually calling the sink. Right. The api should be structured to make a virtual call _only_ in the rare instance the buffer overflows. That is my suggestion. You can be certain to supply a buffer that will not overflow in many/most cases. I, and I'm sure most of the developers, are open to new ideas to make something like this as painless as possible. I still think we should keep the delegate mechanism. Note, you can always allocate a stack buffer, use an inner function as a delegate, and get the inliner to remove the indirect calls. Or use an alternative private mechanism to build the data. We're talking about druntime specifically. It is a binary lib. The inliner won't save you. Let's define the situation here -- there is a boundary in druntime in across which no inlining can occur. Before the boundary or after the boundary, inlining is fair game. So for instance, if a druntime object has 3 members it needs to toString in order to satisfy it's own toString, those members will probably all be druntime objects as well. In which case it can optimize those sub-calls. And let's also not forget that druntime has template objects in it as well, which are ripe for inlining. This is what I meant. Would you say that *one* delegate call per object output is OK? I would say that an uncontrollable virtual call is NEVER okay, especially in otherwise trivial and such core functions like toString in druntime. But one is certainly better than
Re: toString refactor in druntime
On 10/31/14 3:04 PM, Walter Bright wrote: On 10/27/2014 12:42 AM, Benjamin Thaut wrote: I'm planning on doing a pull request for druntime which rewrites every toString function within druntime to use the new sink signature. That way druntime would cause a lot less allocations which end up beeing garbage right away. Are there any objections against doing so? Any reasons why such a pull request would not get accepted? Why a sink version instead of an Output Range? A sink is an output range. Supporting all output ranges isn't necessary. -Steve
Re: toString refactor in druntime
On 10/31/14 3:07 PM, H. S. Teoh via Digitalmars-d wrote: On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote: On 10/27/2014 12:42 AM, Benjamin Thaut wrote: I'm planning on doing a pull request for druntime which rewrites every toString function within druntime to use the new sink signature. That way druntime would cause a lot less allocations which end up beeing garbage right away. Are there any objections against doing so? Any reasons why such a pull request would not get accepted? Why a sink version instead of an Output Range? To allow toString to be a virtual function, perhaps? Besides, the sink version basically allows encapsulation of an output range -- instead of calling x.toString(outputRange) you just write: x.toString((const(char)[] data) { outputRange.put(data); }); No, please don't do that. It's put(outputRange, data); -Steve
Re: toString refactor in druntime
On 10/31/14 5:01 PM, Walter Bright wrote: On 10/31/2014 12:07 PM, H. S. Teoh via Digitalmars-d wrote: On Fri, Oct 31, 2014 at 12:04:24PM -0700, Walter Bright via Digitalmars-d wrote: On 10/27/2014 12:42 AM, Benjamin Thaut wrote: I'm planning on doing a pull request for druntime which rewrites every toString function within druntime to use the new sink signature. That way druntime would cause a lot less allocations which end up beeing garbage right away. Are there any objections against doing so? Any reasons why such a pull request would not get accepted? Why a sink version instead of an Output Range? To allow toString to be a virtual function, perhaps? Output ranges can be virtual functions. All an output range is is a type with a put method. He said toString not sink. And there are more use cases than a type that implements 'put'. What I object to with the sink design is there is no consistency in design - we cannot preach ranges as a best practice and then use some other methodology. Keep in mind that saying toString will take output ranges means that ALL toString implementers must handle ALL forms of output ranges. It's not an issue with we don't know what we're doing, it's an issue of let's not make everyone who wants to spit out a simple string handle 5+ different use cases, and you'd better test for them, because the compiler won't complain until it's used! I think toString should be first and foremost SIMPLE. It already was -- return a string. But that forces people to allocate, and we want to avoid that. Using a sink is pretty much just as simple. BTW, just to be clear, I applaud fixing druntime to remove unnecessary GC allocations, and agree that with proper design most of the allocations can go away. It's just that sink and output ranges are both designed to solve the same problem in pretty much the same way. The difference appears to be little more than tomayto tomahto. It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. -Steve
Re: Programming Language for Games, part 3
On 11/3/14 12:12 PM, bearophile wrote: Andrei Alexandrescu: Then don't mention it in the first place. You either make points you can stand by on don't. Don't fumble around. -- Andrei There's also a third option, offer the information I have, if it's valuable, even when it's not complete because others can get interested and find the full information themselves (note: this is how science works in laboratories). That's fine so long as it comes with clear disclosure. -- Andrei
Re: bug in assigning to dynamic array element
On Monday, 3 November 2014 at 00:16:48 UTC, ketmar via Digitalmars-d wrote: error-prone code. no, this is not another task for lint. not rejecting such code is safe in the terms of program will not segfault, but it's obviously not safe in terms of correct code. Yes, this is a common complaint. Without solid semantic analysis it would probably be better to only have dynamic vectors as a library type with fat slices that are locked to the underlying array. That's what everybody expects from a dynamic array type anyway. …it is a reaaallyyy good idea to support what most people's assumptions about dynamic arrays… D would gain more from relaxing memory safe language constructs and focus more on supporting programming constructs by semantic analysis. This is an area where the C++ crowd will be gridlocked to their backwards compatible mindset. But they are getting increasingly more powerful sanitizers…
Re: toString refactor in druntime
Walter Bright newshou...@digitalmars.com wrote: [snip] Have you ever looked at the C openssl.lib? The .h files with it are loaded with metaprogramming done with C macros. Yet I've never heard anyone complain about it. Those macros are a very common common complaint in my experience. C .h files for DLLs are typically stuffed with C macros. [snip] The defense presents openssl as Exhibit A! Presenting OpenSSL as a case for good interface design is a crime by itself! Tobi
Re: Programming Language for Games, part 3
On 02/11/2014 20:33, Walter Bright wrote: On 11/2/2014 12:12 PM, bearophile wrote: I think the free mixing of signed and unsigned integral values is not a good idea in D. It's simply not workable to put a wall between them. Every proposal for it has entailed various unfortunate, ugly, and arbitrary consequences. We need warnings like gcc has: -Wsign-compare Warn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned. -Wconversion Warn for implicit conversions that may alter a value. This includes ... conversions between signed and unsigned, like unsigned ui = -1 ... Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion. It is really unfortunate that D is more bug-prone than gcc in this case. There was some promising work here: https://github.com/D-Programming-Language/dmd/pull/1913
Fwd: char16_t and char32_t
I wonder if posting this message to this list is more appropriate than to d.learn? -- Forwarded message -- In the following pages (which have differing file naming patterns for whatever reason!): http://dlang.org/interfaceToC.html http://dlang.org/cpp_interface I would suggest to add the info that wchar is compatible with the char16_t and dchar with char32_t of C11. See: http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29#Changes_from_C99 Currently wchar and dchar are marked as being compatible with wchar_t depending on the sizeof(wchar_t). That's true, but I guess char{16,32}_t provide a stable mapping. -- Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा
Fwd: Interfacing with C++
It was recommended that I discuss this on this list rather than d.learn... (I didn't think I'd graduate out of d.learn *that* quickly...) -- Forwarded message -- Hello. I really really need to be able to interface well with a C++ library which contains lots of classes if I am going to further invest time into D. Now from the http://dlang.org/cpp_interface I find out the current status of built-in C++ interfacing support. I'm working on Linux so using the COM support is not an option for me (whatever COM may be!). A few queries: 1) How mature is the SWIG support for wrapping a library into D? Specifically does the above SWIG support take advantage of the built-in C++ support features like connecting directly to virtual functions? 2) Is there any further work underway to implement support for static and non-virtual class member functions? Or is this not at all possible? If so, why? 3) The page speaks about having to integrate an entire C++ compiler into the D compiler. Could the usage of libclang help here in having to avoid writing a new C++ compiler module or am I talking through my (non-existent) hat? -- Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा
Re: Programming Language for Games, part 3
On Mon, Nov 3, 2014 at 3:42 PM, bearophile via Digitalmars-d digitalmars-d@puremagic.com wrote: There's also a third option, offer the information I have, if it's valuable, even when it's not complete because others can get interested and find the full information themselves That's true. But when making points to high-level decision makers like Andrei, it is often more productive to do the research oneself and present the result and not just chime in with pointers because they don't have the time to follow those pointers. (pun intended) -- Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा
Re: `alias newSymbol = existingSymbol` or `alias existingSymbol newSymbol`
Hello people. FWIW, for those who want to alias one symbol to multiple other symbols and saying that only the old syntax helps them, how about allowing alias a = b = c = int? It is merely an extension of the assignment-based new syntax, no? -- Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा
Re: Fwd: Interfacing with C++
Shriramana Sharma via Digitalmars-d wrote in message news:mailman.1464.1415039051.9932.digitalmar...@puremagic.com... Hello. I really really need to be able to interface well with a C++ library which contains lots of classes if I am going to further invest time into D. Now from the http://dlang.org/cpp_interface I find out the current status of built-in C++ interfacing support. I'm working on Linux so using the COM support is not an option for me (whatever COM may be!). That page is out of date. Support has improved significantly since then. A few queries: 1) How mature is the SWIG support for wrapping a library into D? Specifically does the above SWIG support take advantage of the built-in C++ support features like connecting directly to virtual functions? No idea. 2) Is there any further work underway to implement support for static and non-virtual class member functions? Or is this not at all possible? If so, why? Work is complete. IIRC it was in the last release, you might need to grab master/an alpha for very latest stuff. Special member functions (dtor/operators) generally don't work. 3) The page speaks about having to integrate an entire C++ compiler into the D compiler. Could the usage of libclang help here in having to avoid writing a new C++ compiler module or am I talking through my (non-existent) hat? Yes. But adding a second compiler to the compiler is problematic even if you don't have the write the second compiler. You however could make a C++ binding generator with clang (see dstep). Also, note that you can still use some aspects of C++ templates from D - you can pass a templated struct or class between the languages (but you will have to more or less re-write it on the other side). This is done in ddmd (magicport2/newmagic) with root.array. You can also call templated functions with some hacks, if you are careful about ensuring they're instantiated on the C++ side. (ie use pragma(mangle)) So, a lot is possible, but when things go wrong you'll be fighting nasty abi and alignment bugs.
Re: DIP66 v1.1 (Multiple) alias this.
On Monday, 3 November 2014 at 15:39:42 UTC, IgorStepanov wrote: I meant that when you say that X is a subtype of T and X is a subtype of V where you don't know what T and V are, it means you don't really know what you're doing. And that is an error and the compiler should inform you about it as soon as possible. However I may be mistaken. IMO the behaviour should be analogous to name lookup for modules: there should be an error only on use. It's hard to come up with a non-artificial example, but I can imagine there are some valid use cases in generic code. It won't hurt to report the ambiguity error on use, while it could theoretically hurt to report it early, so I'd suggest to go with the former.
Re: Programming Language for Games, part 3
On Saturday, 1 November 2014 at 20:14:15 UTC, Walter Bright wrote: Jonathan is reinventing D with a somewhat different syntax. Some points on the video: May be you should have a couple of beers with him too, just like you did with Andrei a long time ago! :)
Re: Fwd: Interfacing with C++
On Monday, 3 November 2014 at 18:24:12 UTC, Shriramana Sharma via Digitalmars-d wrote: It was recommended that I discuss this on this list rather than d.learn... (I didn't think I'd graduate out of d.learn *that* quickly...) -- Forwarded message -- Hello. I really really need to be able to interface well with a C++ library which contains lots of classes if I am going to further invest time into D. You might find my project Smidgen (https://github.com/alynch4047/smidgen) useful, It's not finished but you might consider extending it rather than starting elsewhere. The build systems works on Linux 64 using cmake so you should be able to get started fairly easily, and there is a sample mini set of C++ classes used for testing which you can look at. It was created to wrap Qt, using the same *.sip file definitions as are used by PyQt. The FEATURE list TODO and DONE list is as follows: FEATURES * All D * Understandable, maintainable code * Wraps protected and virtual methods, allows virtual methods to be overridden in D * Mixin classes in target C++ library supported * Allows custom type conversions between C++ and D types * C++ enums mapped to D enums and are type checked in D * Wraps nested C++ classes * Tested * Based on the sip format. This is well proven and allows simplified maintenance of wrappers for multiple versions of the target library. (All larger target libraries will need some ongoing maintenance of the wrapper regardless of the wrapping technology). PROVISOS * Currently works with wrapped method arguments/return types of X, X* and X but not implemented are X* etc. * Wrapped types which are returned by value must have a copy constructor (could be changed later) * DO NOT capture references to (stack-based) arguments when overriding wrapped virtual methods. They are destroyed by the wrapper when the virtual method ends. * (Qt only) When emitting signals, must use emit! notation, not just call signal. GOTCHAS === * An invalid getClassNameC can cause segfaults when compiling the target application because it is used in template instantiation * If getClassName does not work for a subclass (QMoveEvent) when we are expecting T = the base class (QEvent), and it was created as the base class (QEvent) (because getClassName did not work) then it casts to the sub class (QMOveEvent) on a later lookup (because it is defined on the other method as the return type) and crashes. DONE * Static methods * Default values * Enums * Multiple packages / modules * Nested classes e.g. QMetaObject::Connection * Transfer, TransferThis and TransferBack for arguments * Destructors - and deregister instance from createdInD * Multiple inheritance = multiple pointers * Conversion functions in package_wrapper.cpp should have ability to add #include directives at the top of package_wrapper.cpp * Virtual functions * Protected functions * Sip If clauses for features, platforms TODO * non-primitive Typedefs * Primitive types C - D conversion - *.conf file %CToDType long = long %CToDType unsigned char = ubyte * Sip If clauses for timelines %Timeline {Qt_5_0_0 Qt_5_0_1 Qt_5_0_2} * KeepReference for arguments + tests for Transfer etc. - Easy, in class with KeepRef e.g. View.setModel(model /KeepReference/) it has an extra attribute - void* setModel_SMIKeepRef then in setModel() { View_setModel_SMIX23(model.wrappedObject); setModel_SMIKeepRef = model; } This will make D keep a reference to the model as long as the View instance is alive. Each view will have its own reference so the total can go above 1 for a given model. * getCastPointerForInterface can be easily improved by not switching on a name but instead each class has a separate variable for each base class pointer, that is populated in the constructor - each class has one extra pointer per interface implemented - override virtual void*[] getExtraPointers() { void*[] extraPointers = super.getExtraPointers(); extraPointers ~= wrappedObject_Calculator; return extraPointers; } - in constructor this() { wrappedObject_Calculator = castRectAsCalculator(wrappedObject); } - in destructor ~this() { deregisterWrappedObject(wrappedObject); deregisterWrappedObejct(wrappedObject_Calculator); } * instance_wrapper et al., need to also register base class pointers * getWrappedObject / getClassName - how to handle this in a x-module fashion. * Add support for wrapping members * Add QTest support * int arguments that take a default enum value enum defaults * char** - Use this _idea_ this(string[] args) { // if (m_instance != null) // throw new RuntimeException(QCoreApplication can only be initialized once); argc = cast(int)args.length; argv = toStringzArray(args); this(argc, argv); // m_instance.aboutToQuit.connect(m_instance, disposeOfMyself()); } * Threading? - wrappedObjects[] should be shared as with CPP instance tracker. Use signal.d's WeakRef and InvisibleAddress * qRegisterMetaType?? * Add %UsesConverter to package.sip, so that
Re: Fwd: Interfacing with C++
On Monday, 3 November 2014 at 20:32:34 UTC, Abdulhaq wrote: On Monday, 3 November 2014 at 18:24:12 UTC, Shriramana Sharma via Digitalmars-d wrote: It was recommended that I discuss this on this list rather than d.learn... (I didn't think I'd graduate out of d.learn *that* quickly...) -- Forwarded message -- Hello. I really really need to be able to interface well with a C++ library which contains lots of classes if I am going to further invest time into D. You might find my project Smidgen (https://github.com/alynch4047/smidgen) useful, It's not finished but you might consider extending it rather than starting elsewhere. The build systems works on Linux 64 using cmake so you should be able to get started fairly easily, and there is a sample mini set of C++ classes used for testing which you can look at. It was created to wrap Qt, using the same *.sip file definitions as are used by PyQt. The FEATURE list TODO and DONE list is as follows: BTW one of the reasons that I have not yet completed this project is that I don't have a handle on where the current C++ interfacing work is going and don't want to work on something only to have it made redundant. Also, it has to use a hack to work around the lack of weak references and if the GC is changed to relocate objects then it will break this aspect of the code.
Re: std.experimental.logger formal review round 3
I will remove the trusted later this week
Re: toString refactor in druntime
On Monday, 3 November 2014 at 15:42:57 UTC, Steven Schveighoffer wrote: At the moment, you are stuck with most toString calls allocating on the GC every time they are called. I think the virtual call thing should be a pleasant improvement :) Note that delegates aren't virtual calls, but indirect calls. The former need 2 memory access, the latter none (or 3 vs. 1 if the delegate/object isn't yet in a register).
Re: Fwd: Interfacing with C++
On Monday, 3 November 2014 at 18:24:12 UTC, Shriramana Sharma via Digitalmars-d wrote: 1) How mature is the SWIG support for wrapping a library into D? Specifically does the above SWIG support take advantage of the built-in C++ support features like connecting directly to virtual functions? I investigated this recently. It actually work fairly well, minus 2 things: - swig use 0 terminated sting to pass string back en forth. But in C++, char* can be a string or a buffer, and when it is the later, you can run into problems. - swig generate unnecessary garbage in the binding layer. I tried to work on it, but swig require serious ramp up to contribute to.
Re: Programming Language for Games, part 3
On 11/3/14 10:10 PM, John wrote: On Saturday, 1 November 2014 at 20:14:15 UTC, Walter Bright wrote: Jonathan is reinventing D with a somewhat different syntax. Some points on the video: May be you should have a couple of beers with him too, just like you did with Andrei a long time ago! :) I'm considering writing an open letter responding to all videos, give Jonathan a first crack at reviewing it, and then meeting for beers. -- Andrei
Re: DIP66 v1.1 (Multiple) alias this.
On Monday, 3 November 2014 at 20:06:27 UTC, Marc Schütz wrote: On Monday, 3 November 2014 at 15:39:42 UTC, IgorStepanov wrote: I meant that when you say that X is a subtype of T and X is a subtype of V where you don't know what T and V are, it means you don't really know what you're doing. And that is an error and the compiler should inform you about it as soon as possible. However I may be mistaken. IMO the behaviour should be analogous to name lookup for modules: there should be an error only on use. It's hard to come up with a non-artificial example, but I can imagine there are some valid use cases in generic code. It won't hurt to report the ambiguity error on use, while it could theoretically hurt to report it early, so I'd suggest to go with the former. There are two cases: 1: when alias a this tries to override base class typeof(a) 2: when alias a this tries to override alias b this where is(typeof(a) == typeof(b)) The first check is hard to implement at lookup-time, because base classes are resolved before alias this. The second check may be easely dropped (anyway alias this conflicts are resolved properly at lookup time). Do you accept this scheme (remove the second check but still alive the first check)?
Re: Programming Language for Games, part 3
On Monday, 3 November 2014 at 21:11:07 UTC, Andrei Alexandrescu wrote: and then meeting for beers. -- Andrei Be aware that he doesn't drink (alcohol) too much: https://twitter.com/Jonathan_Blow/status/515268581525700608 Matheus.
Re: toString refactor in druntime
On 11/3/2014 9:36 AM, Tobias Müller wrote: Presenting OpenSSL as a case for good interface design is a crime by itself! Not at all. I presented it as an example of a C library that has a metaprogramming interface, but that interface has not prevented bug fix updates to the shared library itself without requiring recompiling of apps that call it. All shared C libraries have a metaprogramming interface if they have macros in the .h file.
Re: toString refactor in druntime
On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is.
Re: toString refactor in druntime
On 11/3/14 4:37 PM, Walter Bright wrote: On 11/3/2014 9:36 AM, Tobias Müller wrote: Presenting OpenSSL as a case for good interface design is a crime by itself! Not at all. I presented it as an example of a C library that has a metaprogramming interface, but that interface has not prevented bug fix updates to the shared library itself without requiring recompiling of apps that call it. All shared C libraries have a metaprogramming interface if they have macros in the .h file. I had a very nasty experience with using a template-based API. I vowed to avoid it wherever possible. The culprit was std::string -- it changed something internally from one version of libc++ to the next on Linux. So I had to recompile everything, but the whole system I was using was with .so objects. templates do NOT make good API types IMO. -Steve
Re: toString refactor in druntime
On 11/3/14 4:40 PM, Walter Bright wrote: On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is. Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange) void myprint(in char[] s) { } static assert(isOutputRange!(typeof(myprint), char)); No 'put' in sight, except as a substring of isOutputRange. I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR). -Steve
Re: std.experimental.logger formal review round 3
On Monday, 3 November 2014 at 20:41:14 UTC, Robert burner Schadek wrote: I will remove the trusted later this week After few tweaks (to allows @system toString()) in my branch you should be able to just merge it directly to your PR branch if you are ok with proposed changes.
Re: Fwd: char16_t and char32_t
On Monday, 3 November 2014 at 18:24:13 UTC, Shriramana Sharma via Digitalmars-d wrote: In the following pages (which have differing file naming patterns for whatever reason!): http://dlang.org/interfaceToC.html http://dlang.org/cpp_interface I would suggest to add the info that wchar is compatible with the char16_t and dchar with char32_t of C11. See: http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29#Changes_from_C99 Currently wchar and dchar are marked as being compatible with wchar_t depending on the sizeof(wchar_t). That's true, but I guess char{16,32}_t provide a stable mapping. If you believe the D documentation needs updating, you are welcome and encouraged to submit a pull request to https://github.com/D-Programming-Language/dlang.org. Also see http://forum.dlang.org/post/nplvjskmuywijvztm...@forum.dlang.org For info on compiling the dd files. Mike
Re: Programming Language for Games, part 3
On 11/3/2014 12:10 PM, John wrote: On Saturday, 1 November 2014 at 20:14:15 UTC, Walter Bright wrote: Jonathan is reinventing D with a somewhat different syntax. Some points on the video: May be you should have a couple of beers with him too, just like you did with Andrei a long time ago! :) I'd like that. Jonathan is quite a likable fellow, and we've been exchanging some nice emails.
Re: toString refactor in druntime
On Monday, 3 November 2014 at 22:33:25 UTC, Steven Schveighoffer wrote: On 11/3/14 4:40 PM, Walter Bright wrote: On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is. Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange) void myprint(in char[] s) { } static assert(isOutputRange!(typeof(myprint), char)); No 'put' in sight, except as a substring of isOutputRange. I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR). -Steve In many cases templates are good because they provide the a way for the programmer to use a library optimized for their particular application. This is the case for the toString function. An argument can be made that using templates is dangerous because if they are used incorrectly, the number of template instantiates can blow up. But this can always be solved by the programmer by changing all their template calls to use the same template parameters. This allows the template solution to simultaneously support a sink that represents a real function, or a delegate, or whatever the application needs. I understand that people like having a binary library that instantiates it's own functions that have a static interface and I think there's value to that. But most of the value is in dynamic libraries that the compiler cannot optimize. When the compiler can optimize, let it:) I updated my test code to use a templated sink, here the link: http://marler.info/dtostring.d Method 1: ReturnString string toString(); Method 2: SinkDelegate void toString(void delegate(const(char)[]) sink); Method 3: SinkTemplate void toString(T)(T sink) if(isOutputRange!(T,const(char)[])); Method 4: SinkDelegateWithStaticHelperBuffer struct SinkStatic { char[64] buffer; void delegate(const(char)[]) sink; } void toString(ref SinkStatic sink); Method 5: SinkDelegateWithDynamicHelperBuffer struct SinkDynamic { char[] buffer; void delegate(const(char)[]) sink; } void toString(ref SinkDynamic sink); void toString(SinkDynamic sink); (DMD Compiler on x86) dmd dtostring.d RuntimeString run 1 (loopcount 1000) Method 1 : 76 ms Method 2 : 153 ms Method 3 : 146 ms Method 4 : 157 ms Method 5ref : 165 ms Method 5noref: 172 ms StringWithPrefix run 1 (loopcount 100) Method 1 : 149 ms Method 2 : 22 ms Method 3 : 21 ms Method 4 : 80 ms Method 5ref : 81 ms Method 5noref: 82 ms ArrayOfStrings run 1 (loopcount 100) Method 1 : 1 sec Method 2 : 81 ms Method 3 : 77 ms Method 4 : 233 ms Method 5ref : 232 ms Method 5noref: 223 ms (DMD Compiler on x86 with Optimization) dmd -O dtostring.d RuntimeString run 1 (loopcount 1000) Method 1 : 30 ms Method 2 : 65 ms Method 3 : 55 ms Method 4 : 68 ms Method 5ref : 68 ms Method 5noref: 67 ms StringWithPrefix run 1 (loopcount 100) Method 1 : 158 ms Method 2 : 9 ms Method 3 : 8 ms Method 4 : 63 ms Method 5ref : 64 ms Method 5noref: 66 ms ArrayOfStrings run 1 (loopcount 100) Method 1 : 1 sec, 292 ms Method 2 : 35 ms Method 3 : 34 ms Method 4 : 193 ms Method 5ref : 198 ms Method 5noref: 200 ms The results aren't suprising. The template out performs the delegate sink. In a very big project one might try to limit the number of instantiations of toString by using a specific toString instance that accepts some type common OutputRange wrapper which would make the template version perform the same as the sink delegate version, but for projects that don't need to worry about that, you will get better performance from more compiler optimization.
Re: Programming Language for Games, part 3
On 11/3/14 11:27 PM, MattCoder wrote: On Monday, 3 November 2014 at 21:11:07 UTC, Andrei Alexandrescu wrote: and then meeting for beers. -- Andrei Be aware that he doesn't drink (alcohol) too much: https://twitter.com/Jonathan_Blow/status/515268581525700608 Matheus. Thanks. Coffee is even better! -- Andrei
Re: Programming Language for Games, part 3
On 11/3/2014 10:03 AM, Nick Treleaven wrote: On 02/11/2014 20:33, Walter Bright wrote: It's simply not workable to put a wall between them. Every proposal for it has entailed various unfortunate, ugly, and arbitrary consequences. We need warnings like gcc has: -Wsign-compare Warn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned. -Wconversion Warn for implicit conversions that may alter a value. This includes ... conversions between signed and unsigned, like unsigned ui = -1 ... Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion. I find these to suffer from the same problems as all the proposals to fix the issue - they motivate the user to fix them with unfortunate, ugly, and arbitrary consequences. We need to be very careful with the idea of just add a warning. Warnings are a sure sign of wishy-washy language design where the designers cannot make up their mind, so they dump it on the user. One person's warning become another person's must fix, and the language becomes balkanized, which is not good for portability, comprehensibility, and best practices. It is really unfortunate that D is more bug-prone than gcc in this case. I'm afraid that is a matter of opinion. There was some promising work here: https://github.com/D-Programming-Language/dmd/pull/1913
Re: Programming Language for Games, part 3
On Mon, Nov 03, 2014 at 04:29:17PM -0800, Walter Bright via Digitalmars-d wrote: On 11/3/2014 10:03 AM, Nick Treleaven wrote: On 02/11/2014 20:33, Walter Bright wrote: It's simply not workable to put a wall between them. Every proposal for it has entailed various unfortunate, ugly, and arbitrary consequences. We need warnings like gcc has: -Wsign-compare Warn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned. -Wconversion Warn for implicit conversions that may alter a value. This includes ... conversions between signed and unsigned, like unsigned ui = -1 ... Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion. I find these to suffer from the same problems as all the proposals to fix the issue - they motivate the user to fix them with unfortunate, ugly, and arbitrary consequences. We need to be very careful with the idea of just add a warning. Warnings are a sure sign of wishy-washy language design where the designers cannot make up their mind, so they dump it on the user. One person's warning become another person's must fix, and the language becomes balkanized, which is not good for portability, comprehensibility, and best practices. [...] Don't add a warning, just make it outright illegal to assign signed to unsigned and vice versa unless an explicit cast is given. Code that *needs* to assign signed to unsigned *should* be self-documented with a cast indicating a reinterpretation of the bit representation of the value, and code that *unintentionally* mixes signs is buggy and therefore *should* result in a compile error so that the programmer can fix the problem. There are no unfortunate, ugly, or arbitrary consequences here. Much like the recent (or not-so-recent) change of prohibiting implicit conversion of a pointer to bool in an if-condition, or the requirement of a default case in a non-final switch, or so many other improvements in D over C/C++, such a change will (1) make problematic code an error so that it will get fixed, and (2) force users to rewrite non-problematic code to be more self-documenting so that their intent is clearer. Sounds like a win-win situation to me. T -- Bomb technician: If I'm running, try to keep up.
Re: toString refactor in druntime
On 11/3/2014 2:28 PM, Steven Schveighoffer wrote: I had a very nasty experience with using a template-based API. I vowed to avoid it wherever possible. The culprit was std::string -- it changed something internally from one version of libc++ to the next on Linux. So I had to recompile everything, but the whole system I was using was with .so objects. templates do NOT make good API types IMO. It seems this is blaming templates for a different problem. If I have: struct S { int x; }; in my C .h file, and I change it to: struct S { int x,y; }; Then all my API functions that take S as a value argument will require recompilation of any code that uses it. Would you conclude that C sux for making APIs? Of course not. You'd say that a stable API should use reference types, not value types. Having templates or not is irrelevant.
Re: toString refactor in druntime
On 11/3/2014 2:33 PM, Steven Schveighoffer wrote: On 11/3/14 4:40 PM, Walter Bright wrote: On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is. Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange) void myprint(in char[] s) { } static assert(isOutputRange!(typeof(myprint), char)); No 'put' in sight, except as a substring of isOutputRange. I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR). The documentation says, more specifically, that the requirement is that it support put(r,e). The array operands are output ranges NOT because the output ranges need to know about arrays, but because arrays themselves have a put() operation (as defined in std.array). All the algorithm (such as a toString()) needs to do is call put(r,e). It doesn't need to do anything else. It isn't any more complicated than the sink interface.
Re: toString refactor in druntime
On 11/3/14 8:09 PM, Walter Bright wrote: On 11/3/2014 2:28 PM, Steven Schveighoffer wrote: I had a very nasty experience with using a template-based API. I vowed to avoid it wherever possible. The culprit was std::string -- it changed something internally from one version of libc++ to the next on Linux. So I had to recompile everything, but the whole system I was using was with .so objects. templates do NOT make good API types IMO. It seems this is blaming templates for a different problem. If I have: struct S { int x; }; in my C .h file, and I change it to: struct S { int x,y; }; Then all my API functions that take S as a value argument will require recompilation of any code that uses it. Would you conclude that C sux for making APIs? Of course not. You'd say that a stable API should use reference types, not value types. a string is a reference type, the data is on the heap. But that is not the issue. The issue is that it's IMPOSSIBLE for me to ensure std::string remains stable, because it's necessarily completely exposed. There is no encapsulation. Even if I used a pointer to a std::string, the implementation change is going to cause issues. On the contrary, having C-strings as a parameter type has never broken for me. In later projects, I have added simple immutable string type modeled after D, which works so much better :) -Steve
Re: toString refactor in druntime
On 11/3/14 8:16 PM, Walter Bright wrote: On 11/3/2014 2:33 PM, Steven Schveighoffer wrote: On 11/3/14 4:40 PM, Walter Bright wrote: On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is. Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange) void myprint(in char[] s) { } static assert(isOutputRange!(typeof(myprint), char)); No 'put' in sight, except as a substring of isOutputRange. I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR). The documentation says, more specifically, that the requirement is that it support put(r,e). The array operands are output ranges NOT because the output ranges need to know about arrays, but because arrays themselves have a put() operation (as defined in std.array). You can't import std.array from druntime. All the algorithm (such as a toString()) needs to do is call put(r,e). It doesn't need to do anything else. It isn't any more complicated than the sink interface. Again, std.range.put isn't defined in druntime. And neither is isOutputRange. Are you planning on moving these things to druntime? -Steve
Re: bug in assigning to dynamic array element
On Mon, 03 Nov 2014 16:39:43 + via Digitalmars-d digitalmars-d@puremagic.com wrote: On Monday, 3 November 2014 at 00:16:48 UTC, ketmar via Digitalmars-d wrote: error-prone code. no, this is not another task for lint. not rejecting such code is safe in the terms of program will not segfault, but it's obviously not safe in terms of correct code. Yes, this is a common complaint. Without solid semantic analysis it would probably be better to only have dynamic vectors as a library type with fat slices that are locked to the underlying array. That's what everybody expects from a dynamic array type anyway. …it is a reaaallyyy good idea to support what most people's assumptions about dynamic arrays… D would gain more from relaxing memory safe language constructs and focus more on supporting programming constructs by semantic analysis. This is an area where the C++ crowd will be gridlocked to their backwards compatible mindset. But they are getting increasingly more powerful sanitizers… good semantic analysis as a big task, i think we all understand it. as moving dynamic arrays out of core language is the thing that surely won't be approved, the only sane way to safely fix this issue without starting discussion about when .ptr must be loaded is just reject impure assigns to dynamic array elements. sure this will reject some cases where impure assigns are ok, but better be safe that sorry, isn't it? ah, it isn't for D. sure, this decision will break some code. that's why it will never be approved, despite all hype about safety. at least leaving this feature as is should help C++ programmers to adopt D. they used to languages that has nothing common with sanity. ;-) signature.asc Description: PGP signature
Re: toString refactor in druntime
On 11/3/2014 5:47 PM, Steven Schveighoffer wrote: Again, std.range.put isn't defined in druntime. True. And neither is isOutputRange. Wouldn't really be needed. Are you planning on moving these things to druntime? This illustrates a long running issue about what goes in druntime and what in phobos. It's not much of an argument for having a different API that does the same thing, only incompatible.
Re: toString refactor in druntime
On Mon, Nov 03, 2014 at 05:56:56PM -0800, Walter Bright via Digitalmars-d wrote: On 11/3/2014 5:47 PM, Steven Schveighoffer wrote: Again, std.range.put isn't defined in druntime. True. And neither is isOutputRange. Wouldn't really be needed. Are you planning on moving these things to druntime? This illustrates a long running issue about what goes in druntime and what in phobos. [...] Another prime example is std.typecons.Tuple, which blocked the implementation of byPair in AA's. T -- Political correctness: socially-sanctioned hypocrisy.
Re: Programming Language for Games, part 3
On 11/3/2014 4:49 PM, H. S. Teoh via Digitalmars-d wrote: Don't add a warning, just make it outright illegal to assign signed to unsigned and vice versa unless an explicit cast is given. This has been proposed before. There are no unfortunate, ugly, or arbitrary consequences here. Much like the recent (or not-so-recent) change of prohibiting implicit conversion of a pointer to bool in an if-condition, or the requirement of a default case in a non-final switch, or so many other improvements in D over C/C++, such a change will (1) make problematic code an error so that it will get fixed, and (2) force users to rewrite non-problematic code to be more self-documenting so that their intent is clearer. Sounds like a win-win situation to me. Should be careful with analogies like that. Each case is different. Your proposal (which has been proposed many times before) requires, as you say, explicit casting. You are glossing over and dismissing the problems with explicit casts, and the problems with overloading, etc.
Re: bug in assigning to dynamic array element
On Mon, 03 Nov 2014 09:50:26 -0500 Steven Schveighoffer via Digitalmars-d digitalmars-d@puremagic.com wrote: There is a reason we get at least 1 question a week on how D arrays work. and this is a clear sign that something is *very* wrong with them. i fully understand the mechanics behind dynamic arrays, slicing and so on. what i *can't* understand here is why compiler allowing me to shoot my foot even without a warning. compiler *knows* that this is dynamic array. it *knows* that assign is impure (as saveIt() obviously not pure and it can't be). yet it silently allows me do that. it's *very* error-prone code. it's easy for compiler to reject such code (or at least warn me). but it choses to carefully hide the possible bug. i'm nat talking about it must work as i expect! here. what i'm talking about is that D compiler allows potentialy unsafe and error-prone code. it's ok for pointers, i'm walking in dangerous area with pointers, but it's not ok when i using *built-in* *type*! it's like ahahaha, let's see how smart you are! i will not warn you about problematic code (despite i can do that without big problems) and we'll see how fast you'll find that gotcha! it's very funny to read discussions about safety and environment variables here. they were boring before, but now i realised the sarcasm, and they becomes very amusing. signature.asc Description: PGP signature
Re: toString refactor in druntime
On 11/3/14 6:05 PM, Jonathan Marler wrote: On Monday, 3 November 2014 at 22:33:25 UTC, Steven Schveighoffer wrote: On 11/3/14 4:40 PM, Walter Bright wrote: On 11/3/2014 8:09 AM, Steven Schveighoffer wrote: It is a huge difference to say EVERYONE who implements toString will take any templated type that purports to be an output range, vs giving one case to handle. All an output range is is a type with a 'put' method. That's it. You're making it out to be far more complex than it is. Directly from the docs: (http://dlang.org/phobos/std_range.html#isOutputRange) void myprint(in char[] s) { } static assert(isOutputRange!(typeof(myprint), char)); No 'put' in sight, except as a substring of isOutputRange. I don't think you realize what a beast supporting all output ranges is, or using them (hint: calling r.put for a generic output range is an ERROR). -Steve In many cases templates are good because they provide the a way for the programmer to use a library optimized for their particular application. This is the case for the toString function. An argument can be made that using templates is dangerous because if they are used incorrectly, the number of template instantiates can blow up. But this can always be solved by the programmer by changing all their template calls to use the same template parameters. This allows the template solution to simultaneously support a sink that represents a real function, or a delegate, or whatever the application needs. If we make toString a template, we precludes it as a virtual function, and we force the object to expose its inner workings. I think the template solution has advantages, one being the possibility for optimization. But I don't think the gains are significant enough. It's also more complex than necessary. I understand that people like having a binary library that instantiates it's own functions that have a static interface and I think there's value to that. But most of the value is in dynamic libraries that the compiler cannot optimize. When the compiler can optimize, let it:) I updated my test code to use a templated sink, here the link: http://marler.info/dtostring.d Method 1: ReturnString string toString(); Method 2: SinkDelegate void toString(void delegate(const(char)[]) sink); Method 3: SinkTemplate void toString(T)(T sink) if(isOutputRange!(T,const(char)[])); Method 4: SinkDelegateWithStaticHelperBuffer struct SinkStatic { char[64] buffer; void delegate(const(char)[]) sink; } void toString(ref SinkStatic sink); Method 5: SinkDelegateWithDynamicHelperBuffer struct SinkDynamic { char[] buffer; void delegate(const(char)[]) sink; } void toString(ref SinkDynamic sink); void toString(SinkDynamic sink); (DMD Compiler on x86) dmd dtostring.d RuntimeString run 1 (loopcount 1000) Method 1 : 76 ms Method 2 : 153 ms Method 3 : 146 ms Method 4 : 157 ms Method 5ref : 165 ms Method 5noref: 172 ms StringWithPrefix run 1 (loopcount 100) Method 1 : 149 ms Method 2 : 22 ms Method 3 : 21 ms Method 4 : 80 ms Method 5ref : 81 ms Method 5noref: 82 ms ArrayOfStrings run 1 (loopcount 100) Method 1 : 1 sec Method 2 : 81 ms Method 3 : 77 ms Method 4 : 233 ms Method 5ref : 232 ms Method 5noref: 223 ms (DMD Compiler on x86 with Optimization) dmd -O dtostring.d RuntimeString run 1 (loopcount 1000) Method 1 : 30 ms Method 2 : 65 ms Method 3 : 55 ms Method 4 : 68 ms Method 5ref : 68 ms Method 5noref: 67 ms StringWithPrefix run 1 (loopcount 100) Method 1 : 158 ms Method 2 : 9 ms Method 3 : 8 ms Method 4 : 63 ms Method 5ref : 64 ms Method 5noref: 66 ms ArrayOfStrings run 1 (loopcount 100) Method 1 : 1 sec, 292 ms Method 2 : 35 ms Method 3 : 34 ms Method 4 : 193 ms Method 5ref : 198 ms Method 5noref: 200 ms The results aren't suprising. The template out performs the delegate sink. In a very big project one might try to limit the number of instantiations of toString by using a specific toString instance that accepts some type common OutputRange wrapper which would make the template version perform the same as the sink delegate version, but for projects that don't need to worry about that, you will get better performance from more compiler optimization. I think the performance gains are minimal. The only one that is significant is StringWithPrefix, which has a 11% gain. But that's still only 1ms, and 1ms on a PC can be attributed to external forces. I would increase the loop count on that one. Note, if you really want to see gains, use -inline. -Steve
Re: toString refactor in druntime
On Tuesday, 4 November 2014 at 02:49:55 UTC, Steven Schveighoffer wrote: On 11/3/14 6:05 PM, Jonathan Marler wrote: In many cases templates are good because they provide the a way for the programmer to use a library optimized for their particular application. This is the case for the toString function. An argument can be made that using templates is dangerous because if they are used incorrectly, the number of template instantiates can blow up. But this can always be solved by the programmer by changing all their template calls to use the same template parameters. This allows the template solution to simultaneously support a sink that represents a real function, or a delegate, or whatever the application needs. If we make toString a template, we precludes it as a virtual function, and we force the object to expose its inner workings. I think the template solution has advantages, one being the possibility for optimization. But I don't think the gains are significant enough. It's also more complex than necessary. I was thinking you could have the best of both worlds with templates. For example, you could define the toString template like this: void toStringTemplate(T)(T sink) if(isOutputRange!(T,const(char)[])) Then you could declare an alias like this: alias toString = toStringTemplate!(void delegate(const(char)[])); Which (correct me if I'm wrong) I believe is equivalent to the original sink delegate function. This allows programmers to write the logic for toString once and allow a developer using the library to choose whether they want to use the delegate version or the generic output range version. This gives the user of the library the ability to choose the best version for their own application. Note: I added this alias method to my dtostring.d test code and it wasn't as fast as the delegate version. I'm not sure why as I thought the generated code would be identical. If anyone has any insight as to why this happened let me know. code is at http://marler.info/dtostring.d
Re: The cost of write barriers
On Sunday, 2 November 2014 at 08:48:46 UTC, Jonathan Barnard wrote: The upcoming version 1.4 of Go uses write barriers in preparation for the future implementation of a concurrent and generational GC. On the mailing list thread discussing the beta (https://groups.google.com/forum/#!topic/golang-nuts/7VAcfULjiB8), a few people note speed reductions of 30-50% in their benchmarks. I think this vindicates to a degree D's decision to avoid garbage collection strategies that require write barriers. Write barrier are only required on objects that contain mutable pointer and are shared. in D, that is a subset of the shared heap. D's type system would allow to use such strategy while mitigating the cost quite a lot.
Re: toString refactor in druntime
On Tuesday, 4 November 2014 at 04:34:09 UTC, Jonathan Marler wrote: On Tuesday, 4 November 2014 at 02:49:55 UTC, Steven Schveighoffer wrote: On 11/3/14 6:05 PM, Jonathan Marler wrote: In many cases templates are good because they provide the a way for the programmer to use a library optimized for their particular application. This is the case for the toString function. An argument can be made that using templates is dangerous because if they are used incorrectly, the number of template instantiates can blow up. But this can always be solved by the programmer by changing all their template calls to use the same template parameters. This allows the template solution to simultaneously support a sink that represents a real function, or a delegate, or whatever the application needs. If we make toString a template, we precludes it as a virtual function, and we force the object to expose its inner workings. I think the template solution has advantages, one being the possibility for optimization. But I don't think the gains are significant enough. It's also more complex than necessary. I was thinking you could have the best of both worlds with templates. For example, you could define the toString template like this: void toStringTemplate(T)(T sink) if(isOutputRange!(T,const(char)[])) Then you could declare an alias like this: alias toString = toStringTemplate!(void delegate(const(char)[])); Which (correct me if I'm wrong) I believe is equivalent to the original sink delegate function. This allows programmers to write the logic for toString once and allow a developer using the library to choose whether they want to use the delegate version or the generic output range version. This gives the user of the library the ability to choose the best version for their own application. Note: I added this alias method to my dtostring.d test code and it wasn't as fast as the delegate version. I'm not sure why as I thought the generated code would be identical. If anyone has any insight as to why this happened let me know. code is at http://marler.info/dtostring.d I'm sure it's been mentioned before, but you should try ldc/gdc as they have much more capable optimisers.
Re: spawnProcess() not child?
Is there nobody that knows a solution? :(
Re: spawnProcess() not child?
On Sunday, 2 November 2014 at 00:59:43 UTC, Bauss wrote: Is there a way to spawn a process that won't be a child process, because I can't seem to kill any processes created with spawnProcess() It keeps giving me access denied for the processes and it's necessary for me to kill a process, compile it and then spawn it again. Taking a blind guess: Could it be that the process has already exited, and the PID got recycled and assigned to a new process? Then you would try to kill that process instead of your spawned one, which would fail if it doesn't belong to you.
Re: spawnProcess() not child?
The parent / child relationship always exists. In POSIX OSs, you may ignore SIGCHLD signal (announcing child process death), so that in case of child process exit it will not become zombie, rather it will be disposed on the spot. As a side note, in Linux, there exist a system call allowing process re-parenting, but it is intended for use in experimenting, rather than in normal use case. Side note II, there is no real chance of wrapping PID numbers around in a reasonable time frame.
Re: shallow copy of const(Object)[]
On 10/31/14 2:38 PM, anonymous wrote: I have a const(Object)[] and I want a shallow copy of the array. ..dup doesn't do it, which I thought a bug, but according to Martin Nowak it's by design [1]. std.array.array fails, too. Is there really nothing in phobos for this? static import std.array; void main() { const(Object)[] a; version(dup) auto b = a.dup; /* Nope. Apparently, dup is supposed to convert the elements to mutable [1], which doesn't work with const(Object), of course. */ version(array) auto c = std.array.array(a); /* Nope. Tries to convert to mutable, too? */ version(meh) { typeof(a) d; d.reserve(a.length); foreach(e; a) d ~= e; } } [1] https://github.com/D-Programming-Language/druntime/pull/1001#discussion_r19674927 Well, it's a matter of how you look at it when you request dup. Traditionally in D, dup has meant give me a copy with all the elements being mutable. If we were forward thinkers, we would have called this 'mdup'. We don't have a way to say give me a copy and keep all the attributes the same. I think in order to get what you want, we need a new method. I would propose one that is pure, and can be deduced to have the result be unique, and therefore implicitly castable to any constancy. What I like about that is: 1. It works with any change of constancy that would normally be allowed. 2. It works with const - const, which is what we don't currently have (cdup) I think if you change the name (an unfortunate requirement), and then add pure and inout appropriately, we have something that may supplant dup as the main mechanism to copy arrays. I think we need 2 overloads. One that takes a const array and returns a mutable one, when no indirections are in the elements, and one that takes an inout array and returns an inout one for indirections. Both should be pure. -Steve
Question about eponymous template trick
I have an example of code like this: template Node(String) { struct Node {} struct Name {} struct Attr {} } void main() { alias MyNode = Node!(string).Node; alias MyName = Node!(string).Name; alias MyAttr = Node!(string).Attr; } This code fails during compilation with message: Compilation output: /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' So question is: is this intended behaviour and I'm missing something about eponymous templates? Or is it a bug in compiler?
Re: spawnProcess() not child?
On 11/3/14 6:34 AM, angel wrote: The parent / child relationship always exists. In POSIX OSs, you may ignore SIGCHLD signal (announcing child process death), so that in case of child process exit it will not become zombie, rather it will be disposed on the spot. As a side note, in Linux, there exist a system call allowing process re-parenting, but it is intended for use in experimenting, rather than in normal use case. Side note II, there is no real chance of wrapping PID numbers around in a reasonable time frame. From OP's code, he is on Windows. -Steve
Re: Question about eponymous template trick
On Monday, 3 November 2014 at 14:07:55 UTC, Uranuz wrote: I have an example of code like this: template Node(String) { struct Node {} struct Name {} struct Attr {} } void main() { alias MyNode = Node!(string).Node; alias MyName = Node!(string).Name; alias MyAttr = Node!(string).Attr; } This code fails during compilation with message: Compilation output: /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' So question is: is this intended behaviour and I'm missing something about eponymous templates? Or is it a bug in compiler? Looks like compiler looks for Node, Name and Attr in Node struct, because of eponymous thing. This code works though: template N(String) { struct Node {} struct Name {} struct Attr {} } void main() { alias MyNode = N!(string).Node; alias MyName = N!(string).Name; alias MyAttr = N!(string).Attr; }
Re: API hooking in Dlang?
On Monday, 3 November 2014 at 07:46:57 UTC, Jack wrote: On Monday, 3 November 2014 at 06:51:11 UTC, Dirk wrote: On Monday, 3 November 2014 at 04:31:40 UTC, Dirk wrote: On Monday, 3 November 2014 at 03:41:19 UTC, Dirk wrote: I am wondering if there is any libraries I have missed for API hooking? Preferably on windows, and linux, although just windows is fine. I found one named kong(http://www.dsource.org/projects/kong), although it has been abandoned and only supports xp on windows. Or if there is any detours bindings anywhere that would be great. Im a little surprised there isn`t much on Dll Injection/API hooking on Dlang. I figure people must be doing it as it is very common. Could anyone point me in the right direction? I should of mentioned that I have also seen the MadCodeHook Library bindings, which is great but the MCH library is very expensive. I ended up finding an example on github(https://github.com/Trass3r/hooksample), not sure how I missed it. With that said it is alot easier than I thought. I am beginning to love D :). You should find some at code.dlang.org That was actually the first place I checked. The only example was dmadhook which is a wrapper of the MadCodeHook paid library. Thanks for helping though.
accessing numeric template parameters
If I have a struct with numeric template parameter, how can I access it within member functions? Like normal member variables? And how about the constructor? struct polynomial(uint base) { private: uint[] N; public: this(uint x) { base = x; } ... void add(Polynomial!base P) { if(N.length P.N.length) N.length = P.N.length; foreach(i; 0..P.N.length) { N[i] = (N[i]+P.N[i]) % base; } } } This doesn't work for me :-/
Re: API hooking in Dlang?
On Monday, 3 November 2014 at 04:31:40 UTC, Dirk wrote: I should of mentioned that I have also seen the MadCodeHook Library bindings, which is great but the MCH library is very expensive. Weird, it used to be open source and free.
Re: [SDL + TKD] Seg fault from creating DirectoryDialog
On Sunday, 2 November 2014 at 23:05:05 UTC, Jack wrote: On Sunday, 2 November 2014 at 17:39:46 UTC, Gary Willoughby wrote: On Sunday, 2 November 2014 at 12:11:23 UTC, Jack wrote: Whole error is: http://codepad.org/C2l4rUel That's not the true error. That's dub throwing an exception when trying to run the built executable. As shown here: https://github.com/D-Programming-Language/dub/blob/master/source%2Fdub%2Fgenerators%2Fbuild.d#L464 I would suggest building the application without using dub then run the program through a debugger to find the location in the source where it's actually seg-faulting. I personally use this one: http://www.affinic.com/?page_id=109. Thank you. I built the program using the compiler and debugged it with the C::B gui version of gdb, and it spewed out information about call stacks and things that, I confess, I have no idea what the hell it is: http://codepad.org/Bj3y6tqr and it seems to point to line 123 in tcl.d as shown here: http://picpaste.com/pics/Screenshot_from_2014-11-03_06_53_17-C6eIWp7k.1414969454.png And now, as I said before, don't know what this is exactly. Looks like a threading error somewhere. What version of Tcl/Tk are you linking against? Are you using threads in your program? Tcl/Tk can be a pain with threading as i've read. There exists thread-friendly versions as seen here: http://www.tcl.tk/doc/howto/compile.html Notice the --enable-threads switch. I don't really know what to suggest. Try reducing the program down until you've found where the issue stops happening. It may be an incompatibility with SDL?
Re: accessing numeric template parameters
On Monday, 3 November 2014 at 14:27:47 UTC, Dominikus Dittes Scherkl wrote: If I have a struct with numeric template parameter, how can I access it within member functions? Like normal member variables? And how about the constructor? struct polynomial(uint base) { private: uint[] N; public: this(uint x) { base = x; } ... void add(Polynomial!base P) { if(N.length P.N.length) N.length = P.N.length; foreach(i; 0..P.N.length) { N[i] = (N[i]+P.N[i]) % base; } } } This doesn't work for me :-/ You cannot assign to it, because it is only avaliable during compilation. Think of it as an immediate value, not variable.
Re: Question about eponymous template trick
Looks like compiler looks for Node, Name and Attr in Node struct, because of eponymous thing. I understand it but I want to know if it is documented behaviour or not. Could anybody clear what happens with eponymous stuff and why I can't get acces to *other* declarations inside eponymous template? I guess that it is not intended behaviour.
Re: Templates for structures
On 11/02/2014 04:10 AM, novice2 wrote: Hello. I need write some wrapper around legacy data structure. May be it should be class. May be structure with methods. The problem is writing repetitive code for underlying data. For example: - code to read length-byte-prefixed string to D string for every field in every structure; - code to write D string back to length-byte-prefixed string; Is it possible to write some template or mixin, and then just write myStruct.addFiled(type=ByteLengthString, name=name) myStruct.addFiled(type=ShortLengthString, name=filed2) myStruct.addFiled(type=WeirdStoredInteger, name=counter) May be it can be done with template, mixin, UDA, ...? May be something already realized, and i can see sources as example? Any ideas or examples please. Just show direction for me ) Thanx. It sounds possible but I don't understand it yet. Can you give an example of the input and output to the D code? Ali
Re: Question about eponymous template trick
On 11/03/2014 06:36 AM, Uranuz wrote: Looks like compiler looks for Node, Name and Attr in Node struct, because of eponymous thing. I understand it but I want to know if it is documented behaviour or not. Could anybody clear what happens with eponymous stuff and why I can't get acces to *other* declarations inside eponymous template? I guess that it is not intended behaviour. I think it's the intended behavior. I think documentation is outdated. Ali
Re: Question about eponymous template trick
I think it's the intended behavior. I think documentation is outdated. Ali Thanks. So I will modify my programme to workaround this.
Re: Question about eponymous template trick
Also I failed to find any documentation about eponymous stuff in language reference. As far as I remember it was here but now looks like it is missing.
Re: Question about eponymous template trick
On Monday, 3 November 2014 at 14:58:03 UTC, Ali Çehreli wrote: I think it's the intended behavior. I think documentation is outdated. Both forms should really work though. I had always thought that the short form was simply possible if the names matched.
simd and dmd compiler v 2.066 and 2.067.0-b1
Hi. Not sure if my code is correct - I wanted to build the simplest working example of simd use. The following compiles and works under ldc (I have not disassessembled the result to see if it is using simd instructions), but generates a compiler error under dmd (2.066 and 2.067.0-b1 running under Fedora 20). The only message is: Internal error: backend/el.c 2874 Let me know if you think the code is okay, and if so I will see if I can figure out how to generate a bug report (if it's not something already known). Thanks. Laeeth. import std.stdio; import core.simd; void main() { short8 vec; foreach(i;0..8) { vec.ptr[i]=cast(short)i; } vec=3*vec; foreach(i;0..8) { writefln(%s,vec.ptr[i]); } }
Re: API hooking in Dlang?
On Monday, 3 November 2014 at 14:32:05 UTC, Sean Kelly wrote: On Monday, 3 November 2014 at 04:31:40 UTC, Dirk wrote: I should of mentioned that I have also seen the MadCodeHook Library bindings, which is great but the MCH library is very expensive. Weird, it used to be open source and free. Apparently you can still download it, but you need to have a nag scree running in the background. Their reasoning behind making it premium, from what I gather is that it was being used in Malware which was causing AV's to give a false positive for any legitimate applications using the MCH lib.
Re: Question about eponymous template trick
On 11/3/14 9:07 AM, Uranuz wrote: I have an example of code like this: template Node(String) { struct Node {} struct Name {} struct Attr {} } void main() { alias MyNode = Node!(string).Node; alias MyName = Node!(string).Name; alias MyAttr = Node!(string).Attr; } This code fails during compilation with message: Compilation output: /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(12): Error: no property 'Node' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(13): Error: no property 'Name' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' /d228/f410.d(14): Error: no property 'Attr' for type 'Node!string' So question is: is this intended behaviour and I'm missing something about eponymous templates? Or is it a bug in compiler? This is troubling. So you can never access struct Name inside there? This USED to work IIRC, but then again, the eponymous trick only used to work if there was only one member in the template. -Steve
Re: simd and dmd compiler v 2.066 and 2.067.0-b1
On Monday, 3 November 2014 at 15:33:00 UTC, Laeeth Isharc wrote: Hi. Not sure if my code is correct - I wanted to build the simplest working example of simd use. The following compiles and works under ldc (I have not disassessembled the result to see if it is using simd instructions), but generates a compiler error under dmd (2.066 and 2.067.0-b1 running under Fedora 20). The only message is: Internal error: backend/el.c 2874 Let me know if you think the code is okay, and if so I will see if I can figure out how to generate a bug report (if it's not something already known). Thanks. Laeeth. import std.stdio; import core.simd; void main() { short8 vec; foreach(i;0..8) { vec.ptr[i]=cast(short)i; } vec=3*vec; foreach(i;0..8) { writefln(%s,vec.ptr[i]); } } It looks OK to me. Whether or not the code is correct, any internal compiler error or segfault is a bug.
Re: spawnProcess() not child?
On Monday, 3 November 2014 at 14:09:21 UTC, Steven Schveighoffer wrote: From OP's code, he is on Windows. I believe on Windows you have to sort out some kind of permissions to terminate a process. No idea if std.process does this, but it sounds like probably not.
Struct template
struct Internal { int i; double d; string s; } struct External_int { Internal internal; @property Internal* ptr () { return internal; } this (int a) { internal.s = int; internal.i = a; } } struct External (T) { Internal internal; @property Internal* ptr () { return internal; } static if (is(typeof(T) == int)) { this (T a) { internal.s = int; internal.i = a; } } } void main () { auto e1 = External_int(1); // Ok auto e2 = External!int(1); // Nope, cannot implicitly // convert expression (1) // of type int to Internal } Why? And how is this fixed? Thanks.
Re: Struct template
static if (is(typeof(T) == int)) should be static if (is(T == int)) T is already a type. Ahh. Thanks!
Re: Struct template
On Monday, 3 November 2014 at 17:03:33 UTC, deed wrote: struct Internal { int i; double d; string s; } struct External_int { Internal internal; @property Internal* ptr () { return internal; } this (int a) { internal.s = int; internal.i = a; } } struct External (T) { Internal internal; @property Internal* ptr () { return internal; } static if (is(typeof(T) == int)) { this (T a) { internal.s = int; internal.i = a; } } } void main () { auto e1 = External_int(1); // Ok auto e2 = External!int(1); // Nope, cannot implicitly // convert expression (1) // of type int to Internal } Why? And how is this fixed? Thanks. static if (is(typeof(T) == int)) should be static if (is(T == int)) T is already a type.
Reading unicode string with readf (%s)
Hi! The following code does not correctly handle Unicode strings. - import std.stdio; void main () { string s; readf (%s, s); write (s); } - Example input (Test. in cyrillic): - Тест. - (hex: D0 A2 D0 B5 D1 81 D1 82 2E 0D 0A) Example output: - ТеÑÑ. - (hex: C3 90 C2 A2 C3 90 C2 B5 C3 91 C2 81 C3 91 C2 82 2E 0D 0A) Here, the input bytes are handled separately: D0 - C3 90, A2 - C2 A2, etc. On the bright side, reading the file with readln works properly. Is this an expected shortcoming of %s-reading a string? Could it be made to work somehow? Is it worth a bug report? Ivan Kazmenko.
Re: Embedding D Shared Library in WSGI Web Server
On Tuesday, 28 October 2014 at 09:34:33 UTC, Chris wrote: On Tuesday, 28 October 2014 at 00:16:03 UTC, John McFarlane wrote: Hi, I've written a modest shared library in D that I'd like to call directly from a Python web server (Linux/OS X, Apache, WSGI, Pyramid). I can call it reliably from within Python unit tests but on a running server, the library causes a SIGSEGV as soon as I try anything as complicated as a writeln call. Under Linux, I've tried using Pyd, CFFI and ctypes to bind the native .so to Python with the same result. I've tried calling Runtime.initialize();from an init function on server startup and from the D function being called as part of the web request. I've even tried writing a shim in C to make these calls and call through to the D. I've compiled with DMD and GDC with a variety of switches. Currently my build command looks like: dmd ./d/*.d -version=library -release -shared -O -inline -defaultlib=libphobos2.so -fPIC -oflibgusteau.so The extern(C) function takes a string and returns a string. I've tried holding onto a pointer to the returned string and passing in an adequately sized byte array from Python. Smaller strings seem to cause a crash with lower probability but typically the input and output strings are a few KB in size and consistently crash. I taken measures to ensure that they are correctly encoded and null terminated. I've also tried disabling the GC, calling terminate on function exit (after copying result into received buffer) and various other measures in an attempt to get something working. I'm guessing that the web server spawns/relies on a thread or process for each request and I've read that runtime initialization should be invoked from the main thread. Does this always mean the first thread that was created on process start up or does it just have to be consistent? If calling from a thread other than the one used to initialize, is that a problem? Are other threads created when GC is invoked which might last past the extern function being called and if so, can I prevent this by controlling collection explicitly? Thanks, John I had a similar problem with a DLL for Python. The reason my DLL would crash were some writeln statements. After removing them it worked fine. I suppose the writeln messes things up, be it because of threads or because of conflicts in the file system (remember writeln is a file system operation). I suggest you have your lib not print things to console, but use a different mechanism instead, e.g. pass a string back to Python and have Python do the printing (if needs be). You could also try to set your lib up as a small socket server that waits for input and answers. That usually works for me. Thanks for the suggestion. I looked into removing all of my writeln calls and found the I still had the same problem. Simply a call to to!string with the input char* is enough to cause a crash. I will go with the socket server as a last resort but it would be much easier (especially from a testing POV) if I could call the native D code directly from the web server.
Re: Reading unicode string with readf (%s)
On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: readf (%s, s); Worth noting: this reads to end-of-file (not end-of-line or whitespace), and reading the whole file into a string was what I indeed expected it to do. So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too.
Re: Reading unicode string with readf (%s)
On 11/03/2014 11:47 AM, Ivan Kazmenko wrote: On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: readf (%s, s); Worth noting: this reads to end-of-file (not end-of-line or whitespace), and reading the whole file into a string was what I indeed expected it to do. So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. I don't know the answer to the Unicode issue with readf but you can read the file by chunks: import std.stdio; import std.array; import std.exception; string readAll(File file) { char[666] buffer; char[] contents; char[] piece; do { piece = file.rawRead(buffer); contents ~= piece; } while (!piece.empty); return assumeUnique(contents); } void main () { string s = stdin.readAll(); write (s); } Ali
Re: Reading unicode string with readf (%s)
On Monday, 3 November 2014 at 19:47:17 UTC, Ivan Kazmenko wrote: So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. Maybe something like this: import std.stdio; import std.array; import std.conv; string text = stdin .byLine(KeepTerminator.yes) .join() .to!(string);
Re: Why ByChunk is not regnize by st.range.takeOne and why Section has no value
On Monday, 3 November 2014 at 06:43:50 UTC, Ali Çehreli wrote: On 11/02/2014 04:58 PM, bioinfornatics wrote: Dear, Some problem to build this code: http://fpaste.org/147327/75948141/ $ ldc2 fasta_test.d /usr/include/d/std/range.d(3605): Error: template std.array.save cannot deduce function from argument types !()(ByChunk), candidates are: I think that is due to the too permissive template constraint of takeOne in phobos/std/range.d. Even though it say isInputRange!R, it clearly needs isForwardRange!R because it calls .save() on that range: @property auto save() { return Result(_source.save, empty); } So, the following is wrong: auto takeOne(R)(R source) if (isInputRange!R) It should be: auto takeOne(R)(R source) if (isForwardRange!R) If you modify range.d locally to require ForwardRange, you will see that your following call will get an error message because byChunk is not a ForwardRange: // Take a piece of byte from current file ubyte[] buffer = takeOne(inputRange); I think this issue is already reported as a part of the following bug: https://issues.dlang.org/show_bug.cgi?id=9724 Ali Ok but I do not see why to use save method for a takeOne function is possible to write this function without to use it
Re: accessing numeric template parameters
On Mon, Nov 3, 2014 at 3:27 PM, Dominikus Dittes Scherkl via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: If I have a struct with numeric template parameter, how can I access it within member functions? Like normal member variables? And how about the constructor? struct polynomial(uint base) { private: uint[] N; public: this(uint x) { base = x; } base is part of the type. polynomial is just a 'recipe' for a type, the real struct would be Polynomial!(0), Polynomial!(1), etc. Note that Polynomial!0, Polynomial!1, ... are all different types. Being part of the type means it's defined only at compile-time, you cannot use a runtime value (like 'x') to initialize it. Note that with your current code, `base' is not visible outside Polynomial. You can alias it to a field to make it visible: struct Polynomial(uint base) { alias b = base; // b is visible outside (but set at compile-time !) ... } You can create one like this: Polynomial!2 poly; poly.N = [0,1,0,0,1,1]; assert(poly.b == 2); Of course, you cannot change b: `poly.b = 3;' is forbidden.
Re: simd and dmd compiler v 2.066 and 2.067.0-b1
Reduced testcase: import core.simd; void main() { short8 vec; vec=vec*3; } I've filed a bug report: https://issues.dlang.org/show_bug.cgi?id=13674
Re: Why ByChunk is not regnize by st.range.takeOne and why Section has no value
On Monday, November 03, 2014 21:03:51 bioinfornatics via Digitalmars-d-learn wrote: Ok but I do not see why to use save method for a takeOne function is possible to write this function without to use it It looks like the idea was that beacause you know that there's only one element, you can make it random-access range with opSlice and popBack and the whole shebang. And that works great if the range is at least a forward range, but it currently falls apart with an input range, because while you can easily emulate stuff like back and opIndex by forwarding it to front, save can't be emulated so easily. So, either front needs to be accessed and saved in the Result struct rather than than simply having it contain the range that it's forwarding to, or it needs to have another branch of the static if for handling input ranges separately. Though to be honest, I'm not sure that using takeOne makes a lot of sense over take in that case. You don't really get a performance boost, and since you can't add on the random-access range capabilities without making it eager and saving the result of front (which is an iffy thing to do with some input ranges), it's really not adding anything over plain take. I'd honestly favor just fixing takeOne's template constraint so that it checked for forward ranges. The only reason that I see to make takeOne work with input ranges is simply so that no one will be surprised when it doesn't work with an input range. But that's not really adding any useful functionality as far as I can tell. Though maybe there's something that I'm missing. - Jonathan M Davis
Re: Why ByChunk is not regnize by st.range.takeOne and why Section has no value
On Monday, 3 November 2014 at 21:03:51 UTC, bioinfornatics wrote: On Monday, 3 November 2014 at 06:43:50 UTC, Ali Çehreli wrote: On 11/02/2014 04:58 PM, bioinfornatics wrote: Dear, Some problem to build this code: http://fpaste.org/147327/75948141/ $ ldc2 fasta_test.d /usr/include/d/std/range.d(3605): Error: template std.array.save cannot deduce function from argument types !()(ByChunk), candidates are: I think that is due to the too permissive template constraint of takeOne in phobos/std/range.d. Even though it say isInputRange!R, it clearly needs isForwardRange!R because it calls .save() on that range: @property auto save() { return Result(_source.save, empty); } So, the following is wrong: auto takeOne(R)(R source) if (isInputRange!R) It should be: auto takeOne(R)(R source) if (isForwardRange!R) If you modify range.d locally to require ForwardRange, you will see that your following call will get an error message because byChunk is not a ForwardRange: // Take a piece of byte from current file ubyte[] buffer = takeOne(inputRange); I think this issue is already reported as a part of the following bug: https://issues.dlang.org/show_bug.cgi?id=9724 Ali Ok but I do not see why to use save method for a takeOne function is possible to write this function without to use it Example: auto takeOne(R)(ref R source) if (isInputRange!R) { static if (hasSlicing!R) { return source[0 .. !source.empty]; } else { typeof(R.front) r; if(!source.empty){ r = source.front; source.popFront(); } return r; } }