Re: Safety, undefined behavior, @safe, @trusted
Yigal Chripun wrote: In .Net land, MS uses .net to implement parts of their OS so no surprise there that those OS APIs are available to .net code. Really? What parts? There are a bajillion APIs that you can use from .NET that aren't written in .NET. Microsoft just made it easier to use native code from .NET than Java does.
Re: importing modules with non-identifier names
yigal chripun wrote: This tight mapping is also a problem when you want to rearange physical structure without affecting the API - e.g. a module had grown to be too big and you want to split it into multiple files. std.algorithm is a prime example of such way too big module. What about public imports? Tango does this. The old import will contain a pragma(msg) telling you what you should import instead, and maybe some aliases in case some functions or types changed names as well.
Re: Shared Hell
Kagamin wrote: Christopher Wright Wrote: A function that accesses shared data has to put in fences. There's no way to have the same code deal with shared and unshared code. Acquiring a lock on a non-shared instance is safe, just an unnecessary expense. I would have looked into optimizing this expense away rather than punting the problem to the programmer. Shared code can put data into *really* shared environment, which must not happen for unshared data. Okay, but the compiler can try copying the method, removing the 'shared' storage class, and running semantic on the result. If that succeeds, you're guaranteed not to be doing anything that would be unsafe unless you're casting, and you can call the shared method on a local instance. This lets you avoid whole program analysis and blacklisting unsafe operations. In this case, the compiler can also point to the line of code that prevents the method from being marked not shared.
Re: What Does Haskell Have to Do with C++?
Don wrote: Andrei Alexandrescu wrote: Don wrote: Jeremie Pelletier wrote: http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-with-c/ Bartosz's second part of 'Template Metaprogramming Made Easy (Huh?)', its quite a read :) Yes, it is excellent. Two comments: (1) Bartosz's D examples make me seriously question 'static foreach' which is scheduled for implementation (bugzilla 3377). If implemented, it will be a source of frustration, since it will not be very usable inside templates. The ability to exit from a 'static foreach' is something which is possible with a 'return'-style syntax, but is not possible with the 'eponymous template hack'. I think breaking early out of a static foreach is not necessary (but indeed convenient) for writing good loops. (2) It seems pretty clear that we need to allow the eponymous trick to continue to work when more than one template member is present. I think everyone who's ever attempted template metaprogramming in D has proposed it! Yes, that was on the list for a long time. Bartosz even has participated to many related discussions. I'm surprised the article made it seem an unescapable matter of principles, when it clearly is a trivially fixable bug in the language definition. Yes, looking at the compiler source, it doesn't look too difficult. The fact that something like this works: template foo(int X) { static if (bar!(X)) { const int foo = 57; } else { const char [] foo = abc; } } makes it pretty clear that the difficult part has already been done. I don't know what happens with template mixins, though. I hate template mixins (and I'm not convinced they're useful for anything, either). My mock object library http://dsource.org/projects/dmocks/ uses: mixin(method!(name, returnType, arguments...)); The implementation is a long and ugly string mixin. There's a bug that prevents you from implementing interface methods with aliases. If this were removed, I could replace the long and ugly string mixin with a very short string mixin and a short template mixin. Due to problems with .stringof, my current system usually fails for methods with templated arguments or return types (eg void filter(HashSet!(int) integers). Now that I think of it, I could probably make things better by using a forwarding function.
Re: Shared Hell
Denis Koroskin wrote: I've recently updated to DMD2.035 (from DMD2.031 because all the later versions had issues with imports) and for the first time faced problems with shared modifier. I don't need shared and all my globals are __gshared (they are globally unique instances that don't need per-thread copies). Yet some of methods of the class hierarchy (a root singleton class and everything which is accessible through it) are synchronized (well, you know why). That's where the problems begin. Marking a method as synchronized automatically makes it shared (more or less obvious). And marking the method shared makes it unable to invoke with non-shared instance (and __gshared != shared), meaning that I'm unable to use my __gshared variables anymore, making this attribute useless for any serious safe programming. So I started with replacing __gshared with shared and quickly understood how viral it is. Not only you mast mark all the members shared (methods and field), instantiate classes with shared attribute, you also have to create a duplicate all the methods to make them accessible with both shared and non-shared (thread-local) instances: Why can't you use a non-shared method on a shared object? The compiler could insert locking on the caller side. Why can't you use a shared method on a non-shared object? The compiler could, as an optimization, duplicate the method, minus the synchronization. Or it could leave in the locking, which is expensive but correct.
Re: Shared Hell
Walter Bright wrote: Denis Koroskin wrote: I've recently updated to DMD2.035 (from DMD2.031 because all the later versions had issues with imports) and for the first time faced problems with shared modifier. I don't need shared and all my globals are __gshared (they are globally unique instances that don't need per-thread copies). I don't understand. Are you running multiple threads? Are those threads accessing globals? A function that accesses shared data has to put in fences. There's no way to have the same code deal with shared and unshared code. Acquiring a lock on a non-shared instance is safe, just an unnecessary expense. I would have looked into optimizing this expense away rather than punting the problem to the programmer. As an escape from the type system, you can always cast away the shared-ness. But I wonder about code that both uses global variables shared across threads that don't need synchronization? Maybe the methods are mostly inherently threadsafe. Only a small portion requires locking, so it's more efficient to handle it manually.
Re: Disallow catch without parameter (LastCatch)
Denis Koroskin wrote: On Wed, 28 Oct 2009 00:21:47 +0300, grauzone n...@example.net wrote: BCS wrote: Hello grauzone, PS: I wonder, should the runtime really execute finally blocks if an Error exception is thrown? (Errors are for runtime errors, Exception for normal exceptions.) Isn't it dangerous to execute arbitrary user code in presence of what is basically an internal error? If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place? You still can use a catch (Throwable t) to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?). I've seen code that has throws new OutOfMemoryException(__FILE__, __LINE__); when malloc (or other allocation mechanism) has failed, and it always make me smile. Maybe the GC should reserve a small amount of space (~1KB) for its exceptions, when memory is tight.
Re: Disallow catch without parameter (LastCatch)
Denis Koroskin wrote: OutOfMemory exception is supposed to be thrown with a call to onOutOfMemoryError(), that throws OutOfMemoryError.classinfo.init (i.e. global immutable instance of an Error). That's clever. I like it.
Re: Disallow catch without parameter (LastCatch)
grauzone wrote: Christopher Wright wrote: Please keep full attributions. PS: I wonder, should the runtime really execute finally blocks if an Error exception is thrown? (Errors are for runtime errors, Exception for normal exceptions.) Isn't it dangerous to execute arbitrary user code in presence of what is basically an internal error? Are all Errors unrecoverable except by immediately aborting the application? What about logging? What about putting up a reasonable error message for the user? What about restarting the failed module in case the issue was temporary and environmental? Something is wrong with your program internally if something like this happens. You can't expect a consistent program state. And most of the code in finally blocks was not written for such situations. You'll probably end up throwing another runtime error from within a finally block. Quite possibly. But immediately terminating the process is simply not acceptable. How am I going to fix this problem if I can't even log that a problem occurred? If I have a SaaS application, I have to rely on my users to email or call up to find out something bad happened? What if it's an assertion error or a bounds error in a plugin? I can unload that plugin and continue on with no issues. I'm getting OutOfMemoryErrors? I'll disable caching and prefetching and reduce my memory footprint by 80%. Problem solved. There is one category of errors that is not recoverable. If the runtime is left in an inconsistent state, it should try to output an error message and terminate. Everything else, an application could potentially handle.
Re: Disallow catch without parameter (LastCatch)
grauzone wrote: Right now, you can catch every exception with try { something; } catch { somethingelse; }. Can we get rid of this abomination before D2 is finalized? I claim that it's completely useless, and even more so, every single use of this is a bug. If you really want to catch everything, you might as well write catch (Exception o), or catch (Throwable o) for those who know what they're doing. PS: I wonder, should the runtime really execute finally blocks if an Error exception is thrown? (Errors are for runtime errors, Exception for normal exceptions.) Isn't it dangerous to execute arbitrary user code in presence of what is basically an internal error? Are all Errors unrecoverable except by immediately aborting the application? What about logging? What about putting up a reasonable error message for the user? What about restarting the failed module in case the issue was temporary and environmental?
Re: parallelFuture
Andrei Alexandrescu wrote: dsimcha wrote: Again, code: http://dsource.org/projects/scrapple/browser/trunk/parallelFuture/parallelFuture.d Docs: http://cis.jhu.edu/~dsimcha/parallelFuture.html What license is the library under? Andrei Boost. I suppose you didn't want to look at the source in case the license wasn't sufficiently liberal, but it's easy enough to scan through the module's doc comments for a license block, without reading the source code.
Re: OT: Hats... Mostly unnecessary?
It had a button.
Re: OT: Hats... Mostly unnecessary?
Bob Jones wrote: I dont know about you but I have severe diffculty comprehending what people are trying to say if they have a hat upon their head. It jars my brain. I find berets particulary disturbing FWIW. I had a hat, once.
Re: Semicolons: mostly unnecessary?
AJ wrote: Walter Bright newshou...@digitalmars.com wrote in message news:hbo88h$1q...@digitalmars.com... AJ wrote: Walter, do you write at all? If so, why not take a breather and write an article about this, given that you have direct experience in addition to opinion on the topic? :) I write an awful lot - blogs, documentation, articles, presentations, etc. The ; debate, though, is a very old and tired one, and makes me tired just thinking about it :-) So many much more interesting things to write about. Bottom line: yes, there is a case both ways. Nobody will be convinced to change sides. Both can be made to work. There's nothing new to say about it. How about just a list of pros and cons for each? Or even, just the esoteric things that you as an implementer may already know that the layman doesn't? If you're trying to catch C/C++ coders, you need semicolons. If they're optional in some circumstances, that will lead to recommendations that you always include them in case the code changes to require them. This only leaves the possibility of removing semicolons entirely. This would mandate newlines as separators instead. Then you'd need a different character to negate newlines. The C/C++ crowd would leave at this point, since that's just silly. (Though less typing.)
Re: LRU cache for ~=
Brad Roberts wrote: On Mon, 19 Oct 2009, Walter Bright wrote: Denis Koroskin wrote: Safe as in SafeD (i.e. no memory corruption) :) Right. The problems with other definitions of safe is they are too ill-defined. There's SafeD, which has a fairly formal definition. But a fairly generic name, which confuses people repeatedly. I'm not the first to recommend that the name be changed. It does more harm than good.
Re: Revamping associative arrays
Moritz Warning wrote: On Sat, 17 Oct 2009 18:58:08 +, BCS wrote: what will this do? foreach(key; aa.keys) if(Test(key)) aa.remove(key); It's undefined behavior. You shouldn't try to mutate the aa while iterating. I hope that will be fixed. It took me some time to find this out. That's really annoying, and it's true of most (all?) C# base class library collections. When coding in C#, I often find myself doing: var remove = new HashedSetFoo(); foreach (var foo in foos) if (Test(foo)) remove.Add(foo); foos.RemoveAll(remove); It's more allocation than necessary, but more than that, it's an unnecessarily complicated way of interacting with the collection.
Re: Revamping associative arrays
Piotrek wrote: bearophile Wrote: I'd really like the default iteration on an AA to yield its keys, instead of values as currently done. Because if I have a key I can find its value, while the opposite is not possible, so having keys is much more useful. This is true in Python too. In my dlibs all iterables and functions behave like this. The current D design is just a design mistake ad Walter was wrong on this. No! No! No! Maybe you are wrong. Or it's a metter of taste. I remember that I spent many hours on finding bug in python's script written by me in my job. The reason was the python's behaviour decribed by you. Then I couldn't understand why the hell iterating on collection returns a key in the first place. It's so not intuitive. Your explanation is not even close in convincing me. If I wanted keys I would write: foreach (key, value; set) or (key; set.keys) Why not mandate using both keys and values? That should eliminate ambiguity. Essentially, an associative array would be a Tuple!(Tkey, Tvalue)[] with some extra accessors.
Re: dmd support for IDEs and the D tool chain
Jacob Carlborg wrote: On 10/17/09 00:23, Christopher Wright wrote: Jacob Carlborg wrote: On 10/16/09 12:58, Tomas Lindquist Olsen wrote: GtkD supports Glade. Yes, but GtkD doesn't use native controls. A minor point, I think. Eclipse doesn't look very native and has widespread acceptance. It depends on what you're looking at. The SWT philosophy is something like this: Use controls that are available as native controls on as many platforms as possible. For example, if a control is available as native on 3 out of 4 platforms, use the native on the 3 platforms and emulate it on the fourth. If a control is only native on 1 out of 4 platforms don't include it in SWT. SWT also has some custom (non-native) controls like the tabs used by Eclipse. And the tabs are everywhere, and no attempt was made to make them look native to any platform.
Re: Communicating between in and out contracts
Rainer Deyke wrote: Rainer Deyke wrote: Andrei Alexandrescu wrote: I honestly believe the whole old thing can't be made to work. Shall we move on to other possibilities instead of expending every effort on making this bear dance? It definitely /can/ be made to work, for some value of work. It sacrifices the natural order of evaluation to gain a concise and intuitive syntax. I don't think it should be dismissed out of hand. Also, from the Eiffel docs (http://archive.eiffel.com/doc/online/eiffel50/intro/language/invitation-07.html): The notation 'old expression' is only valid in a routine postcondition. It denotes the value the expression had on routine entry. It seems that Eiffel had 'old' semantics that I've proposed all along. Any significant problems with this approach would have been discovered by the Eiffel community by now. It requires duplicating the object. If the object is mutable, this requires duplicating it and recursively duplicating everything it references. If the object is immutable, this is free.
Re: Working with files over 2GB in D2
language_fan wrote: Sat, 17 Oct 2009 10:58:15 +0200, Frank Benoit thusly wrote: In Tango search for __USE_LARGEFILE64 to find the relevant places. Not only other functions are used, also types and structures are different. I think there was some talk about merging Tango and Phobos, but now since Tango has been abandoned (no D2 port is planned it seems), would it make sense to rewrite those parts of Tango that are missing in Phobos, and license them using a more liberal practical license? Abandoned?! Nobody has abandoned Tango. Tango hasn't been ported to D2 because it's too much of a moving target.
Re: 64-bit
Lutger wrote: Currently: LDC is a mature compiler that does linux 64 bit well, but is not available for D2, the 'alpha' branch of the language and also doesn't work on windows. LDC works on Windows, except for exception handling. Which is probably a deal breaker for most people.
Re: dmd support for IDEs and the D tool chain
Jacob Carlborg wrote: On 10/16/09 12:58, Tomas Lindquist Olsen wrote: GtkD supports Glade. Yes, but GtkD doesn't use native controls. A minor point, I think. Eclipse doesn't look very native and has widespread acceptance.
Re: dmd support for IDEs
BCS wrote: template Foo (T) { T map(T[]) { ... } } class Bar { mixin Foo!(int); } void main() { Bar bar; bar. /// will the IDE have to do anything special to see 'map' or will it just be listed as another function? } Probably it would just work. On the other hand, if you had this: T manipulate(T)(T value) { ... } MyObject foo; manipulate(foo). // IDE dies here The compiler wouldn't have completion on the line of code you're currently editing, since it's a syntax error. The IDE won't know anything about D and so can't determine what the return type of manipulate() is.
Re: dmd support for IDEs
language_fan wrote: Now every time I see a gtk+/swt/dwt application I wonder where the heck that unintuitive terrible piece of cr*p came: http://book.javanb.com/swt-the-standard-widget-toolkit/images/0321256638/ graphics/14fig03.gif 2002, maybe?
Re: dmd support for IDEs
Jeremie Pelletier wrote: Walter Bright wrote: But if you want to contribute, how about a JSON parser for phobos? You'll need one anyway for your IDE. BTW, JSON parsing comes for free with javascript. Why not incorporate dmdscript into your IDE as its extension language? The official JSON website has tons of bindings, here's the C one: http://fara.cs.uni-potsdam.de/~jsg/json_parser/ I'm gonna try and get it converted to D over the weekend. Tango already has a good JSON parser, but I imagine its license (BSD) doesn't meet Walter's requirements.
Re: Phobos.testing
Andrei Alexandrescu wrote: Sorry. I occasionally scan the bug reports and work on the Phobos-related ones, but I missed yours. I just assigned to myself four bugs you submitted. Phobos should probably use trac tickets. It would make it easier to range query phobos bugs.
Re: dmd support for IDEs
Walter Bright wrote: In my discussions with companies about adopting D, the major barrier that comes up over and over isn't Tango vs Phobos, dmd being GPL, debugger support, libraries, bugs, etc., although those are important. It's the IDE. They say that the productivity gains of D's improvements are overbalanced by the loss of productivity by moving away from an IDE. And what is it about an IDE that is so productive? Intellisense (Microsoft's word for autocompletion). So, while I'm not going to be writing an IDE, I figure that dmd can help. dmd already puts out .doc and .di files. How about putting out an xml file giving all the information needed for an IDE to implement autocompletion? There'd be one .xml file generated per .d source file. The nice thing about an xml file is while D is relatively easy to parse, xml is trivial. Furthermore, an xml format would be fairly robust in the face of changes to D syntax. What do you think? The huge things are: - code navigation (go to definition / find usages) - reformatting - refactoring - autocompletion Code navigation alone is a huge help, and with reliable autocompletion would be sufficient for me to switch from vim. What you are suggesting would make both of those easier, though the IDE might need to duplicate D's symbol lookup. I'm not sure whether what you are talking about will help at all with reformatting or refactoring, and I really have no idea what would be required for this.
Re: dmd support for IDEs
Andrei Alexandrescu wrote: Nick Sabalausky wrote: Walter Bright newshou...@digitalmars.com wrote in message news:has92u$1vu...@digitalmars.com... Lutger wrote: What about file/line/column of the symbol? Is this much work / hard work to add? file/line of course, but I don't see a point to column. So the IDE knows where it is and can actually do things with it, instead of just knowing Well, it's somewhere around here-ish. And what should the tab size be? :o) Let's see, how many characters are in a tab character?
Re: Array literals' default type
Don wrote: Christopher Wright wrote: Don wrote: I don't understand why runtime-determined array literals even exist. They're not literals!!! They cause no end of trouble. IMHO we'd be *much* better off without them. You don't see the use. I do. I would go on a murderous rampage if that feature were removed from the language. For example, one thing I recently wrote involved creating a process with a large number of arguments. The invocation looked like: exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3, arg4] ~ moreGeneratedArgs); There were about ten or fifteen lines like that. You'd suggest I rewrite that how? char[][] args; args ~= procName; args ~= arg1; args ~= arg2; args ~= generatedArgs; args ~= arg3; Of course not. These runtime 'array literals' are just syntax sugar for a constructor call. Really, they are nothing more. I'm quite surprised that there is a runtime function for this. I would expect codegen to emit something like: array = __d_newarray(nBytes) array[0] = exp0 array[1] = exp1 ... At worst, it would be something like: exec(description, createArray(procName, arg1, arg2) ~ generatedArgs ~ createArray(arg3, arg4) ~ moreGeneratedArgs); PHP does this. I haven't used PHP enough to hate it. Depending on what the 'exec' signature is, it could be simpler than that. But that's the absolute worst case. The language pays a heavy price for that little bit of syntax sugar. The price being occasional heap allocation where it's unnecessary? The compiler should be able to detect this in many cases and allocate on the stack instead. Your createArray() suggestion doesn't have that advantage. Or parsing difficulties? It's not an insanely difficult thing to parse, and people writing parsers for D comprise an extremely small segment of your audience. Or just having another construct to know? Except in PHP, you can't use arrays without knowing about the array() function, and in D, you can't easily use arrays without knowing about array literals. So it's the same mental load. You could say array() is more self-documenting, but that's only when you want someone who has no clue what D is to read your code. I think it's reasonable to require people to know what an array literal is. What is the price?
Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]
Yigal Chripun wrote: On 10/10/2009 00:36, Christopher Wright wrote: Yigal Chripun wrote: On 09/10/2009 00:38, Christopher Wright wrote: It makes macros highly compiler-specific, or requires the compiler's AST to be part of the language. Nemerle took the nuclear option, and its macros are all-powerful. That's a reasonable way of doing things. I'd be happy with a more restricted system that's easier to standardize, especially if it got rid of all the hacky string manipulation in current D metaprogramming. (Seriously, even __traits returns string arrays for a lot of stuff. It's ridiculous.) It doesn't have to be compiler specific. all is needed is a standardized API to the compiler. Right. It adds something huge that's normally compiler-specific to the language. This makes me uncomfortable. It greatly increases the difficulty of implementation. I disagree - a properly designed compiler will have such an API anyway. Look at how Clang is designed - it's a modular compiler where each part has its own library. you can combine its libs in different ways to provide different options: a full command-line compiler, semantic analysis for IDE, incremental builder for an IDE, etc.. that design obviously requires APIs for the different components. What's so hackish about that? Reread. Current D metaprogramming is hackish. Nemerle's isn't. I was referring to what Don said that providing a hook into the compiler is hackish. many large modular systems do exactly that: eclipse, firefox, even the OS itself. Unix provides syscalls which *are* an API to the OS. a properly designed API doesn't have to expose internal implementation details. btw, in Nemerle they have syntax to compose/decompose AST specifically so they don't need to expose the internal structure of the AST. So they have a separate object model for the syntax tree that macros can affect. This is what I would recommend for D. What do you mean by object model? they have a synax to manipulate AST: [ some code ] would be parsed by the compiler as the AST of some code and would be represented internally by the compiler specific AST representation. I looked up nemerle macros after this. There are a couple parts. 1. AST Mixins It's a lot like string mixins with builtin string formatting and automatic conversion of arguments to their string form. Syntactic sugar on top of this. That's all that macros are. Yes, you can manipulate the AST, but at this stage, it's entirely opaque. 2. Compiler plugins You can define a compiler module that does arbitrary things to the AST. Many modules will make use of macros. The Nemerle compiler might attempt to conflate plugins with macros, but if there were an alternate implementation of Nemerle, the difference would become very apparent very quickly. AST mixins are sexy. Compiler plugins are also sexy[1], but targeted toward a much different audience. D could benefit from both, but the latter is far lower on the list than a decent compile-time reflection system. And of this, only compiler plugins have the issues that I mentioned earlier. [1] Unless you're Richard Stallman. Onoz, someone could use a proprietary plugin with GCC!
Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]
Yigal Chripun wrote: On 09/10/2009 00:38, Christopher Wright wrote: It makes macros highly compiler-specific, or requires the compiler's AST to be part of the language. Nemerle took the nuclear option, and its macros are all-powerful. That's a reasonable way of doing things. I'd be happy with a more restricted system that's easier to standardize, especially if it got rid of all the hacky string manipulation in current D metaprogramming. (Seriously, even __traits returns string arrays for a lot of stuff. It's ridiculous.) It doesn't have to be compiler specific. all is needed is a standardized API to the compiler. Right. It adds something huge that's normally compiler-specific to the language. This makes me uncomfortable. It greatly increases the difficulty of implementation. What's so hackish about that? Reread. Current D metaprogramming is hackish. Nemerle's isn't. many large modular systems do exactly that: eclipse, firefox, even the OS itself. Unix provides syscalls which *are* an API to the OS. a properly designed API doesn't have to expose internal implementation details. btw, in Nemerle they have syntax to compose/decompose AST specifically so they don't need to expose the internal structure of the AST. So they have a separate object model for the syntax tree that macros can affect. This is what I would recommend for D.
Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]
Bill Baxter wrote: It seems macros are implemented as compiler extensions. You compile your macros into DLLs first, that then get loaded into the compiler as plugins. On the plus side, doing things that way you really do have access to any API you need at compile-time, using the same syntax as run-time. All of .NET can be used at compile-time in your macros. No more can't CTFE that gotchas. But it does raise security concerns. I wonder if they have some way to prevent macros from running malicious code. I guess you better run your web-based compiler service in a tightly partitioned VM. C# has security levels. If you run the Nemerle compiler in low trust mode, fewer bad things can happen. Overall it seems pretty nifty to me, really. Giving macros access to an actual compiler API seems less hackish than throwing in a smattering of diverse functionality under the heading of __traits. And less prone to gotchas than trying to create a separate compile-time D interpreter that runs inside the D compiler. What do you see as the down sides? Just that some rogue macro might mess up the AST? It makes macros highly compiler-specific, or requires the compiler's AST to be part of the language. Nemerle took the nuclear option, and its macros are all-powerful. That's a reasonable way of doing things. I'd be happy with a more restricted system that's easier to standardize, especially if it got rid of all the hacky string manipulation in current D metaprogramming. (Seriously, even __traits returns string arrays for a lot of stuff. It's ridiculous.)
Re: Getting constructor's metadata
Max Samukha wrote: Is it possible to get types or aliases of all constructors of a class in D2? No. __traits has some random functionality in this regard. It has a command getVirtualFunctions which only returns virtual overloads. By virtual, we mean appears in vtbl. So any non-private, non-static overload will show up. Constructors do not appear in any object vtbl. It would be kind of odd if they did. There's a patch to add getOverloads to __traits. It would do what you want. But I doubt it works on DMD 2.020.
Re: How initialize a static rectangular array (2-d matrix)
Justin Johansson wrote: Jarrett Billingsley Wrote: On Thu, Oct 8, 2009 at 8:10 PM, Justin Johansson n...@spam.com wrote: I almost have to apologize for this question but .. How does one initialize a static rectangular array (2-d matrix) in D1? None of the following or other variations that I've tried compile with DMD 1.0. int[2, 3] matrix = [ 1, 2, 3, 4, 5, 6 ]; ..that's not how you declare a rectangular array type. It's int[3][2]. int[3][2] matrix = [[1, 2, 3], [4, 5, 6]]; Thanks Jarrett. Am I having a blonde day? int[2,3] m = [ 1, 2, 3 ]; writefln( m=%s, .sizeof=%d, m, m.sizeof); Compiles and prints: m=[1,2,3], .sizeof=12 So what does that declaration, int[2,3], mean? Think this is what threw me initially. Thanks, Justin 2,3 is a comma expression. Evaluate everything, and return the rightmost value.
Re: [Issue 3377] [tdpl] static foreach should be implemented
d-bugm...@puremagic.com wrote: http://d.puremagic.com/issues/show_bug.cgi?id=3377 downs default_357-l...@yahoo.de changed: What|Removed |Added CC||default_357-l...@yahoo.de --- Comment #1 from downs default_357-l...@yahoo.de 2009-10-08 12:35:53 PDT --- This does compile (on 1.0): template Repeat(T, int I) { static if (!I) alias Tuple!() Repeat; else alias Tuple!(T, Repeat!(T, I - 1)) Repeat; } downs, you are a genius. You can create code that is both elegant and dreadful. You make the world a more interesting place.
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu wrote: Christopher Wright wrote: What exactly is your suggestion? It seems that you mean that: delete obj; should call a destructor but not call delete() or notify the GC that the memory is free. That is correct. In particular, an object remains usable after delete. You're saying that there is a problem, but you're not telling us what's wrong. Why the hell do you want to destroy an object without recycling its memory? Why does the inability to do so cause a problem? The matter has been discussed quite a bit around here and in other places. I'm not having as much time as I'd want to explain things. In short, destroying without freeing memory avoids dangling references and preserves memory safety without impacting on other resources. Memory safety, sure, but you're deleting the object. It is no longer valid. You need to add a flag to the object indicating it's invalid, and everything that uses it needs to check that flag. Instead of a probable segfault in the current system, you'll get strange errors. It sounds like a complicated way of supporting a rare use case. Why not use a library solution? Make an IDisposable interface with methods void dispose() and bool disposed()? If you don't have enough time to explain the reasoning, could you post a link to a more detailed explanation?
Re: Get template and its instantiation parameters
BCS wrote: Hello Michal, If one has a template instance, is it possible to get template name and parameter type that was used for instantiating, at compile time? consider: class List (T) {} List!(int) lst; Foo (lst); I want to create such template Foo which prints: List!(int) List int You could try parsing T.stringof at compiletime to extract the parts you need. No, you can't. You can try parsing demangle!(T.mangleof) at compiletime to extract the parts you need. stringof is a morass of inconsistency and partial information. Whenever a template gets within a mile of a type, all bets are off.
Re: Eliminate class allocators and deallocators?
What exactly is your suggestion? It seems that you mean that: delete obj; should call a destructor but not call delete() or notify the GC that the memory is free. You're saying that there is a problem, but you're not telling us what's wrong. Why the hell do you want to destroy an object without recycling its memory? Why does the inability to do so cause a problem? It seems like a performance hack to me -- you've got an object that isn't valid anymore, but you want to hang on to the memory for some other purpose. And you could override new() and delete(), but you don't want to incur the performance penalty of calling the runtime to fetch the deallocator. The only remaining use that I see is a way to reset a shared object without explicitly passing around a reference to the new version of the object. This seems potentially dangerous, and nothing I want for default behavior.
Re: Google C++ style guide
Jeremie Pelletier wrote: Me neither, in fact I would *love* to see a -nrtti switch in DMD to disable the generation of all ClassInfo and TypeInfo instances, along with a version identifier, maybe version = RTTI_Disabled; to let code handle it. I use RTTI a lot for simple debugging like printing the name of a class or type in generic code or meta programming, but not at all in production code. Most of the time I can rely on .stringof and a message pragma to do the same. You use RTTI for dynamic casts, variadic functions, and the default implementation of toString. You could safely eliminate some fields from ClassInfo and TypeInfo, but you can't get rid of them entirely. The best you can do is make TypeInfo entirely opaque (no fields) and only include the base class, interfaces, and name for ClassInfo.
Re: What does Coverity/clang static analysis actually do?
Nick Sabalausky wrote: static void Main(string[] args) { Foo f; if(args.Count() 2) { f = new Foo(); } if(args.Count() 2) { f.bar(); // ERROR: Use of unassgned local variable 'f' } Foo f2; createFoo(ref f2); // ERROR: Use of unassgned local variable 'f2' f2.bar(); } static void createFoo(ref Foo f) { f = new Foo(); } - The first one is rather strange coding though and makes it easy to hide errors anyway. And the second one's a tad odd too, plus I don't see any harm in solving that with Foo f2=null: it would at least be a hell of a lot better than the compiler doing that very same =null automatically. I know Walter doesn't agree, but I'd much rather have a few slightly inconvinient false positives (or would it really be a false negative?) than even a mere possibility for a hidden error. The second one is an error; createFoo might use its argument before assigning. You should have marked its argument as out instead, which would not yield an error. In point of fact, that's a common pattern in C#. Dictionaries define a method bool TryGetValue(key, out value): DateTime date; if (dict.TryGetValue(key, out date)) { // use date }
Re: Defining some stuff for each class in turn
Andrei Alexandrescu wrote: Christopher Wright wrote: Andrei Alexandrescu wrote: I am becoming increasingly aware that we need to provide some means to define certain members (data and functions) for each class as if they were pasted there. Most of the examples given would be well served by decent builtin reflection. Walter thinks reflection is too expensive to be active by default. Find a cheaper way to provide runtime reflection. It's not as sexy as using templates, but it's DRY and easier to use. Slower, but you don't pay the cost of reflection multiple times if you have multiple libraries requiring reflection. What cheaper way would be than allowing a base class to prescribe reflection for its hierarchy? Where do templates even enter the mix? What's slower and why? Why do reflection as a language feature (increases base language size, buggy, rigid) instead of allowing it as a library if we so can? I'm totally against that. Andrei Once you get two or three libraries using reflection, it's cheaper to have the language provide it than to have separate, incompatible reflection systems. It doesn't matter whether the language provides reflection or the standard library. (The only way for me to tell is whether I'm importing from core or from std.) Either way, it should be standardized and easy to opt in or out (depending on the default), and there should be no way or no cost for opting in twice. You have to use templates to get reflection info, currently. Unless CTFE has gotten a lot better, in which case it's effectively the same as using templates, but with a bit less executable bloat. Template-based solutions can be faster than reflection-based solutions because you can access fields and methods directly. But runtime reflection doesn't disallow templates.
Re: What does Coverity/clang static analysis actually do?
BCS wrote: Hello Walter, Consider the Bible. It's long and complicated, and by careful examination of it you can find a verse here and there to justify *any* behavior. This is true of any long document if you are willing to string together enough quotes and ignore enough of it. I'd bet you could get the Declaration of Intendance out of Playboy if you wanted to. What is this Declaration of Intendance you speak of? As for ignoring context...well, I'm willing to discuss this, but not here.
Re: Defining some stuff for each class in turn
Andrei Alexandrescu wrote: I am becoming increasingly aware that we need to provide some means to define certain members (data and functions) for each class as if they were pasted there. Most of the examples given would be well served by decent builtin reflection. Walter thinks reflection is too expensive to be active by default. Find a cheaper way to provide runtime reflection. It's not as sexy as using templates, but it's DRY and easier to use. Slower, but you don't pay the cost of reflection multiple times if you have multiple libraries requiring reflection.
Re: Null references redux + Cyclone
bearophile wrote: Jeremie Pelletier: Again, that's a lazy view on programming. High level constructs are useful to isolate small and simple algorithms which are implemented at low level. Software is inherently multi-scale. Probably in 90-95% of the code of a program micro-optimizations aren't that necessary because those operations are done only once in a while. But then it often happens that certain loops are done an enormous amount of times, so even small inefficiencies inside them lead to low performance. That's why profiling helps. This can be seen by how HotSpot (and modern dynamic language JITters work): usually virtual calls like you can find in a D program are quick, they don't slow down code. Yet if a dynamic call prevents the compile to perform a critical inlining or such dynamic call is left in the middle of a critical code, it may lead to a slower program. That's why I have Java code go 10-30% faster than D code compiled with LDC, not because of the GC and memory allocations, but just because LDC isn't smart enough to inline certain virtual methods. Certainly agreed on virtual calls: on my machine, I timed a simple example as executing 65 interface calls per microsecond, 85 virtual calls per microsecond, and 210 non-member function calls per microsecond. So you should almost never worry about the cost of interface calls since they're so cheap, but they are 3.5 times slower than non-member functions. In most cases, the body of a method is a lot more expensive than the method call, so even when optimizing, it won't often benefit you to use free functions rather than class or interface methods.
Re: Null references redux
Walter Bright wrote: Andrei Alexandrescu wrote: Walter Bright wrote: Even forcing an explicit initializer doesn't actually solve the problem - my experience with such features is programmers simply insert any old value to get the code to pass the compiler, even programmers who know it's a bad idea do it anyway. I think you're starting to be wrong at the point where you don't realize that many bugs come from references that people have forgotten to initialize. Once you acknowledge those, you will start to realize that a reference that must compulsively be initialized is valuable. The problem is it's worse to force people to provide an initializer. You aren't forcing them. They decide for themselves. They determine whether it's appropriate for a particular variable to be null. You can achieve the same goal through contracts. However, this is much more verbose -- enough so that you'll only add these contracts when hunting down a bug. And if you have an array of things It isn't a theoretical problem with providing bad initializers just to shut the compiler up. I have seen it in the wild every time some manager required that code compile without warnings and the compiler warned about no initializer. C# requires that every variable be initialized before use. You know how often I get such an error? Maybe once for every 100 hours of coding. It's mainly for cases where I expect an integer to be initialized to 0 and it's not. You know how often I provide a bad initializer to shut the compiler up? Never. This is partially because C#'s compiler has good flow analysis. It's mostly because: - I declare variables where I use them, not beforehand. - I often declare variables via IDE commands -- I write the code to fetch or calculate a value and assign it to a variable that doesn't exist, and the IDE fills in the type and declares it in the correct place. - I usually don't have more than four or five local variables in a function (often no more than one or two). Out of 300KLOC, there are a few dozen functions that break this rule. DMDFE functions are often long, complex, and have many local variables. I see how this would conflict with your coding style. You would have to add a few question marks for each function, and then you'd be done. DMDFE is ~60KLOC, but you could probably switch it over to this type system without structural changes to any function in a couple days.
Re: Null references redux
Jeremie Pelletier wrote: There again, I favor stronger initialization semantics over nonnull types. This will get rid of most of these errors Only for local variables. Not for fields. Most segfaults I have take me at most a few minutes to pinpoint. Its finding backdoors to compiler enforcements thats annoying. You're complaining now because you'd try to cram 'null' down the throat of something marked 'not-null' and fear it would be difficult?
Re: Null references redux
Andrei Alexandrescu wrote: Walter Bright wrote: Justin Johansson wrote: Walter, in the heat of this thread I hope you haven't missed the correlation with discussion on Dispatching on a variant and noting: Thanks for pointing it out. The facilities in D enable one to construct a non-nullable type, and they are appropriate for many designs. No. There is no means to disable default construction. I looked into this slightly. You'd have to do mark non-nullable fields as requiring ctor initialization, prevent reallocating arrays of non-nullables, and a few other things. At the time I wasn't considering struct constructors; without them, you'd have to forbid structs that contain non-nullable fields, but with them, it's okay. I just don't see them as a replacement for *all* reference types. Non-nullable references should be the default. Andrei
Re: Null references redux
Michel Fortin wrote: On 2009-09-26 22:07:00 -0400, Walter Bright newshou...@digitalmars.com said: [...] The facilities in D enable one to construct a non-nullable type, and they are appropriate for many designs. I just don't see them as a replacement for *all* reference types. As far as I understand this thread, no one here is arguing that non-nullable references/pointers should replace *all* reference/pointer types. The argument made is that non-nullable should be the default and nullable can be specified explicitly any time you need it. So if you need a reference you use Object as the type, and if you want that reference to be nullable you write Object?. The static analysis can then assert that your code properly check for null prior dereferencing a nullable type and issues a compilation error if not. I dislike these forced checks. Let's say you're dealing with a compiler frontend. You have a semantic node that just went through some semantic pass and is guaranteed, by flow control and contracts, to have a certain property initialized that was not initialized prior to that point. The programmer knows the value isn't null. The compiler shouldn't force checks. At most, it should have automated checks that disappear with -release. Also, it introduces more nesting. Also, unless the compiler's flow analysis is great, it's a nuisance -- you can see that the error is bogus and have to insert extra checks. It should be fine to provide a requireNotNull template and leave it at that.
Re: putting more smarts into a == b
Jarrett Billingsley wrote: On Sat, Sep 26, 2009 at 9:32 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Consider two objects a and b with a of class type. Currently, the expression a == b is blindly rewritten as a.opEquals(b). I argue it should be rewritten into a call to an (imaginary/inlined) function equalObjects(a, b), with the following definition: bool equalObjects(T, U)(T a, U b) if (is(T == class)) { static if (is(U == class)) { if (b is null) return a is null; if (a is null) return b is null; } else { enforce(a !is null); } return a.opEquals(b); } This hoists the identity test outside the opEquals call and also deals with null references. What do you think? I'm almost sure that C# does this already, and it's a useful behavior. C# operator overloads are of the form: public static ReturnType operator+(Arg1 arg1, Arg2 arg2) {} Object.operator== is defined to call arg1.Equals(arg2) if arg1 isn't null. But this isn't a feature of operator overloads. Of course, with nonnull types, the check for null wouldn't even need to exst ;) How clever and insightful of you!
Re: Dispatching on a variant
Justin Johansson wrote: I've had a good poke around the forums and couldn't find anything on this so ... What's the recommended method for dispatching code off the runtime type of a variant variable (Phobos D2 std.variant)? Does one use a bunch of if ( var.peek!(type1)) { ... } else if ( var.peek!(type2) { ... } for all N possible types, or is there a better faster way with a switch or jump table of sorts? Variant should have an accessible typeinfo property. (When I say should, I mean that it would be appropriate for it to have it. I am not saying that I believe it has it.) It should be faster to compare that (or switch on typeinfo.name) than to peek for each type.
Re: Null references redux
Walter Bright wrote: Denis Koroskin wrote: If an object may or may not have a valid value, you mark it as nullable. All the difference is that it's a non-default behavior, that's it. And a user is now warned, that an object may be not initialized. He isn't warned, that's just the problem. The null object happily says I succeeded for all input and returns more default values and null objects. This is not the proposal. The proposal was to codify in the type system whether a particular object has null as a valid value. If a variable that cannot be null is not initialized to a non-null value before use, that is an error. It's entirely equivalent to using the current type system with a ton of manual contracts requiring that variables not be null. Except the contracts are enforced at compile time, not runtime. A similar concept would be range-bounded integer types, or floating point types that cannot be NaN or infinity.
Re: Null references redux
Jeremie Pelletier wrote: What if using 'Object obj;' raises a warning unitialized variable and makes everyone wanting non-null references happy, and 'Object obj = null;' raises no warning and makes everyone wanting to keep the current system (all two of us!) happy. I believe it's a fair compromise. It's a large improvement, but only for local variables. If your segfault has to do with a local variable, unless your function is monstrously large, it should be easy to fix, without changing the type system. The larger use case is when you have an aggregate member that cannot be null. This can be solved via contracts, but they are tedious to write and ubiquitous.
Re: Pure dynamic casts?
Jeremie Pelletier wrote: language_fan wrote: Wed, 23 Sep 2009 10:43:53 -0400, Jeremie Pelletier thusly wrote: You're right about concurrency being a different concept than threading, but I wouldn't give threading away for a pure concurrent model either. I believe D is aiming at giving programmers a choice of the tools they wish to use. I could see uses of both a concurrent model with message passing and a threading model with shared data used at once in a program. The danger in too large a flexibility is that concurrency is not easy and it is getting incresingly complex. You need to be extraordinary good at manually managing all concurrent use of data. If I may predict something that is going to happen, it is that there will be high level models that avoid many low level pitfalls. These models will not provide 100% efficiency, but they are getting faster and faster, without compromizing the safety aspect. This already happened with memory allocation (manual vs garbage collection - in common applications, but not in special cases). Before that we gave some of the error detection capabilities to the compiler (e.g. we do not write array bounds checks ourselves anymore). And optimizations (e.g. register allocation). You may disagree, but I find it much more pleasant to find that the application does never crash even though it works 15% slower than an optimal C++ code would. 15% slower is an extreme performance hit. I agree that code safety is useful and I use this model all the time for initialization and other code which isn't real time, but 15% takes away a lot of the application's responsiveness, if you have 50 such applications running on your system you just spent $1000 more in hardware to get the performance of entry level hardware with faster code. What are most applications these days? MS Office, a web browser, maybe an email client, some odds and ends, and a whole bunch of web sites running on servers somewhere (with associated database servers and some other odds and ends). How much does it cost to get a slightly better machine? Fully hosted? Maybe $100/month. How much does it cost to develop it in a faster but more error-prone language? Maybe months more time to market, time you're not making money but are still paying developers. Those developers will need to be more skilled than the ones using a safer language, and thus will cost you more. New features will take more time to develop. It's a competitive advantage to use a slower, safer language on the web. Desktop applications are not quite so straightforward. If you wrote a real time renderer for example with that 15% hit, you get a very noticeable difference in framerate. Not to mention standard GUIs to be laggy on slower machines (just MSN messenger runs to a crawl on my old computer, yet it can run the first UT which does way more operations per second, because there's no performance hit by safer code bloat). Games are not interesting in this regard. They require performance, and they're hideously expensive. A studio can throw developers at the problems and make them go away. Not all games are like this, of course. But most are.
Re: Does dmd have SSE intrinsics?
Andrei Alexandrescu wrote: Yah, but inside do something interesting you need to do special casing anyway. Andrei Sure, but if you're writing a generic library you can punt the problem to the user, who may or may not care about the return value at all. As is, it's a cost you pay whether you care or not.
Re: Does dmd have SSE intrinsics?
Robert Jacques wrote: Yes, although classes have hidden vars, which are runtime dependent, changing the offset. Structs may be embedded in other things (therefore offset). And then there's the whole slicing from an array issue. Um, no. Field accesses for class variables are (pointer + offset). Successive subclasses append their fields to the object, so if you sliced an object and changed its vtbl pointer, you could get a valid instance of its superclass. If the class layout weren't determined at compile time, field accesses would be as slow as virtual function calls.
Re: Pure dynamic casts?
Jeremie Pelletier wrote: You can clearly see all there is to a dynamic cast is simply adjusting the pointer to the object's virtual table. So a compiler knowing the source and destination offset of the vtable can easily inline the code for such a cast. That may be correct, but you're describing it in a way that confuses me, probably in part because it assumes a fair bit of knowledge on the part of the listener. Objects are laid out like this: class vtbl pointer object.Object fields superclass fields superclass interface1 vtbl pointer superclass interface2 vtbl pointer ... class fields class interface1 vtbl pointer class interface2 vtbl pointer ... (The relative order of fields and interface vtbl pointers doesn't matter.) You need a special vtbl for interfaces because a virtual function call works like: branch (object.vtbl + offset) The offset must be known at compile time. And it has to be the same offset for all possible objects implementing this interface. One implemented interface might require an entirely different vtbl layout than another. The solution is to use an entirely different vtbl.
Re: Does dmd have SSE intrinsics?
Robert Jacques wrote: On Tue, 22 Sep 2009 07:09:09 -0400, bearophile bearophileh...@lycos.com wrote: Robert Jacques: [snip] Also, another issue for game/graphic/robotic programmers is the ability to return fixed length arrays from functions. Though struct wrappers mitigates this. Why doesn't D allow to return fixed-sized arrays from functions? It's a basic feature that I can find useful in many situations, it looks more useful than most of the last features implemented in D2. Bye, bearophile Well, fixed length arrays are an implicit/explicit pointer to some (stack/heap) allocated memory. So returning a fixed length array usually means returning a pointer to now invalid stack memory. Allowing fixed-length arrays to be returned by value would be nice, but basically means the compiler is wrapping the array in a struct, which is easy enough to do yourself. Using wrappers also avoids the breaking the logical semantics of arrays (i.e. pass by reference). You could ease the restriction by disallowing implicit conversion from static to dynamic arrays in certain situations. A function returning a dynamic array cannot return a static array; you cannot assign the return value of a function returning a static array to a dynamic array. Or in those cases, put the static array on the heap.
Re: Does dmd have SSE intrinsics?
Jeremie Pelletier wrote: Why would you declare void variables? The point of declaring typed variables is to know what kind of storage to use, void means no storage at all. The only time I use void in variable types is for void* and void[] (which really is just a void* with a length). In fact, every single scope has an infinity of void variables, you just don't need to explicitly declare them :) 'void foo;' is the same semantically as ''. It simplifies generic code a fair bit. Let's say you want to intercept a method call transparently -- maybe wrap it in a database transaction, for instance. I do similar things in dmocks. Anyway, you need to store the return value. You could write: ReturnType!(func) func(ParameterTupleOf!(func) params) { auto result = innerObj.func(params); // do something interesting return result; } Except then you get the error: voids have no value So instead you need to do some amount of special casing, perhaps quite a lot if you have to do something with the function result.
Re: Mixin a constructor ?
Michel Fortin wrote: On 2009-09-19 21:17:36 -0400, language_fan f...@bar.com.invalid said: Since the constructor has no meaning outside classes, should it be interpreted as a free function if mixed in a non-class context? I really wonder how this could be valid code. Does the grammar even support the 3rd line? Personally, I'd like it very much if functions from template mixins could overload with functions from outside the mixin. It'd allow me to replace string mixins with template mixins in quite a few places. Also if you could implement a function from an interface with a template mixin.
Re: Mixin a constructor ?
Jacob Carlborg wrote: Is it supposed to possible to mixin a constructor? The code below doesn't compile. The error: is main.d(23): Error: constructor main.A.this() does not match parameter types (int) main.d(23): Error: expected 0 arguments, not 1 A template mixin introduces a new scope. This is pretty annoying in some cases. More often, it is convenient. Since the constructor is not in the same scope as the class, it might be causing problems. If you didn't introduce a new scope by default, it'd be easy enough to add it in the template or around the mixin: template MixMeIn() { int imInUrScope; { int imOuttaUrScope; } } Additionally, the difference would be easily detectable, because symbol collision would cause the code to fail to compile. Unless the mixin adds a function overload and you pass the address of the overload set somewhere, and now you're passing the wrong overload...which is an old problem for D, aggravated by D's property syntax, and unlikely to be fixed soon.
Re: Template Metaprogramming Made Easy (Huh?)
language_fan wrote: In fact this is the group which uses something other than the hybrid object-oriented/procedural model. Damn straight! They use a hybrid OO/procedural/functional model. Like D. Or C#. Oh, but Prolog, you may say. And I admit, I've seen it used a couple times by academics. But I've seen similar languages used at my job, and we're not by any means an algorithms shop. I'm actually aware of very few languages that break the mold. There are toy languages like Befunge; there are solver-oriented languages like Prolog and Zimpl; and there are a couple oddities like METAFONT. What languages have you seen that are so innovative and different in paradigm?
Re: Modern Windows GUI visual styles
Tim M wrote: Daniel Keep Wrote: Tim M wrote: Microsoft says to use Application.EnableVisualStyles http://msdn.microsoft.com/en-us/library/system.windows.forms.application.enablevisualstyles.aspx Umm... you do realise that's for .NET, right? Run it through a debugger and you will probably find that both provide an abstraction over the same complicated win32 api functions. Or look at Mono's implementation. Or use Reflector http://www.red-gate.com/products/reflector/ -- it's free.
Re: Simple bolt-on unittest improvement
Justin Johansson wrote: Hope it doesn't sound like I just discovered America but being a D newbie one is keen to play with all the language features. So soon getting round to playing with D's unit test facility with JUnit (Java test unit) experience in mind, found that I wanted all my tests to run even if one or the tests would otherwise fail on some assert. Googled for DUnit as a hunch such beast might exist and sure enough found DUnit for D somewhere after the Delphi hits. http://www.dsource.org/projects/dmocks/wiki/DUnit Sure enough DUnit writeup spoke about need for continuous testing in D as had occurred to me. Then it dawned upon me that there really wasn't any need to go away from D's built-in unit test facility to achieve this and hence no need really for the DUnit approach. The idea is to keep working within D's built in unit test facility; just don't use assert statements in current fashion as if one fails then whole test stops running. Simply replace assert statements with a function call that tests and records the assert condition instead .. much like in JUnit where you have functions like assertTrue, assertEquals etc. Then just inside your main program you call up your unit test pretty print report and decide then (say based upon number of failed tests relative to total number of tests) whether to continue with your mainline code or bail out. The regime now looks something like this: Class1: unittest { jjunit.expectEquals( __FILE__, __LINE__, some_x, some_y); jjunit.expectTrue( __FILE__, __LINE__, somecond); } And you don't want to use dunit's assertions because they throw exceptions, which means you don't see more than one error when running the application. The problem with this is that you are going to continue running a test after an assertion fails. This is fine for a lot of unittests -- in fact beneficial -- but in others it's going to be guaranteed failure: auto foo = buildFoo(); expect(foo !is null); expect(foo.bar == 17); If you really want to work with d's builtin unittests, your strategy is required. Personally, I dislike it. That's why dunit is as it is.
Re: DDL should become official part of DMD
BLS wrote: JPF wrote: BLS wrote: c topic.. what do you think ? IMO : this could be a D killer feature. I don't know how complicated that would be (licensing issues, ...), but as a developer / user I would really like it: It's needed to implement stuff like addins in a convenient way. And it would be great if we could finally use statically loaded shared libraries instead of static compilation of everything (I guess that needs compiler integration, so it's a good reason to include DDL with dmd ;-)). Also, if you look at http://www.digitalmars.com/d/1.0/dll.html#Dcode the current way to do D DLLs for use with D code is not very developer friendly. Exporting flat functions like getMyClass just doesn't feel right. Now compare that with DDLs features: http://www.dsource.org/projects/ddl/wiki/AboutDDL .DDL clearly wins. By the way, I guess most of you know that already, but http://h3.team0xf.com/devlog/?p=12 has an updated version of DDL with a new linker. I can hear you , but it seems that we are pretty alone. DDL showed signs of offering a proper reflection library. I'm drooling a bit over the possibility.
Re: Bug with patch
Michel Fortin wrote: I submitted a Phobos bug with a patch. Now I wonder: should I signal it to someone or just leave it lying there until it's found and applied by someone? (Here's the bug: http://d.puremagic.com/issues/show_bug.cgi?id=3298.) If it were assigned to someone, you should just wait for that person to handle it. Andrei seems to handle most Phobos development, so I'd assign it to him. The worst that happens is that he reassigns it.
Re: D on the Objective-C runtime?
Michel Fortin wrote: Another approach is my D/Objective-C bridge: http://michelf.com/projects/d-objc-bridge/, which allows you to write a bridged class like below. It needs D1 and is not multithreaded, only can do classes (no protocols, no categories for now), but it works quite well for what it does. snip /** Open a new window and put it on the center of the screen. */ void openWindow(Object sender) { } // Objective-C binding for IB actions. mixin IBAction!(openWindow); mixin IBAction!(openWebsite); Off topic, but this would be a good place for user-defined attributes. Then you could write something like: @IBAction void openWindow(Object sender) {}
Re: D naming style?
Jarrett Billingsley wrote: On Fri, Sep 4, 2009 at 9:18 PM, Ali Cehreliacehr...@yahoo.com wrote: Thank you! Jarrett Billingsley Wrote: Many people don't indicate class members with any kind of decoration I noticed that too. :) The justification that I've come up with is that, we need the decoration in e.g. C++, because the member declaration is not visible in the implementation file, so the decoration communicates that the member is in the header file. That's not the case in D, so there is no need for the decoration; but I miss them too. :) I'm consistently confused by D (and Java and C#) code that doesn't indicate member names, especially when they're named really common things that often conflict with local variables, like len or src or such. Unless the type is small enough to fit on a single screen, it's easy to forget the member names. Most of the code I write uses classes that fit in one screen (20 lines or so) and still prefixes private fields with an underscore. It's convenient when initializing fields from constructor parameters.
Re: The Linker is not a Magical Program
Walter Bright wrote: A rant I wrote a few months ago: http://programmer.97things.oreilly.com/wiki/index.php/The_Linker_Is_not_a_Magical_Program For reference, GNU ld has to be compiled with -linvisible-pink-unicorn.
Re: Reference value of structs not optimized or inlined?
Walter Bright wrote: Ary Borenszweig wrote: Walter Bright escribió: There are a lot of D specific optimization opportunities that are left undone for now. Why? Which of the thousand things people want done in D should be done first? Those that the askers are willing to implement first, I'd say.
Re: Should be easy
Saaa wrote: I did get it to compile at one time, but didn't know how to use it, like your code.. index( array, index2); //compiles and all, but how do I set the value? index( array, index2) = -1; // doesn't work If you're using d2, add 'ref' to the return type. Otherwise, you need indexAssign: void indexAssign(TArray : TArray[])(TArray array, BaseType!(TArray) value, int[] indices...) { static if (is (typeof (array[0]) == typeof(value)) { array[indices[0]] = value; } else { indexAssign(array[indices[0]], value, indices[1..$]); } } Also, why the ... ? In case you know the number of indices ahead of time. It costs nothing and lets you use a more natural syntax some of the time.
Re: Serialization for D. Comments, please!
grauzone wrote: Is there any real reason for all those mixins? which ones? All used by the user. That would be Serializable and SerializableRecuring. Also, what is curing in this context, and why would you need to do it multiple times?
Re: [Issue 3001] Templated types within a mixin not reinstantiated properly for new instantiation
--- Comment #1 from Matti Niemenmaa matti.niemenmaa+dbugzi...@iki.fi 2009-06-11 09:32:40 PDT --- I'm bumping this to 'blocker' because it's preventing me from using DMD for my project. I think we need clarification on the definition and usage of blocker. I typically would use it to mean that DMD cannot be released until the bug is fixed. Other people seem to be using it in a more liberal sense.
Re: D2's feature set?
Kristian Kilpi wrote: I think I shouldn't post this because I could very well start one of those mega-threads... :D Of course, only Walter Co know what D2 will include when it's finally 'released'. Concurrency stuff has been developed lately. But something more? Or is that it? What do you think? I haven't thought about it too much, but lets say something... ;) 1) Scoped members. For example: class Foo { scope Bar bar; // gets destructed with Foo object } You need to do escape analysis and whole program analysis to determine whether there are aliases to a scope member. Failing that, it's pretty easy to introduce bugs that are difficult to find. It would be fine as long as you always assign with a NewExpression.
Re: DMD 2.030 doesn't exist
A.M. wrote: Christopher Wright Wrote: A.M. wrote: please correct that, as it gives a bad picture of ur project. The Ur-Project has arrived! Photos at 11 -- we're waiting on a replacement lens. what is that?? are u making fun of me, or u misunderstood what I was saying? if u think I was wrong when I said so, correct me rather than just laughing at me. I saw a chance to make a joke and I took it. If you had used the word 'augment', I might have said Tissue augmentation is not a matter of twiddling bits. It's nothing against you. If you look around, there's only one other person here who uses abbreviations such as you do. It's generally a good idea to match your appearance to your surroundings, if there's no moral issue involved. It indicates that you have some knowledge about the community and want to be a part of it. You can, as an alternative, prove this via contributions and ignore the issue of fitting in. Starting with an accusatory complaint is not a good way to do this. Or you can take a few jokes. They're not meant to disparage you.
Re: Why are void[] contents marked as having pointers?
Jarrett Billingsley wrote: On Tue, Jun 2, 2009 at 7:11 PM, Christopher Wright dhase...@gmail.com wrote: Vladimir Panteleev wrote: I wasn't suggesting any GC modifications, I was just suggesting that void[]'s TypeInfo has pointers flag be set to false. The suggestion was that void[] be used as ubyte[] currently is, and then to use void*[] to indicate an array of unknown type that may have pointers. How do you have a void*[] point to a block of memory that is not a multiple of (void*).sizeof? Another good point. Or how do you index it by byte?
Re: DMD 2.030 doesn't exist
A.M. wrote: please correct that, as it gives a bad picture of ur project. The Ur-Project has arrived! Photos at 11 -- we're waiting on a replacement lens.
Re: Functions with package protection
Robert Fraser wrote: grauzone wrote: Sorry to dig up this old post, but I still don't understand why 'package' functions cannot be virtual? Is there a good reason for this? I can't see why we can't use polymorphism on 'package' functions! Is there way to make it virtual without making it public? (e.g. a 'virtual' keyword?) package needs to fixes: - package methods must be allowed to be virtual - package methods must be allowed to be accessed from sub packages (module a.b.x should be able to access package identifiers declared in module a.y) I don't understand why these fixes applied, especially because they are completely backward compatible. package methods must be allowed to be virtual isn't backwards-compatible. This code will work differently if package methods were made virtual: That's a larger problem, I think: you can override methods silently. The override keyword should be required.
Re: Why are void[] contents marked as having pointers?
bearophile wrote: Christopher Wright: Another good point. Or how do you index it by byte? How can you read write files of 3 bytes if voids are 4 bytes long chunks? :o) I don't understand. I want to read and write files byte-by-byte. Bye, bearophile Vladimir was suggesting that void[] be the same as ubyte[] and that you use void*[] if you might include a pointer. So that use case would be safe.
Re: Why are void[] contents marked as having pointers?
MLT wrote: Walter Bright Wrote: Vladimir Panteleev wrote: I don't know why it was decided to mark the contents of void[] as might have pointers. It makes no sense! Consider: [...] 3) It's very rare in practice that the only pointer to your object (which you still plan to access later) to be stored in a void[]-allocated array! Rare or common, it still would be a nasty bug lurking to catch someone. The default behavior in D should be to be correct code. Doing potentially unsafe things to improve performance should require extra effort - in this case it would be either using the gc function to mark the memory as not containing pointers, or storing them as ubyte[] instead. As quite a newby, I can sum up what I understood as follows: 1. The idea of void[] is that you can put anything in it without casting. 2. Because of this, you might put pointers in a void[]. 3. Since you have legitimately stored pointers, and we don't want to have the GC throw away something that we still have valid pointers for, we have to have the GC scan over void[] arrays for possible hits. 4. This pretty much means that any big(*) D program can not afford to put uniformly distributed data in a void[] array, because the GC will stop working correctly - it will not dispose of stuff that you don't need any more. (*) where big means a program that creates and destroys a lot of objects. So, currently if you want to use void[] to store non-pointers, you need to use the gc function to mark the memory as not containing pointers. A comment and a question. I agree that suddenly losing data because you stored a pointer in a void[] is worse than GC not working well. However, since GC in D is so automatic, almost any use of void[] to store non-pointer data will cause massive memory leaks and eventual program failure. First, this is no problem if you are merely aliasing an existing array. In order for it to be an issue, you must copy from some array to a void[] -- for instance, appending to an existing void[], or .dup'ing a void[] alias. (While a GC could work around the latter case, it would be unsafe -- you can append something with pointers to a void[] copy of an int[].) I can see 4 solutions... First, to not allow non-pointers to be stored in void[]. So non-pointers are stored in ubyte[], pointers in void[]. Kinda looses the main point of using void[]. Second, void[] is not scanned by GC, but you can mark it to be. This can cause bugs if you store a pointer in void[], and later retreive it, but don't mark correctly. This is an unsafe option. Third, void[] is scanned by GC, but you can mark it not to be. This can cause memory leaks if you store complex data in void[] in a big program, and don't handle GC marking correctly. This is already available. If you know your array doesn't have pointers, you can call GC.hasNoPointers(array.ptr). This is a safe option. Forth - somewhat more complex. Since the compiler knows exactly when a pointer is stored in a void[] and when not, it would be possible to have the compiler handle all by itself, as long as the property of having to be scanned by GC is dirty - once a variable has it, any other that touches that variable gets the property. This isn't really the case unless you get some really invasive whole program analysis (not available with D's compilation model, or if you want to interact with code written in other languages, or if you want to do runtime dynamic linking) or a really invasive runtime (think of calling a method every time you access an array). In point of fact, that's not going to be enough. You need to call the runtime with every assignment, since you might be passing individual ubytes around when they're part of a pointer and reassembling them somewhere else. Of these four solutions, the last 3 can still cause bugs if one stores both pointers and data in the same void[] array, no matter how the memory is marked, unless one does that marking on a very fine scale (is that possible?) struct S { int i; int* j; } You're screwed. My conclusion from all this is either don't use void[], or only use void[] to store pointers if you don't want bugs in a valid program. Not bugs, but potential performance issues. And the advice should be don't allocate void[], to split hairs.
Re: static this sucks, we should deprecate it
grauzone wrote: I had the same problem when writing the D/Objective-C bridge. Basically, if you ask the Objective-C runtime to instanciate a class not previously registered, it won't find it. My choice was to require manual pre-registrations of the classes you want to use, and register everything that is possible lazily as soon as you use a bridged class. Yes, and that pre-registration is only there to make the compiler generate the required compile-time reflection code (like with .tupleof or __traits). While compile-time reflection is probably really more flexible than runtime reflection, requiring this kind of registration remains a weakness of the compile-time approach. Solutions would be to make reflection fully dynamic (as you said) and extend RTTI for that, or to provide better ways to inspect modules as a whole. For the latter, maybe __traits should just be able to inspect all members of a module, and to follow imports. Or one could introduce some kind of module preprocessor, which enables you to execute code for each module at compile time (transparent for the processed module). Just by the way, annotations would also be nice. It's annoying to add additional information to members without them. This additional information can be stuff like default values, versioning of serializable members, behavior for missing values on deserialization, human readable help text if you want to use reflection to read/write user configuration files... I've seen four good uses of annotations in the past that could not easily be replaced: - dependency injection configuration - ORM configuration - event broker registration (this method should be called on this event) - test method/class registration This brings up an issue. Let's say I use static constructors to configure a serialization library, then use a static constructor to read objects using this serialization library. There's no way to define an order in which static constructors should be run within a module, but here it makes a huge difference. It would be very convenient to have as much of this configuration as possible in a readable format and not static constructors.
Re: Why are void[] contents marked as having pointers?
Vladimir Panteleev wrote: I wasn't suggesting any GC modifications, I was just suggesting that void[]'s TypeInfo has pointers flag be set to false. The suggestion was that void[] be used as ubyte[] currently is, and then to use void*[] to indicate an array of unknown type that may have pointers. This works when all pointers are aligned, or when the garbage collector does not optimize in cases where a type is known not to contain unaligned pointers. Alternatively, you can change the runtime to notify the GC on array copies so it can keep track of type information when you're avoiding the type system. But it's so easy to get around this by accident, it's not a reasonable solution (even if it could be made fast).
Re: Why are void[] contents marked as having pointers?
Vladimir Panteleev wrote: On Mon, 01 Jun 2009 05:28:39 +0300, Christopher Wright dhase...@gmail.com wrote: Vladimir Panteleev wrote: std.boxer is actually a valid counter-example for my post. The specific fix is simple: replace the void[] with void*[]. The generic fix is just to add a line to http://www.digitalmars.com/d/garbage.html adding that hiding your only reference in a void[] results in undefined behavior. I don't think this should be an inconvenience to any projects? What do you use for may contain unaligned pointers? Sorry, what do you mean? I don't understand why such a type is needed? Implementing support for scanning memory ranges for unaligned pointers will slow down the GC even more. Because you can have a struct with align(1) that contains pointers. Then these pointers can be unaligned. Then an array of those structs cast to a void*[] would contain pointers, but as an optimization, the GC would consider the pointers in this array aligned because you tell it they are.
Re: Why are void[] contents marked as having pointers?
Vladimir Panteleev wrote: On Mon, 01 Jun 2009 14:10:57 +0300, Christopher Wright dhase...@gmail.com wrote: Vladimir Panteleev wrote: On Mon, 01 Jun 2009 05:28:39 +0300, Christopher Wright dhase...@gmail.com wrote: Vladimir Panteleev wrote: std.boxer is actually a valid counter-example for my post. The specific fix is simple: replace the void[] with void*[]. The generic fix is just to add a line to http://www.digitalmars.com/d/garbage.html adding that hiding your only reference in a void[] results in undefined behavior. I don't think this should be an inconvenience to any projects? What do you use for may contain unaligned pointers? Sorry, what do you mean? I don't understand why such a type is needed? Implementing support for scanning memory ranges for unaligned pointers will slow down the GC even more. Because you can have a struct with align(1) that contains pointers. Then these pointers can be unaligned. Then an array of those structs cast to a void*[] would contain pointers, but as an optimization, the GC would consider the pointers in this array aligned because you tell it they are. The GC will not see unaligned pointers, regardless if they're in a struct or void[] array. The GC doesn't know the type of the data it's scanning - it just knows if it might contain pointers or it definitely doesn't contain pointers. Okay, so currently the GC doesn't do anything interesting with its type information. You're suggesting that that be enforced and codified.
Re: Source control for all dmd source
Leandro Lucarella wrote: Jérôme M. Berger, el 31 de mayo a las 19:03 me escribiste: Leandro Lucarella wrote: Well, that's great to hear! As Robert said, please tell if you need any help. Please, please, please consider using a distributed SCM (I think git would be ideal but mercurial is good too). That would make merging and branching a lot easier. Git is a bad choice because of its poor Windows support. Mercurial or Bazaar are much better in this regard. That's a mith, Git is pretty much supported in Windows now. I know people that uses it in a regular basis. See: http://code.google.com/p/msysgit/ I've used tortoise-git: http://code.google.com/p/tortoisegit/ It worked pretty well, though I didn't spend much time with it.
Re: Why are void[] contents marked as having pointers?
Lionello Lunesu wrote: Denis Koroskin wrote: On Sun, 31 May 2009 22:45:23 +0400, Vladimir Panteleev thecybersha...@gmail.com wrote: I just went through a ~15000-line project and replaced most occurrences of void[]. Now the project is an ugly mess of void[], ubyte[] and casts, but at least it doesn't leak memory like crazy any more. I don't know why it was decided to mark the contents of void[] as might have pointers. It makes no sense! FWIW, I also consider void[] as a storage for an arbitrary untyped binary data, and thus I believe GC shouldn't scan it. You're contradicting yourself there. void[] is arbitrary untyped data, so it could contain uints, floats, bytes, pointers, arrays, strings, etc. or structs with any of those. I think the current behavior is correct: ubyte[] is the new void*. Even in C, people often use unsigned char* for arbitrary data that does not include pointers.
Re: Why are void[] contents marked as having pointers?
Vladimir Panteleev wrote: std.boxer is actually a valid counter-example for my post. The specific fix is simple: replace the void[] with void*[]. The generic fix is just to add a line to http://www.digitalmars.com/d/garbage.html adding that hiding your only reference in a void[] results in undefined behavior. I don't think this should be an inconvenience to any projects? What do you use for may contain unaligned pointers?
Re: static this sucks, we should deprecate it
Derek Parnell wrote: On Sat, 30 May 2009 03:52:44 +1200, Tim Matthews wrote: Walter Bright wrote: It's unreliable because how do you specify the load order? And how does the user relate that to the source semantics? grauzone suggested this earlier: static this {} //full dependencies (all import statements) static this : a, b {} //only dependent from module a and b static this : void {} //no dependencies at all Is there a situation in which the dependancies are not known by the coder writer? For example, linking in some object code that has a static this{} section and not having the source code for that object code. file A.di: void foo(); file B.d: static this () { foo(); } All bets are off. A more sophisticated object format can correct this.
Re: [OT] Convention of Communication
Manfred Nowak wrote: At least a quarter of the last postings here do not follow the usenet convention of proper identifying the author---which is the full name of the author and a valid email adress of the author. I wonder whether those who set themself apart by breaking existing convention would appreciate to be set apart, when others too break convention. -manfred No. There's no reason to require or even incentivize non-anonymity.
Re: Encoding problems...
Robert Fraser wrote: Hi all, Quick question: I want to use some unicode identifiers, but I get unsupported char 0xe2, both with using and not using a BOM. The characters in question are the superset/subset-equals operators: ⊇ and ⊆... Perhaps these are just unsupported by DMD (in which case, I'll file a bug)? Thanks, Robert www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf (As an aside, Google's link obfuscation is hella annoying.) The relevant range is U+2200 to U+22FF (specifically U+2286, U+2287). It's not included.
Re: Why do I get stack overflow?
Ary Borenszweig wrote: When I compile this code I get stack overflow printed in the console. Anyone know why? --- int fact(int X)() { if(X == 0) { return 1; } else { int temp = fact!(X - 1)(); return X * temp; } } const someVar = fact!(0)(); --- Like Moritz said. You need to use static if there rather than if.
Re: Finalizing D2
Brad Roberts wrote: Don wrote: bearophile wrote: Andrei Alexandrescu: there's been a sharp increase in bug reports and patches recently. Walter and I are still scratching our head over that (it's not like dmd got much crappier overnight). I can only infer that more people have started using more of D. I think it's mostly a complex consequence of showing DMD source code. I have predicted this outcome in one post more than one year ago. Yes. It's the simple fact that you can compile DMD out-of-the-box. In fact, everyone who has downloaded DMD is forced to have a working copy of the source code! It's interesting to compare this with GDC, which, with the GNU license, is a purer form of free software. Yet, it's amazingly difficult to get it to compile (I tried once, and failed). It's not just about having source code available. I don't believe that to be the case. That would explain why more _fixes_ are being provided (primarily thanks to your contributions), but not why there's been an increase in bug _filing_. Walter would say that the number of bug reports for a compiler is an indication of its popularity.
Re: OT: on IDEs and code writing on steroids
Nick Sabalausky wrote: Christopher Wright dhase...@gmail.com wrote in message news:gv29vn$7a...@digitalmars.com... Nick Sabalausky wrote: Christopher Wright dhase...@gmail.com wrote in message news:gv0p4e$uv...@digitalmars.com... Nick Sabalausky wrote: I can see certain potential benefits to the general way C# does generics, but until the old (and I do mean old) issue of There's an IComparable, so why the hell won't MS give us an IArithmetic so we can actually use arithmetic operators on generic code? gets fixed (and at this point I'm convinced they've never had any intent of ever fixing that), I don't care how valid the reasoning behind C#'s general approach to generics is, the actual state of C#'s generics still falls squarely into the categories of crap and almost useless. IArithmetic is impossible in C# because operator overloads are static methods, and interfaces cannot specify static methods. Then how does IComparable work? It uses a member function instead. And they can't do the same for arithmetic? I believe the rationale for using static functions is so that you can add null to something. (The indexing operator, mind you, is a member property, so this doesn't always hold.) Additionally, this gets rid of opX_r. In practice, I doubt anyone uses that. But it's too late to make that change.
Re: any html parser with d binding
BCS wrote: Hello reimi, i have 2 question here: 1) can anyone suggest good html parser with d binding? IIRC ANTLR can generate D The last supported version was 2.7.something. It depends on phobos, possibly a rather old version of it (I don't know).
Re: Determine if template argument is an array
Fractal wrote: Hello Any body can explan me how to determine if a template argument is an array? Thanks Have a look at std.traits or tango.core.Traits. The appropriate way to check is via the templates they define, since it's clearer. Looking at the source will tell you how to replicate the effect should you need to.
Re: OT: on IDEs and code writing on steroids
Nick Sabalausky wrote: I can see certain potential benefits to the general way C# does generics, but until the old (and I do mean old) issue of There's an IComparable, so why the hell won't MS give us an IArithmetic so we can actually use arithmetic operators on generic code? gets fixed (and at this point I'm convinced they've never had any intent of ever fixing that), I don't care how valid the reasoning behind C#'s general approach to generics is, the actual state of C#'s generics still falls squarely into the categories of crap and almost useless. IArithmetic is impossible in C# because operator overloads are static methods, and interfaces cannot specify static methods.
Re: OT: on IDEs and code writing on steroids
dsimcha wrote: == Quote from Christopher Wright (dhase...@gmail.com)'s article Nick Sabalausky wrote: Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message news:gus0lu$1sm...@digitalmars.com... I've repeatedly failed to figure out the coolness of C#, and would appreciate a few pointers. Or references. Or delegates :o). Outside of this group, I think most of the people considering C# really cool are people who are unaware of D and are coming to C# from Java. What's cool about C# is that it's like a less-shitty version of Java (and *had* good tools, although the newer versions of VS are almost as much of a bloated unresponsive mess as Eclipse - Which come to think of it, makes me wonder - If Java has gotten so fast as many people claim, why is Eclipse still such a sluggish POS?). Compare C# to D though and most of the coolness fades, even though there are still a handful of things I think D could still learn from C# (but there's probably more than a handful that C# could learn from D). Generics and reflection. Generics just hide a lot of casts, usually, but that's still quite useful. And autoboxing is convenient, though not appropriate for D. What the heck do you need generics for when you have real templates? To me, generics seem like just a lame excuse for templates. Put a template in an interface. Use reflection to instantiate a template.
Re: OT: on IDEs and code writing on steroids
Nick Sabalausky wrote: Christopher Wright dhase...@gmail.com wrote in message news:gv0p4e$uv...@digitalmars.com... Nick Sabalausky wrote: I can see certain potential benefits to the general way C# does generics, but until the old (and I do mean old) issue of There's an IComparable, so why the hell won't MS give us an IArithmetic so we can actually use arithmetic operators on generic code? gets fixed (and at this point I'm convinced they've never had any intent of ever fixing that), I don't care how valid the reasoning behind C#'s general approach to generics is, the actual state of C#'s generics still falls squarely into the categories of crap and almost useless. IArithmetic is impossible in C# because operator overloads are static methods, and interfaces cannot specify static methods. Then how does IComparable work? It uses a member function instead.
Re: with still sucks + removing features + adding features
Derek Parnell wrote: On Mon, 18 May 2009 19:24:13 -0400, bearophile wrote: Christopher Wright: The more common suggestion is: alias bar = foo; This is acceptable, thank you :-) Now I'd like to know what others think about that. But does that mean 'when I write bar I really mean foo' or visa versa? Just pointing out that the '=' sign doesn't really automatically make it fully intuitive. It would work like assignments and renamed imports. Since when did you make an assignment in D where the right hand side was modified according to the value of the left hand side? It's not immediately obvious to someone who hasn't programmed yet, necessarily, but to someone even vaguely familiar with any modern programming language, there is one obvious meaning.
Re: While we're lynching features, how bout' them omittable parens?
Ary Borenszweig wrote: That's what I said it's a contract on the semantic of properties. :) But now I'm curious: what kind of properties do you write? A getter that does calculations and caches the results (rarely). A proxied getter that does lazy loading from a database table (like NHibernate). Mocks.
Re: foreach (x; a .. b) and foreach_reverse (x; a .. b) should be disallowed
grauzone wrote: Look at this for example: writefln(%s, is(typeof(rtzx) == char)); This compiles even if rtzx doesn't exist. But you probably wanted to check the type of rtzx, not it if rtzx exists. If you mistyped rtzx, the compiler will never tell you. You can do 'is(typeof(rtzx)) is(typeof(rtzx) == char)', or wrap it in a template.