Re: Arbitrary Size Integer Arrays
Don wrote: If you provide slice access (eg, give me elements [a..b] as an array of ints) then you can have reasonable performance. Unpacking consecutive elements can be done quite efficiently (it's an interesting optimisation problem, though!). It wouldn't be slicable because a slice would have to start at the beginning of a byte. The D bit type died in that quagmire.
Re: Arbitrary Size Integer Arrays
Walter Bright wrote: Don wrote: If you provide slice access (eg, give me elements [a..b] as an array of ints) then you can have reasonable performance. Unpacking consecutive elements can be done quite efficiently (it's an interesting optimisation problem, though!). It wouldn't be slicable because a slice would have to start at the beginning of a byte. The D bit type died in that quagmire. And std::vectorbool. I didn't mean an actual D slice -- I meant value semantics, not reference semantics. Give me a copy of X[a..b], putting it into an int[] array. Something like: struct ArbitrarySizedIntArray { int[] extractSlice(size_t a, size_t b, int [] dest=null) { } }
Strict mode
In some dynamic/scripting languages the basic programming modality is quite relaxed, this may help the programmer to quickly write a 10 lines long script. But when they want to write longer programs of 200 or 2000+ lines, some of such languages offer a strict mode that imposes more constraints and helps avoid/fix bugs. (Python for example doesn't have a strict mode, it has a single modality, that's more strict than basic Perl, but less strict than for example Java and quite less strict than Ada. While for example JavaScript is a mess, its management of global/local variables is broken.) The C language isn't very strict. D language is designed to be compatible with C, and often it just disallows some unsafe things of C. So SafeD modules may also be in strict mode, disallowing some things that are valid C that can be used in unsafe D modules. One of the several things that can be mode more strict in D are the retrieval of variable names in global/local scopes, and class attributes. For example Ruby forces to prepend class attribute names with @. Most programmers use some name convention for them, or this.. Good IDEs give different colors to class attributes. Replacing programmers conventions with something standard and compiler-enforced may be positive. Another possible idea: in strict mode functions must have an annotation that lists what variables are used from an outer scope, and if they are read, written or both. In this example the function foo has an input variable n, returns a tuple of int and double, and it uses variables a and b found in an outer scope, a is just read and b is read and written (the parentheses around the multiple output arguments are compulsive, they avoid troubles): (int,double) foo(in int n) { outer in int a; outer inout int b; double tot = 0.0; foreach (i, 0 .. n) { b[i] += a[i]; tot += b[i]; } return (n, tot); } Inside this function if you try to a variable c found in an outer scope you have a compilation error. Outer variables have to be listed before their usage. Using many global/outer variables is bad programming practice that leads to messy programs (so generally it's probably better to just add to such foo function a and b among its input/ref arguments), but if you want to use them, then it's better to list that they come from outside. This helps for example when you want to translate some strict D code to another language. There are other ways to make the language more strict, for example disallowing some automatic casts, etc. (C# already has some of this, for example float = double requires a cast. I don't remember if D2 requires this already). Bye, bearophile
Re: contravariant argument types: wanna?
On Wed, 23 Sep 2009 11:13:26 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Jeremie Pelletier wrote: Yigal Chripun wrote: On 23/09/2009 03:07, Andrei Alexandrescu wrote: Hello, Today, overriding functions have covariant return types: class A { A clone(); } class B : A { B clone(); // fine, overrides A.clone } That is entirely principled and cool. Now the entire story is that overriding function may have not only covariant return types, but also contravariant argument types: class A { A fun(B); } class B : A { B fun(A); // fine (in theory), overrides A.fun } Today D does not support contravariant arguments, but Walter told me once he'd be quite willing to implement them. It is definitely the right thing to do, but Walter would want to see a compelling example before getting to work. Is there interest in contravariant argument types? If so, do you know of a killer example? Thanks, Andrei consider: class Car { ... } class Truck : Car { ... } class Driver { void drive (Car c); } class truckDriver : Driver { void drive(Truck t); // NOT contra-variant !! } does the above design will be affected by your suggestion? You just described covariant arguments, which is a feature i'd also like to see. It's different from contravariant arguments, implementing one does not give the other unfortunately. Well there's a good reason for it: contravariant arguments are sound, covariant arguments aren't. My belief is that a design that would need a lot of argument covariance ought to be analyzed. I thought more about the car/truck example and I think it can be worked out nicely. The problem right now is that Truck inherits Car. But a truck is not substitutable for a car in all instances, because for example a driver able to drive a car cannot necessarily drive a truck. Here's a design that fixes that: class AutoVehicle { ... } class Car : AutoVehicle { ... } class Truck : AutoVehicle { ... } class Driver { // A driver is licensed to drive a car void drive(Car c); } class TruckDriver : Driver { // A truck driver is licensed to drive a car... override void drive(Car c); // ... and a truck void drive(Truck c); // No contravariance needed yet } class JamesBond : Driver { // James Bond can drive any auto vehicle // Contravariance needed here override void drive(AutoVehicle c) { ... } } Now if what you have is a JamesBond and a Truck, you need contravariance to have him drive it. (A HotGirl may or may not be present in the scene.) Your example just triggered a possible problem with contravariance. Consider this class: class Bad : TruckDriver { override void drive(AutoVehicle c) { ...} } What does this override, drive(Truck) or drive(Car), or both? What if you didn't want to override both? My instinct is that this should be an error, to keep things simple. But it might be very annoying for some designs... -Steve
Regular expression support in D2
Just having a poke under the D2/Phobos hood with a view to playing with D2 in anger (though I'm wary of jumping from D1 just right now). There are 2 modules: regex.d and regexp.d Which does one use for regular expression support in D2 and why? Is one legacy with respect to the other? Thanks -- Justin Johansson
Re: Regular expression support in D2
Justin Johansson wrote: Just having a poke under the D2/Phobos hood with a view to playing with D2 in anger (though I'm wary of jumping from D1 just right now). There are 2 modules: regex.d and regexp.d Which does one use for regular expression support in D2 and why? Is one legacy with respect to the other? Thanks -- Justin Johansson Use std.regex. regexp is scheduled for deprecation.
Re: contravariant argument types: wanna?
Steven Schveighoffer wrote: On Wed, 23 Sep 2009 11:13:26 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: class AutoVehicle { ... } class Car : AutoVehicle { ... } class Truck : AutoVehicle { ... } class Driver { // A driver is licensed to drive a car void drive(Car c); } class TruckDriver : Driver { // A truck driver is licensed to drive a car... override void drive(Car c); // ... and a truck void drive(Truck c); // No contravariance needed yet } class JamesBond : Driver { // James Bond can drive any auto vehicle // Contravariance needed here override void drive(AutoVehicle c) { ... } } Now if what you have is a JamesBond and a Truck, you need contravariance to have him drive it. (A HotGirl may or may not be present in the scene.) Your example just triggered a possible problem with contravariance. Consider this class: class Bad : TruckDriver { override void drive(AutoVehicle c) { ...} } What does this override, drive(Truck) or drive(Car), or both? What if you didn't want to override both? My instinct is that this should be an error, to keep things simple. But it might be very annoying for some designs... It should override both. It is already the case that one method overrides several others (e.g. with multiple inheritance of interfaces). Andrei
override(T)
Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei
Re: contravariant argument types: wanna?
On Thu, 24 Sep 2009 09:06:41 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Steven Schveighoffer wrote: On Wed, 23 Sep 2009 11:13:26 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: class AutoVehicle { ... } class Car : AutoVehicle { ... } class Truck : AutoVehicle { ... } class Driver { // A driver is licensed to drive a car void drive(Car c); } class TruckDriver : Driver { // A truck driver is licensed to drive a car... override void drive(Car c); // ... and a truck void drive(Truck c); // No contravariance needed yet } class JamesBond : Driver { // James Bond can drive any auto vehicle // Contravariance needed here override void drive(AutoVehicle c) { ... } } Now if what you have is a JamesBond and a Truck, you need contravariance to have him drive it. (A HotGirl may or may not be present in the scene.) Your example just triggered a possible problem with contravariance. Consider this class: class Bad : TruckDriver { override void drive(AutoVehicle c) { ...} } What does this override, drive(Truck) or drive(Car), or both? What if you didn't want to override both? My instinct is that this should be an error, to keep things simple. But it might be very annoying for some designs... It should override both. It is already the case that one method overrides several others (e.g. with multiple inheritance of interfaces). Yes, but interfaces have no implementation -- it's clear you want to override both because there's no alternative. Here is another example: class RaceCar : Car {...} class RaceCarDriver : Driver { alias Driver.drive drive; void drive(RaceCar c) {...} // doesn't override Driver.drive(Car), because he drives normal cars in a different way } class BadDriver : RaceCarDriver // drives all cars like a race car { override void drive(Car c) {...} } Should this override RaceCarDriver.drive(RaceCar)? Currently, this is valid code (tested on 1.046) and results in different behavior than what you propose. Although it's likely in my example you *want* to override both, but there could be cases where you do not. -Steve
Re: override(T)
On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2? In the override(T) world, What does this do? auto ls = new LotterySimulation(); ls.draw(); ??? I'm not sure this works... -Steve
Re: override(T)
So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? One vote in favor :)
Re: override(T)
Steven Schveighoffer wrote: On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. I find the general contravariance not to be that compelling, but for sure being able to implicitly cast delegates makes a lot of sense, since you take the overriding/overloading issues out of the equation. -Steve I agree. Andrei
Re: override(T)
Andrei Alexandrescu wrote: ... So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places.
Re: override(T)
Steven Schveighoffer wrote: On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2? In the override(T) world, What does this do? auto ls = new LotterySimulation(); ls.draw(); ??? I'm not sure this works... -Steve That would be a compile-time error. You'd need to extract the interface you want to work with, and then call against it. In addition, LotterySimulation could offer convenience functions that do that. Andrei
Re: contravariant argument types: wanna?
Steven Schveighoffer wrote: On Tue, 22 Sep 2009 22:02:59 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Yeah most of my display interfaces would make use of covariant arguments, I use main abstract factory for the entire package, and the objects it creates contain factory methods themselves. I plan to have implementations for all of win32, gdk, x11, quartz, cairo, pango, d2d, dwrite, gl, gl3 and finally d3d7 up to d3d11. Most of the client code will therefore see only the interfaces in order to maintain portability, and to allow different implementations to live in the same executable (for example win32/gl/cairo/pango for up to vista or win32/d3d/d2d/dwrite if on win7 and up). Here is a watered down version of a few interfaces I use, which are used by client code: interface IDrawable {} interface IWindow : IDrawable {} // onscreen drawable interface ISurface : IDrawable {} // offscreen drawable interface IDisplayContext {} // base of 2d-3d contextes interface IRenderContext {} // 3d context interface IWindowRenderContext {} // specialized onscreen 3d context interface IRenderer { IWindowRenderContext CreateRenderContext(IWindow); ISurfaceRenderContext CreateRenderContext(ISurface); } And some of their current implementation, which are all used within the package: abstract class Win32Drawable : IDrawable {} final class Win32Window : Win32Drawable, IWindow {} final class Win32Surface : Win32Drawable, IWindow {} final class GLRenderer : IRenderer { GLWindowRenderContext CreateRenderContext(IWindow window) { if(auto win32Window = cast(Win32Window)window) return new GLWindowRenderContext(win32Window); else throw new Error(); } GLSurfaceRenderContext CreateRenderContext(ISurface surface) { if(auto win32Surface = cast(Win32Surface)surface) return new GLSurfaceRenderContext(win32Surface); else throw new Error(); } } abstract class GLRenderContext : IRenderContext {} final class GLWindowRenderContext : GLRenderContext, IWindowRenderContext { this(Win32Window) {} } final class GLSurfaceRenderContext : GLRenderContext, ISurfaceRenderContext { this(Win32Surface) {} } I have over a hundred of such methods doing dynamic casts across all the different implementations like these twos in this package alone, a display interface is quite a large beast. Of course if you can suggest a better way of doing methods expecting a specific implementation of an object, while still allowing client code to call them with the interface pointer, I'd be glad to implement it :) Jeremie There are some possible solutions. First, it looks like you are using interfaces to abstract the platform, which seems more appropriate for version statements. I once wrote an OS abstraction library in C++, and in my fanatic attempt to avoid using the preprocessor for anything, I made everything interfaces (pure abstract classes). I think with D, the version statements are a much better solution, and will reduce overhead quite a bit. Second, Your IRenderer is the one responsible for creating a render context, but it depends on being hooked up with the appropriate IWindow or ISurface object. However, the IRenderer implementation's methods are pretty much static (granted they might be trimmed down). Why not move them into the IWindow and ISurface interfaces? interface IWindow : IDrawable { IWindowRenderContext CreateRenderContext(); } interface ISurface : IDrawable { ISurfaceRenderContext CreateRenderContext(); } If you need an instance of IRenderer for some other reason not shown, then consider using a hidden singleton of the correct implementation. -Steve Because there will be multiple implementations living in the same executable. We all know how microsoft likes to force new technology to new windows versions. I want support for Direct2D, DirectWrite, and all versions of Direct3D. Which requires different implementations for 7, vista, and xp. Then some people might have better performance with GL, for graphic adapter vendor and driver issues, so I'm throwing such an implementation in the mix. On unix you have a choice of different windowing toolkits, be it Gnome, Qt, Xfce or directly using X11 but losing specific features offered by the toolkits. As for merging IRenderer with the drawables, this wouldn't fit my design. I use what I call render contexts and paint contexts for 3d and 2d drawing respectively, which are both built upon a common set of display interfaces to get most of their shared concepts unified and compatible with one another. I also have font layering and rendering interfaces usable by the two. And given that many different render and paint implementations can be used from the same drawable targets, it wouldn't make sense. My first design was using version statements but it was far from flexible enough for my needs. The overhead is mostly needed to allocate the
Re: override(T)
On Thu, 24 Sep 2009 08:30:46 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei It would be a welcome addition. C# calls this feature 'explicit interface implementation' and has a different syntax: class LotterySimulation : Lottery, Figure { void Lottery.draw() {}; void Figure.draw() {}; } The functions cannot be called through an instance of the class, only through the interfaces. In D: auto ls = new LotterySimulation; ls.draw(); Which 'draw' will be called?
Re: override(T)
On Thu, 24 Sep 2009 10:30:09 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Steven Schveighoffer wrote: In the override(T) world, What does this do? auto ls = new LotterySimulation(); ls.draw(); ??? I'm not sure this works... -Steve That would be a compile-time error. You'd need to extract the interface you want to work with, and then call against it. In addition, LotterySimulation could offer convenience functions that do that. OK. And it seems C# does the same thing, from what others are saying. Unfortunately, we don't have a distinct scope-resolution operator (like ::) so there wouldn't be a way to do this without casting to the interface, but I suppose in the cases where you are doing this, you aren't generally using the object directly, only through an interface. -Steve
Re: override(T)
Andrei Alexandrescu wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Doesn't the override keyword trigger an error here? There are no method to override since you're implementing it for the first time. Why would it matter to override both of them differently? You'd need extra work with the vtables to call either depending on the interface pointer its called from. And when called from LotterySimulation how would the compiler pick which one to call? To me it just seems backwards, I would just implement both algorithms in LotterySimulation.draw() since if you implement both interfaces you want that object to perform both draws, even if called from a Lottery interface you're still calling a LotterySimulation which is also aware of the Figure interface. Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei From the news title I thought you meant override(T) where T is the covariant type for the contravariant override: class A { void foo(B); } class B:A { override(B) void foo(A); } Which could just as well be used to generate covariant boilerplate prologs :) As for the interface selection, I'm still asking, how would the compiler know what LotterySimulation.draw() calls into? Jeremie
Re: override(T)
Daniel Keep: Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Looks good enough, I can understand it. For the programmers out there it's positive to use a syntax already in use (especially if it's a good enough syntax). D design principles say D doesn't want to be revolutionary. In D originality is not a virtue when there are no net advantages, syntactical or otherwise. C# has other things worth copying beside explicit interface implementations :-) Bye, bearophile
Re: override(T)
Daniel Keep wrote: Andrei Alexandrescu wrote: ... So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places. Even better! Andrei
Re: override(T)
Steven Schveighoffer wrote: On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2? You're right. I haven't managed to do it yet (the one-leg renaming works in C++, though I forgot the details). All the more argument for defining the feature. Andrei
Re: Arbitrary Size Integer Arrays
Hello Walter, Don wrote: If you provide slice access (eg, give me elements [a..b] as an array of ints) then you can have reasonable performance. Unpacking consecutive elements can be done quite efficiently (it's an interesting optimisation problem, though!). It wouldn't be slicable because a slice would have to start at the beginning of a byte. The D bit type died in that quagmire. It could be sliced if you are willing to play games like element zero is N places after this memory address. At a minimum, Every 8th element will be byte aligned.
Re: contravariant argument types: wanna?
On Thu, 24 Sep 2009 10:54:06 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Steven Schveighoffer wrote: On Tue, 22 Sep 2009 22:02:59 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Yeah most of my display interfaces would make use of covariant arguments, I use main abstract factory for the entire package, and the objects it creates contain factory methods themselves. I plan to have implementations for all of win32, gdk, x11, quartz, cairo, pango, d2d, dwrite, gl, gl3 and finally d3d7 up to d3d11. Most of the client code will therefore see only the interfaces in order to maintain portability, and to allow different implementations to live in the same executable (for example win32/gl/cairo/pango for up to vista or win32/d3d/d2d/dwrite if on win7 and up). Here is a watered down version of a few interfaces I use, which are used by client code: interface IDrawable {} interface IWindow : IDrawable {} // onscreen drawable interface ISurface : IDrawable {} // offscreen drawable interface IDisplayContext {} // base of 2d-3d contextes interface IRenderContext {} // 3d context interface IWindowRenderContext {} // specialized onscreen 3d context interface IRenderer { IWindowRenderContext CreateRenderContext(IWindow); ISurfaceRenderContext CreateRenderContext(ISurface); } And some of their current implementation, which are all used within the package: abstract class Win32Drawable : IDrawable {} final class Win32Window : Win32Drawable, IWindow {} final class Win32Surface : Win32Drawable, IWindow {} final class GLRenderer : IRenderer { GLWindowRenderContext CreateRenderContext(IWindow window) { if(auto win32Window = cast(Win32Window)window) return new GLWindowRenderContext(win32Window); else throw new Error(); } GLSurfaceRenderContext CreateRenderContext(ISurface surface) { if(auto win32Surface = cast(Win32Surface)surface) return new GLSurfaceRenderContext(win32Surface); else throw new Error(); } } abstract class GLRenderContext : IRenderContext {} final class GLWindowRenderContext : GLRenderContext, IWindowRenderContext { this(Win32Window) {} } final class GLSurfaceRenderContext : GLRenderContext, ISurfaceRenderContext { this(Win32Surface) {} } I have over a hundred of such methods doing dynamic casts across all the different implementations like these twos in this package alone, a display interface is quite a large beast. Of course if you can suggest a better way of doing methods expecting a specific implementation of an object, while still allowing client code to call them with the interface pointer, I'd be glad to implement it :) Jeremie There are some possible solutions. First, it looks like you are using interfaces to abstract the platform, which seems more appropriate for version statements. I once wrote an OS abstraction library in C++, and in my fanatic attempt to avoid using the preprocessor for anything, I made everything interfaces (pure abstract classes). I think with D, the version statements are a much better solution, and will reduce overhead quite a bit. Second, Your IRenderer is the one responsible for creating a render context, but it depends on being hooked up with the appropriate IWindow or ISurface object. However, the IRenderer implementation's methods are pretty much static (granted they might be trimmed down). Why not move them into the IWindow and ISurface interfaces? interface IWindow : IDrawable { IWindowRenderContext CreateRenderContext(); } interface ISurface : IDrawable { ISurfaceRenderContext CreateRenderContext(); } If you need an instance of IRenderer for some other reason not shown, then consider using a hidden singleton of the correct implementation. -Steve Because there will be multiple implementations living in the same executable. We all know how microsoft likes to force new technology to new windows versions. I want support for Direct2D, DirectWrite, and all versions of Direct3D. Which requires different implementations for 7, vista, and xp. Then some people might have better performance with GL, for graphic adapter vendor and driver issues, so I'm throwing such an implementation in the mix. On unix you have a choice of different windowing toolkits, be it Gnome, Qt, Xfce or directly using X11 but losing specific features offered by the toolkits. OK, my assumption was wrong, win32 is a toolkit identifier, not a platform identifier :) As for merging IRenderer with the drawables, this wouldn't fit my design. I use what I call render contexts and paint contexts for 3d and 2d drawing respectively, which are both built upon a common set of display interfaces to get most of their shared concepts unified and compatible with one another. I also have font layering and rendering interfaces usable by the two. And given that many different render and paint
Re: override(T)
Andrei Alexandrescu: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. Something that may be useful, partially related: http://en.wikipedia.org/wiki/Multiple_dispatch http://en.wikipedia.org/wiki/Generic_function Bye, bearophile
Re: override(T)
Something that may be useful, partially related: http://en.wikipedia.org/wiki/Multiple_dispatch http://en.wikipedia.org/wiki/Generic_function Something similar to the CLisp syntax looks good enough for D (I think there's no need to add an explicit mark that reminds there's some runtime cost to be paid in this calls): void collideWith(Asteroid x, Asteroid y) { ...} void collideWith(Asteroid x, Spaceship y) { ...} ... Bye, bearophile
Re: contravariant argument types: wanna?
Steven Schveighoffer wrote: On Thu, 24 Sep 2009 10:54:06 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Steven Schveighoffer wrote: On Tue, 22 Sep 2009 22:02:59 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Yeah most of my display interfaces would make use of covariant arguments, I use main abstract factory for the entire package, and the objects it creates contain factory methods themselves. I plan to have implementations for all of win32, gdk, x11, quartz, cairo, pango, d2d, dwrite, gl, gl3 and finally d3d7 up to d3d11. Most of the client code will therefore see only the interfaces in order to maintain portability, and to allow different implementations to live in the same executable (for example win32/gl/cairo/pango for up to vista or win32/d3d/d2d/dwrite if on win7 and up). Here is a watered down version of a few interfaces I use, which are used by client code: interface IDrawable {} interface IWindow : IDrawable {} // onscreen drawable interface ISurface : IDrawable {} // offscreen drawable interface IDisplayContext {} // base of 2d-3d contextes interface IRenderContext {} // 3d context interface IWindowRenderContext {} // specialized onscreen 3d context interface IRenderer { IWindowRenderContext CreateRenderContext(IWindow); ISurfaceRenderContext CreateRenderContext(ISurface); } And some of their current implementation, which are all used within the package: abstract class Win32Drawable : IDrawable {} final class Win32Window : Win32Drawable, IWindow {} final class Win32Surface : Win32Drawable, IWindow {} final class GLRenderer : IRenderer { GLWindowRenderContext CreateRenderContext(IWindow window) { if(auto win32Window = cast(Win32Window)window) return new GLWindowRenderContext(win32Window); else throw new Error(); } GLSurfaceRenderContext CreateRenderContext(ISurface surface) { if(auto win32Surface = cast(Win32Surface)surface) return new GLSurfaceRenderContext(win32Surface); else throw new Error(); } } abstract class GLRenderContext : IRenderContext {} final class GLWindowRenderContext : GLRenderContext, IWindowRenderContext { this(Win32Window) {} } final class GLSurfaceRenderContext : GLRenderContext, ISurfaceRenderContext { this(Win32Surface) {} } I have over a hundred of such methods doing dynamic casts across all the different implementations like these twos in this package alone, a display interface is quite a large beast. Of course if you can suggest a better way of doing methods expecting a specific implementation of an object, while still allowing client code to call them with the interface pointer, I'd be glad to implement it :) Jeremie There are some possible solutions. First, it looks like you are using interfaces to abstract the platform, which seems more appropriate for version statements. I once wrote an OS abstraction library in C++, and in my fanatic attempt to avoid using the preprocessor for anything, I made everything interfaces (pure abstract classes). I think with D, the version statements are a much better solution, and will reduce overhead quite a bit. Second, Your IRenderer is the one responsible for creating a render context, but it depends on being hooked up with the appropriate IWindow or ISurface object. However, the IRenderer implementation's methods are pretty much static (granted they might be trimmed down). Why not move them into the IWindow and ISurface interfaces? interface IWindow : IDrawable { IWindowRenderContext CreateRenderContext(); } interface ISurface : IDrawable { ISurfaceRenderContext CreateRenderContext(); } If you need an instance of IRenderer for some other reason not shown, then consider using a hidden singleton of the correct implementation. -Steve Because there will be multiple implementations living in the same executable. We all know how microsoft likes to force new technology to new windows versions. I want support for Direct2D, DirectWrite, and all versions of Direct3D. Which requires different implementations for 7, vista, and xp. Then some people might have better performance with GL, for graphic adapter vendor and driver issues, so I'm throwing such an implementation in the mix. On unix you have a choice of different windowing toolkits, be it Gnome, Qt, Xfce or directly using X11 but losing specific features offered by the toolkits. OK, my assumption was wrong, win32 is a toolkit identifier, not a platform identifier :) As for merging IRenderer with the drawables, this wouldn't fit my design. I use what I call render contexts and paint contexts for 3d and 2d drawing respectively, which are both built upon a common set of display interfaces to get most of their shared concepts unified and compatible with one another. I also have font layering and rendering interfaces usable by the two. And given that many different render and paint implementations can be
Re: override(T)
Daniel Keep wrote: Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places. I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud. Making it look like C# has bad sides too. Explicit overriding in C# always hides the member from the public view. So this like C# can easily backfire. ++andreis_suggestion; L.
Re: DFL IDE Editor ?
On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl)
Re: contravariant argument types: wanna?
On Thu, 24 Sep 2009 11:53:13 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Steven Schveighoffer wrote: The Tango lib used to define Input and Output streams independent of Seekable streams (there was a Seek interface which was applied separately to an input/output implementation class). But what ends up happening is that it was unwieldly to use streams in cases where seeking is used, because you have to dynamic-cast to the seek interface to determine if seeking is available. interface ISeekableInputStream : IInputStream, ISeekableStream {} You'd think this works well, but it still doesn't cut it. There are about a dozen filter classes in tango that would have to have seekable and non-seekable versions. This was the original problem (that you couldn't seek the filter classes). Covariant arguments is something you're gonna come across at some point or another. Having language support for it does not make it the rule, but a convenience for the exception. Having language support makes it not an exception, even if it's not the rule. The reason it's not automatic is because the language designer wants you to know hey, you're doing something that isn't cheap. Just silently allowing it makes for code that too easily can call multiple dynamic casts every time you call a method. -Steve
Re: override(T)
On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei Umm, but what method would LotterySimulation.draw call? Would it be the override(Lottery) method or the override(Figure) method?
Re: override(T)
On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu l...@lunesu.remove.com wrote: Daniel Keep wrote: Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places. I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud. C# uses familiar syntax to qualify the function name. I think it's natural enough. Making it look like C# has bad sides too. Explicit overriding in C# always hides the member from the public view. So this like C# can easily backfire. According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces. ++andreis_suggestion; I give my vote to C#'s syntax if D can adopt it. L.
Why not move cast to the standard library?
With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye?
Re: override(T)
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. auto x = new LotterySimulation; x.draw(); // what happens?
Re: Why not move cast to the standard library?
On Thu, Sep 24, 2009 at 12:35 PM, downs default_357-l...@yahoo.de wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? std.conv.to is more or less a proof-of-concept of this already. :
Re: contravariant argument types: wanna?
Steven Schveighoffer wrote: The solution we ended up using is that *all* streams defined the seek function, even if they didn't support seeking, and if you called it on such objects, they just throw an exception. So, if you want to see if an object supports seeking, you must call the method + catch the exception? How is this better than a dynamic cast?
Re: Why not move cast to the standard library?
downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei
Re: override(T)
Sean Kelly wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. auto x = new LotterySimulation; x.draw(); // what happens? Nolo compilendere. Andrei
Re: Why not move cast to the standard library?
Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :)
Re: Why not move cast to the standard library?
downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. Andrei
Re: contravariant argument types: wanna?
On Thu, 24 Sep 2009 12:47:12 -0400, grauzone n...@example.net wrote: Steven Schveighoffer wrote: The solution we ended up using is that *all* streams defined the seek function, even if they didn't support seeking, and if you called it on such objects, they just throw an exception. So, if you want to see if an object supports seeking, you must call the method + catch the exception? How is this better than a dynamic cast? It makes the requirement for things that want to wrap streams less stringent. For example, I can implement a Buffer that handles both seekable and non-seekable streams instead of 2 buffer types. It also has less of a penalty for cases where you know the stream is seekable. -Steve
Re: Why not move cast to the standard library?
Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei
should protected imply package?
In Java, protected-level protection implies package-level protection (see e.g. http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html). Should we copy that behavior in D, or take advantage of the package keyword and require it as in package protected? Andrei
Re: override(T)
On 24/09/2009 16:30, Andrei Alexandrescu wrote: Walter and I discussed last night about contravariance and all and could not find a compelling argument in favor of implementing contravariant arguments right now. The feature is nontrivial to implement, potentially surprising, and has a number of odd corner cases. One feature that does get requested often in C++ and Java is the ability to choose which class/interface contains the method you want to override. Consider: interface Lottery { void draw(); } interface Figure { void draw(); } class LotterySimulation : Lottery, Figure { override void draw(); } Right now draw() overrides both methods, but you'd want to override them separately. You could do so through an intermediate interface: class Figure2 : Figure { void draw2() { return draw(); } } class LotterySimulation : Lottery, Figure2 { override void draw(); override void draw2(); } There are a few problems with this, among which the fact that LotterySimulation now cannot inherit another class; the one class slot was occupied by Figure2. So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei in your code you tried to rename draw(), why not make this explicit? provide syntax to disambiguate by explicitly renaming the functions. for example: class A : Figure, Lottery { override(Figure.draw) void draw() { .. } override(Lottery.draw) void draw2() { .. } } please give more consideration to the idea than to my initial suggested syntax. btw, this is how Eiffel implements MI, the programmer specifies the mapping between names from the base class(es) and the subclass in order to solve ambiguities.
Re: Why not move cast to the standard library?
On Thu, 24 Sep 2009 12:35:22 -0400, downs default_357-l...@yahoo.de wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What is the benefit? Does it allow anything that isn't possible today (aside from using cast as a member, which I find not that worthy)? What I'd much rather have is directed casts, even if they are supported by the compiler, such as the casting features of C++ (i.e. const_cast and static_cast). I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat. -Steve
Re: should protected imply package?
Andrei Alexandrescu wrote: In Java, protected-level protection implies package-level protection (see e.g. http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html). Should we copy that behavior in D, or take advantage of the package keyword and require it as in package protected? Andrei I make a clear distinction between 'protected' which can be accessed by any subclasses no matter their modules or packages, and 'package' which is like public but for the current package only. Jeremie
Re: Why not move cast to the standard library?
On 24/09/2009 19:35, downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? vote++; casts and especially implicit casts are evil. The programmer should always prefer calling a conversion function instead of relying on casts. for example, for FP - integer conversion the user may need to change the rounding/truncation behavior.
How does one ask a non-invasive question on this (or any other) forum?
See subject line
Re: Why not move cast to the standard library?
grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie
Re: How does one ask a non-invasive question on this (or any other) forum?
Justin Johansson: See subject line You can't. All questions here will be scrupulously scrubbed, looking for subversive ideas or hidden irony, and if something is found they invariably spout and blossom into invasive threads of often pointless but interesting discussions. Bear hugs, bearophile
Re: DFL IDE Editor ?
Robert Jacques дµ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive
Is typedef an alien?
No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? -- Yours truly, Justin Johansson
Re: How does one ask a non-invasive question on this (or any other) forum?
bearophile wrote: Justin Johansson: See subject line You can't. All questions here will be scrupulously scrubbed, looking for subversive ideas or hidden irony, and if something is found they invariably spout and blossom into invasive threads of often pointless but interesting discussions. Bear hugs, bearophile I SMELL SARCASM. I think somebody needs to have his Antisarcasmon™ dosage upped! :)
Re: Why not move cast to the standard library?
Jeremie Pelletier wrote: grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie What about cast!int could _not_ be done as a function?
Re: Is typedef an alien?
Aenigmatic: Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? -- Yours truly, Justin Johansson The semantics of D typedef comes from Pascal, not from C. It's useful, but unfortunately it's not a true first-class feature in D, its purposes are mostly pre-OOP. You can use it for example to pass a type-specific fixed-size matrix to several functions, and for similar purposes. Not-ex-Pascal programmers may find it less useful (as nested functions). I'd even like to have Pascal-inspired ranged integral values in D :-) int (1 .. 20) x; They give some safety, and in the wild I've already seen D code like: int foo; // values 0 .. 20 (There are several modern ways to generalize this idea of the type system, but in many programs such integral ranges are enough). Often the comments you can find in programs written in old languages can be written as annotations and syntax in modern languages. Generally it's good to have a syntax to tell the compiler some of the semantics you want to put into the comments. Bye, bearophile
Re: Why not move cast to the standard library?
Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote: I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat. I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in 1000 LOC programs.
Re: Is typedef an alien?
Thu, 24 Sep 2009 14:36:01 -0400, Aenigmatic thusly wrote: No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? -- Yours truly, Justin Johansson Typedef works differently in D. It should create a new type, in C++ it's just a type synonym.
Re: Strict mode
Thu, 24 Sep 2009 06:17:22 -0400, bearophile thusly wrote: There are other ways to make the language more strict, for example disallowing some automatic casts, etc. (C# already has some of this, for example float = double requires a cast. I don't remember if D2 requires this already). Since your suggestion may add new syntactic constructs, can you somehow show that making the language more strict also improves overall program quality in some ways that unit testing and stronger type system cannot achieve.
Re: How does one ask a non-invasive question on this (or any other) forum?
downs wrote: bearophile wrote: Justin Johansson: See subject line You can't. All questions here will be scrupulously scrubbed, looking for subversive ideas or hidden irony, and if something is found they invariably spout and blossom into invasive threads of often pointless but interesting discussions. Bear hugs, bearophile I SMELL SARCASM. I think somebody needs to have his Antisarcasmon™ dosage upped! :) I'm actually glad to remark that things have been quite peaceful for quite a while now. Part of the reason may be the summer lull, but now that traffic is starting to pick up, let's keep the light coming without much heat. Andrei
Re: Is typedef an alien?
I'd even like to have Pascal-inspired ranged integral values in D :-) Once structs in D2 become flexible enough (with methods like opBool that get called by if(x){}, etc) they can be used to define such ranged integer. I think this flexibility improvement is a better strategy. Bye, bearophile
Re: Is typedef an alien?
language_fan wrote: Thu, 24 Sep 2009 14:36:01 -0400, Aenigmatic thusly wrote: No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? -- Yours truly, Justin Johansson Typedef works differently in D. It should create a new type, in C++ it's just a type synonym. Exactly, it's most useful to create specialized types from primitives. For example I declared the HANDLE type in my win32 bindings as typedef const(void)* HANDLE; and all its specialized types (HWND, HMONITOR, HDC, etc) are also typedefs of HANDLE, so I have very little chances of misusing them. The only downside is that I must use HWND.init instead of null, but that's just giving better readability to function calls. This is something you just can't do in C.
Re: Why not move cast to the standard library?
downs wrote: Jeremie Pelletier wrote: grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie What about cast!int could _not_ be done as a function? I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives.
Re: Why not move cast to the standard library?
Jeremie Pelletier wrote: downs wrote: Jeremie Pelletier wrote: grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie What about cast!int could _not_ be done as a function? I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives. What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :)
Re: Why not move cast to the standard library?
Thu, 24 Sep 2009 21:13:48 +0200, downs thusly wrote: language_fan wrote: Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote: I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat. I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in 1000 LOC programs. We write templates in 1000 LOC programs to avoid having to write 100 MLOC :) Also, let me categorically state: if you're writing 100MLOC programs, you're doing it horribly, horribly wrong. No conceivable program possibly requires that much logic. I agree, usually there is *something* wrong with your program if it gets that large. I personally do not consider programs of that size very reliable. But the thing is, you probably know that people fear template instantiations. Not only can they cause really weird linking bugs, the more templates you have, the larger the executables get. Also as dmd does not use garbage collection (yet?) during compilation, the instantiations can easily kill the compilation process. Sometimes templates are abused to do what macros were supposed to by used for. I can imagine that templates can cause problems much sooner, you do not even need 1 MLOC of code to do that. Apparently D will never get a powerful macro system since the focus is on other features and templates seem to work just fine on the small scale.
Re: Why not move cast to the standard library?
language_fan wrote: Thu, 24 Sep 2009 13:47:21 -0400, Steven Schveighoffer thusly wrote: I actually prefer the compiler to handle the casting versus templates to cut down on template instantiation bloat. I wonder how D scales to 100 MLOC programs as the template instantiations can be troublesome already in 1000 LOC programs. It scales to a few hundred kLoC if you don't abuse templates (too much) and sacrifice your firstborn to OPTLINK. I don't know what's further, perhaps a hecatomb would do. On a more serious note, the number of template instantiations will probably be more of the logarithmic kind with respect to LoC count. Unless you do everything in a generic way. But writing this sort of code is a major PITA and often a waste of time. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Re: Is typedef an alien?
On Thu, Sep 24, 2009 at 2:36 PM, Aenigmatic proc...@adam-dott-com.au wrote: No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? It's a different beast, and in my experience, pretty useless. Most of the time you want typedef'ed types to interact with other types a little more richly. Say you want to use a double as a time. Okay, what do you get when you subtract two points in time? Not a time, that's for sure. You get a time _span_ instead. So you end up implementing them as structs. Virtually every time I've tried to use typedef, it hasn't sufficed and I've ended up using a struct instead. It seems like a failed idea, or at the very least, yet another half-thought-out abandoned feature.
resolveProperties (dmd hacking)
I'm spending some of my spare time implementing expression rewriting for properties. One thing I've noticed that bugs me is how resolveProperties is scattered all over the place in statement.c and expression.c. I'm wondering why it's called so zealously. It bugs me because I'm worried that read properties can be generated by some of the semantic analysis code after I've already done my rewrites. I want to do my rewrite before properties are resolved, and at the same time this must be done in CompoundStatement::semantic(...) since I need the parent compound statement of any expression being rewritten. If there was some kind of block expression type (CompoundExpression?) that defined ordered execution of expressions within another expression, then I wouldn't need parent CompoundStatements at all. I haven't noticed such a beast in the sources though, and I suspect that implementing one would involve some backend hacks that I don't want to risk. For now I'll move ahead on the assumption that read properties aren't going to pop out of nowhere after I've done my thing, but I would like to know if I'm going about this wrong or just inherited some significant refactoring work. Thanks, - Chad
Re: DFL IDE Editor ?
On Thu, 24 Sep 2009 14:21:55 -0400, dolive doliv...@sina.com wrote: Robert Jacques дµ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive DFL hasn't been updated to DMD 2.032 yet. I've updated my local copy. Here's the link: https://jshare.johnshopkins.edu/xythoswfs/webui/_xy-3615403_1-t_VRRBqZAG
Re: Is typedef an alien?
Thu, 24 Sep 2009 15:33:38 -0400, Jarrett Billingsley thusly wrote: On Thu, Sep 24, 2009 at 2:36 PM, Aenigmatic proc...@adam-dott-com.au wrote: No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? It's a different beast, and in my experience, pretty useless. Most of the time you want typedef'ed types to interact with other types a little more richly. Say you want to use a double as a time. Okay, what do you get when you subtract two points in time? Not a time, that's for sure. You get a time _span_ instead. So you end up implementing them as structs. Virtually every time I've tried to use typedef, it hasn't sufficed and I've ended up using a struct instead. It seems like a failed idea, or at the very least, yet another half-thought-out abandoned feature. I can imagine some uses for it when the type is very simple, and you fear that the compiler cannot inline operations on structs. Other than that, common mainstream language features like typedefs, variant!(), and enums are mere special cases of algebraic datatypes (with some implicit syntactic sugar). There are some downsides, too, but I prefer to have the more general type in languages that I use.
Re: resolveProperties (dmd hacking)
Chad J wrote: It bugs me because I'm worried that read properties can be generated by ... I forgot to clarify. I meant read property /calls/.
Re: resolveProperties (dmd hacking)
Chad J wrote: I'm spending some of my spare time implementing expression rewriting for properties. One thing I've noticed that bugs me is how resolveProperties is scattered all over the place in statement.c and expression.c. I'm wondering why it's called so zealously. It bugs me because I'm worried that read properties can be generated by some of the semantic analysis code after I've already done my rewrites. I want to do my rewrite before properties are resolved, and at the same time this must be done in CompoundStatement::semantic(...) since I need the parent compound statement of any expression being rewritten. If there was some kind of block expression type (CompoundExpression?) that defined ordered execution of expressions within another expression, then I wouldn't need parent CompoundStatements at all. I haven't noticed such a beast in the sources though, and I suspect that implementing one would involve some backend hacks that I don't want to risk. For now I'll move ahead on the assumption that read properties aren't going to pop out of nowhere after I've done my thing, but I would like to know if I'm going about this wrong or just inherited some significant refactoring work. Thanks, - Chad Is CommaExp what you are looking for?
Re: Is typedef an alien?
Thu, 24 Sep 2009 19:44:09 +, language_fan thusly wrote: Thu, 24 Sep 2009 15:33:38 -0400, Jarrett Billingsley thusly wrote: On Thu, Sep 24, 2009 at 2:36 PM, Aenigmatic proc...@adam-dott-com.au wrote: No further response to any responses to my previous post's responses is a both swift and non-invasive. Now my deeply thought question is ... Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? It's a different beast, and in my experience, pretty useless. Most of the time you want typedef'ed types to interact with other types a little more richly. Say you want to use a double as a time. Okay, what do you get when you subtract two points in time? Not a time, that's for sure. You get a time _span_ instead. So you end up implementing them as structs. Virtually every time I've tried to use typedef, it hasn't sufficed and I've ended up using a struct instead. It seems like a failed idea, or at the very least, yet another half-thought-out abandoned feature. I can imagine some uses for it when the type is very simple, and you fear that the compiler cannot inline operations on structs. Other than that, common mainstream language features like typedefs, variant!(), and enums are mere special cases of algebraic datatypes (with some implicit syntactic sugar). There are some downsides, too, but I prefer to have the more general type in languages that I use. If I recall correctly, one of the reasons that also make typedefs in D a bit more useless is the inconsistency in implicit casts. E.g. when you create a temperature type, I think some of the conversions between floats, Temperature, and literals fail.
Re: .init property for char[] type
Justin Johansson wrote: Seriously though, I imagine the D design choices to be influenced by the desire to propagate NaN and invalid UTF in their respective cases so as to detect uninitialized data errors. That's exactly what drove the design choices. If there was a nan value for integers, D would use that. But there isn't, so 0 is the best we can do. Andrei and I were talking last night about the purity of software design principles and the reality, and how the reality forces compromise on the purity if you wanted to get anything done.
Re: Rich Hickey's slides from jvm lang summit - worth a read?
Walter Bright: Executive summary: pure functions and immutable data structures help manage program complexity. At the moment in D there aren't many immutable data structures available, but of course they can be written. Such data structures often put the GC under some/high pressure. I don't know if the current D GC is able to cope. Bye, bearophile
Re: should protected imply package?
On Thu, 24 Sep 2009 23:36:46 +0400, Jarrett Billingsley jarrett.billings...@gmail.com wrote: On Thu, Sep 24, 2009 at 1:38 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: In Java, protected-level protection implies package-level protection (see e.g. http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html). Should we copy that behavior in D, or take advantage of the package keyword and require it as in package protected? Under the current implementation, if protected implied package, all protected methods would suddenly become nonvirtual, since for some reason, package is treated as a kind of 'private'. Not really what you'd want, I think ;) 'package' should not conflate visibility and virtuality. If it didn't do that, having protected imply package would be just fine. Can't agree more!
Re: Why not move cast to the standard library?
downs wrote: Jeremie Pelletier wrote: downs wrote: Jeremie Pelletier wrote: grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie What about cast!int could _not_ be done as a function? I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives. What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :) Compile with -debug -unittest -g and you get no inlines whatsoever, even const values aren't inlined, when I run such an executable in windbg the code cursor actually goes to the declaration of enums and other constants. A lot of casts are just type reinterpretations, with a few semantics behind float to int conversions. I wouldn't give away the convenience of cast() to force everything through to!(T)(). I use cast() for most cases where I don't need anything special, and to!(T)() when I need some specific semantics. It also makes such cases much easier to notice when reading code.
Re: DFL IDE Editor ?
Robert Jacques дµ½: On Thu, 24 Sep 2009 14:21:55 -0400, dolive doliv...@sina.com wrote: Robert Jacques ôµ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive DFL hasn't been updated to DMD 2.032 yet. I've updated my local copy. Here's the link: https://jshare.johnshopkins.edu/xythoswfs/webui/_xy-3615403_1-t_VRRBqZAG yes, I use DFL is dmd2.032, Scintilla DFL Control version is older, is 2007 year. hope upgraded to dmd2.032 . how to make lib ? I use makescintillalib.bat is error, I copyed cpp directory to DFL directory. changed dmd_path, dmc change to dmd. can be compiled out .obj file. thank you ! dolive
Re: DFL IDE Editor ?
Robert Jacques дµ½: On Thu, 24 Sep 2009 14:21:55 -0400, dolive doliv...@sina.com wrote: Robert Jacques ôµ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive DFL hasn't been updated to DMD 2.032 yet. I've updated my local copy. Here's the link: https://jshare.johnshopkins.edu/xythoswfs/webui/_xy-3615403_1-t_VRRBqZAG I use's DFL version is your version, thank you very much ! dolive
Re: resolveProperties (dmd hacking)
Ary Borenszweig wrote: Is CommaExp what you are looking for? That seems to be exactly what I'm looking for. I did not know CommaExp did that. This is most excellent. Now I can just integrate my code into resolveProperties and be fairly certain that everything will work out. Thank you!
Re: Rich Hickey's slides from jvm lang summit - worth a read?
Walter Bright wrote: Executive summary: pure functions and immutable data structures help manage program complexity. I think so too, but you left out the time and identity part related to stm and multiversion concurrency. You could argue these notions are a possible consequence of immutable data structures and pure functions. But the time thingy somehow seems more fundamental than that. Anyhow it nicely hints at what we can do with these concepts. It seems to me that this is the fundamental part of functional programming, and not functions as first class citizens. This is also the part that most modern languages that claim to be hybrid OO / functional do not support.
Re: DFL IDE Editor ?
Robert Jacques дµ½: On Thu, 24 Sep 2009 14:21:55 -0400, dolive doliv...@sina.com wrote: Robert Jacques ôµ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive DFL hasn't been updated to DMD 2.032 yet. I've updated my local copy. Here's the link: https://jshare.johnshopkins.edu/xythoswfs/webui/_xy-3615403_1-t_VRRBqZAG Compiling D Scintilla for DFL... D:\D\dflD:\D\dmd2\windows\bin\dfl -c -debug -O -inline -I.. scintilla Error checking versions; use switch -ver for details D:\D\dmd2\windows\bin\dmd.exe -c -debug -O -inline -I.. scintilla -version=DFL_E XE -ID:\D\dmd2\windows\import -L/exet:nt/su:console:4.0 D:\D\dmd2\windows\lib\DF L_DE~1.LIB scintilla.d(212): Error: function dfl.scintilla.Scintilla.text does not override any function scintilla.d(228): Error: function dfl.scintilla.Scintilla.text of type char[]() overrides but is not covariant with dfl.control.Control.text of type immutable(c har)[]() scintilla.d(228): Error: function dfl.scintilla.Scintilla.text does not override any function scintilla.d(250): Error: function dfl.scintilla.Scintilla.selectedText does not override any function scintilla.d(259): Error: function dfl.scintilla.Scintilla.selectedText of type c har[]() overrides but is not covariant with dfl.textbox.TextBoxBase.selectedText of type immutable(char)[]() scintilla.d(259): Error: function dfl.scintilla.Scintilla.selectedText does not override any function Returned status code 1 D:\D\dflD:\D\dmd2\windows\bin\dfl -c -debug -O -inline -I.. -odcpp cpp\scintill a cpp\scilexer Error checking versions; use switch -ver for details D:\D\dmd2\windows\bin\dmd.exe -c -debug -O -inline -I.. -odcpp cpp\scintilla cpp \scilexer -version=DFL_EXE -ID:\D\dmd2\windows\import -L/exet:nt/su:console:4.0 D:\D\dmd2\windows\lib\DFL_DE~1.LIB Making libs... D:\D\dflD:\D\dm\bin\lib -c -n -p32 dflscintilla.lib scintilla cpp\scintilla cpp \scilexer Digital Mars Librarian Version 8.02n Copyright (C) Digital Mars 2000-2007 All Rights Reserved http://www.digitalmars.com/ctg/lib.html Error: scintilla.obj : No such file or directory Failed. Done. makescintillalib.bat: @rem Make Scintilla interface for D. @rem http://www.dprogramming.com/dfl.php @echo off @cls @rem Either set the environment variables dmd_path and dmc_path @rem or fix the paths below. if not %dmd_path% == goto dmd_set set dmd_path=D:\D\dmd2\windows :dmd_set if not %dmc_path% == goto dmc_set set dmc_path=D:\D\dm :dmc_set if %SCINTILLA_STATIC_BUILD% == goto done_static set _SCINTILLA_STATIC_BUILD=-version=SCINTILLA_STATIC_BUILD :done_static @echo on @rem Compile: @echo Compiling D Scintilla for DFL... @rem -version=NO_DRAG_DROP -version=NO_MDI %dmd_path%\bin\dfl -c -debug -O -inline -I.. %_SCINTILLA_STATIC_BUILD% scintilla @if errorlevel 1 goto oops %dmd_path%\bin\dfl -c -debug -O -inline -I.. -odcpp cpp\scintilla cpp\scilexer @if errorlevel 1 goto oops @echo. @rem Make lib file: @echo Making libs... %dmc_path%\bin\lib -c -n -p32 dflscintilla.lib scintilla cpp\scintilla cpp\scilexer @if errorlevel 1 goto oops @echo. @goto done :oops @echo Failed. :done @echo Done. thank you ! dolive
Re: Rich Hickey's slides from jvm lang summit - worth a read?
Walter Bright: Executive summary: pure functions and immutable data structures help manage program complexity. There's something missing in most of the articles I've read that praise pure functions and immutable data structures. When I write a 500-lines long Python program I often start using almost pure data structures and pure functions, they help me avoid bugs and keep things tidy. Then if the performance is good enough I may stop (I add more tests, docs, etc). If the performance isn't good enough I often profile the code and (beside trying to improve algorithms and data structures, catching and pre-processing, etc), I also sometimes reduce the purity of some performance critical functions/methods and change the code in some spots so it modifies some big data structures in place, to avoid repeated allocations and reduce GC activity. This speeds up the code. I'd like a language that helps me perform such changes from almost purity to a code that in certain spots is less functional/pure. I'd like such language to give me quick ways to go back to a more pure code, to help me modify/debug the code further, because during program design or during debugging purity/immutability help. But once I have optimized my Python code, I have lost some of such simplicity, and it requires work if you want to go back to a more pure code to perform more debugging/code improvements. I think such ideas may be applied to D programs too. Bye, bearophile
Re: DFL IDE Editor ?
On Thu, 24 Sep 2009 16:31:56 -0400, dolive doliv...@sina.com wrote: Robert Jacques дµ½: On Thu, 24 Sep 2009 14:21:55 -0400, dolive doliv...@sina.com wrote: Robert Jacques Ã�´µ½: On Thu, 24 Sep 2009 06:22:57 -0400, dolive89 doliv...@sina.com wrote: can DFL make ide editor ? can do expansion of the corresponding function? Yes. There's the Entice IDE (http://www.dprogramming.com/entice.php) Or the simpler DCode IDE(http://www.dprogramming.com/dcode.php) Or the Scintilla control if you want to roll your own (http://wiki.dprogramming.com/Dfl/ScintillaControl) thank you very much !!! but version is older,can do be upgraded to dmd2.032 ? thank you !!! dolive DFL hasn't been updated to DMD 2.032 yet. I've updated my local copy. Here's the link: https://jshare.johnshopkins.edu/xythoswfs/webui/_xy-3615403_1-t_VRRBqZAG yes, I use DFL is dmd2.032, Scintilla DFL Control version is older, is 2007 year. hope upgraded to dmd2.032 . how to make lib ? I use makescintillalib.bat is error, I copyed cpp directory to DFL directory. changed dmd_path, dmc change to dmd. can be compiled out .obj file. thank you ! dolive Sorry, I've never used the Scintilla control myself. If you just want to make DFL there is a makelib.bat file in the dfl directory.
Re: DFL IDE Editor ?
Compiling D Scintilla for DFL... D:\D\dflD:\D\dmd2\windows\bin\dfl -c -debug -O -inline -I.. scintilla Error checking versions; use switch -ver for details D:\D\dmd2\windows\bin\dmd.exe -c -debug -O -inline -I.. scintilla -version=DFL_E XE -ID:\D\dmd2\windows\import -L/exet:nt/su:console:4.0 D:\D\dmd2\windows\lib\DF L_DE~1.LIB scintilla.d(212): Error: function dfl.scintilla.Scintilla.text does not override any function scintilla.d(228): Error: function dfl.scintilla.Scintilla.text of type char[]() overrides but is not covariant with dfl.control.Control.text of type immutable(c har)[]() scintilla.d(228): Error: function dfl.scintilla.Scintilla.text does not override any function scintilla.d(250): Error: function dfl.scintilla.Scintilla.selectedText does not override any function scintilla.d(259): Error: function dfl.scintilla.Scintilla.selectedText of type c har[]() overrides but is not covariant with dfl.textbox.TextBoxBase.selectedText of type immutable(char)[]() scintilla.d(259): Error: function dfl.scintilla.Scintilla.selectedText does not override any function Returned status code 1 D:\D\dflD:\D\dmd2\windows\bin\dfl -c -debug -O -inline -I.. -odcpp cpp\scintill a cpp\scilexer Error checking versions; use switch -ver for details D:\D\dmd2\windows\bin\dmd.exe -c -debug -O -inline -I.. -odcpp cpp\scintilla cpp \scilexer -version=DFL_EXE -ID:\D\dmd2\windows\import -L/exet:nt/su:console:4.0 D:\D\dmd2\windows\lib\DFL_DE~1.LIB Making libs... D:\D\dflD:\D\dm\bin\lib -c -n -p32 dflscintilla.lib scintilla cpp\scintilla cpp \scilexer Digital Mars Librarian Version 8.02n Copyright (C) Digital Mars 2000-2007 All Rights Reserved http://www.digitalmars.com/ctg/lib.html Error: scintilla.obj : No such file or directory Failed. Done. makescintillalib.bat: @rem Make Scintilla interface for D. @rem http://www.dprogramming.com/dfl.php @echo off @cls @rem Either set the environment variables dmd_path and dmc_path @rem or fix the paths below. if not %dmd_path% == goto dmd_set set dmd_path=D:\D\dmd2\windows :dmd_set if not %dmc_path% == goto dmc_set set dmc_path=D:\D\dm :dmc_set if %SCINTILLA_STATIC_BUILD% == goto done_static set _SCINTILLA_STATIC_BUILD=-version=SCINTILLA_STATIC_BUILD :done_static @echo on @rem Compile: @echo Compiling D Scintilla for DFL... @rem -version=NO_DRAG_DROP -version=NO_MDI %dmd_path%\bin\dfl -c -debug -O -inline -I.. %_SCINTILLA_STATIC_BUILD% scintilla @if errorlevel 1 goto oops %dmd_path%\bin\dfl -c -debug -O -inline -I.. -odcpp cpp\scintilla cpp\scilexer @if errorlevel 1 goto oops @echo. @rem Make lib file: @echo Making libs... %dmc_path%\bin\lib -c -n -p32 dflscintilla.lib scintilla cpp\scintilla cpp\scilexer @if errorlevel 1 goto oops @echo. @goto done :oops @echo Failed. :done @echo Done. thank you ! dolive I don't think this Scintilla control has been made compatible with D2 yet. You can probably start by using string instead of char[]
Re: Why not move cast to the standard library?
Jeremie Pelletier wrote: downs wrote: Jeremie Pelletier wrote: downs wrote: Jeremie Pelletier wrote: grauzone wrote: Andrei Alexandrescu wrote: downs wrote: Andrei Alexandrescu wrote: downs wrote: With all the neat template tricks we have in 2.0, and since we're widely redefining the syntax anyway, why not deprecate the current cast syntax and move it into object.d as a library function? So instead of cast(Foo) bar; you would say cast!Foo(bar); .. save on a keyword and demonstrate language power at the same time. What sez ye? What would the implementation look like? Andrei Unions, and LOTS of static ifs. :) Unions won't work for casting class objects and interfaces because those do pointer adjustments. I think cast must be a primitive. When casting interfaces and objects, the primitive cast just calls into runtime (functions like _d_dynamic_cast etc.). I don't see a reason why cast implemented as templated function couldn't call those runtime functions directly. Andrei What about cast(int) or cast(string) and whatnot then? You'd have cast!A(B) for classes and cast(int) for values, that would be backwards. Jeremie What about cast!int could _not_ be done as a function? I don't want to call into functions for simple value casts. If I want safe casts I use to!int. It may get inlined in release code, but think of the debug overhead it would generate. The current way is great as it is, cast() for straightforward unsafe casting and to!(T)() for safe casting. This is exactly what makes D attractive to me, the choice between safe and unsafe alternatives. What debug overhead? With current casts, all the logic is in the compiler - where you can't get at it. Moving it into the library can only make this better. There is nothing about cast that I can see that requires dedicated compiler assistance. Furthermore, consider it a testcase - if a trivial function like that isn't inlined, _something_ is wrong :) Compile with -debug -unittest -g and you get no inlines whatsoever, even const values aren't inlined, when I run such an executable in windbg the code cursor actually goes to the declaration of enums and other constants. A lot of casts are just type reinterpretations, with a few semantics behind float to int conversions. I wouldn't give away the convenience of cast() to force everything through to!(T)(). I use cast() for most cases where I don't need anything special, and to!(T)() when I need some specific semantics. It also makes such cases much easier to notice when reading code. Good argument. Thanks.
Re: Rich Hickey's slides from jvm lang summit - worth a read?
Thu, 24 Sep 2009 18:00:56 -0400, bearophile thusly wrote: Walter Bright: Executive summary: pure functions and immutable data structures help manage program complexity. There's something missing in most of the articles I've read that praise pure functions and immutable data structures. When I write a 500-lines long Python program I often start using almost pure data structures and pure functions, they help me avoid bugs and keep things tidy. Then if the performance is good enough I may stop (I add more tests, docs, etc). If the performance isn't good enough I often profile the code and (beside trying to improve algorithms and data structures, catching and pre-processing, etc), I also sometimes reduce the purity of some performance critical functions/methods and change the code in some spots so it modifies some big data structures in place, to avoid repeated allocations and reduce GC activity. This speeds up the code. Well, there are type and effect systems that allow in-place modifications without breaking the type rules, but many common functional languages just do not use these systems. If you break free from the safe part of the language, it is like driving a car without seat belt and/or brakes. If you are a hardcore professional, you know how to avoid some of the dangers, but often it is not possible to avoid them all. Static type checking has a crucial property: it can prove some properties (like the absence of some errors) without decreasing the runtime performance. Another alternative are the unit tests, but no matter how many tests you add to your test suite, you can never prove the absence of errors, only their presence. Switching to Python is in one way a step in the wrong direction - you lose something you already had for free - instead you need to emulate it with tons of additional unit tests to achieve acceptable levels of quality. Type systems, like the pure data structures, have their roots in formal logic. I recommend taking a cursory look at the history of types. It all started in 1870s, and even though there were functional languages like Lisp already in 1970, it was only then that someone (Reynolds, Milner) came up with modern concepts like polymorphisms. E.g. the type system for stuff like int get_length_of_a_list(T)(List!(T) list); was invented in the 70s. Lisp could not provide this kind of safety for lists, there was only the core stuff for lambda calculus ready back then. As another example I could mention typesafe printf that was invented in the 80s. The good thing is, some serious advancements have happened since then, but more is definitely yet to come. It would be foolish to think that functional languages have somehow remained stagnant since the introduction of Lisp. On the contrary, the mainstream C-like languages have refused to take advantage of type systems developed in the 90s or in the 21th century. Now that multi-cores are becoming the norm, a lot of research is happening also on that domain.
Re: override(T)
Max Samukha wrote: On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu l...@lunesu.remove.com wrote: Daniel Keep wrote: Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places. I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud. C# uses familiar syntax to qualify the function name. I think it's natural enough. Making it look like C# has bad sides too. Explicit overriding in C# always hides the member from the public view. So this like C# can easily backfire. According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces. OK, but then we'll have to copy the other behavior as well: allowing explicit overrides and any non-explicit overrides will implement the matching interfaces that have not already been explicitly overridden. L.
Re: Pure dynamic casts?
Wed, 23 Sep 2009 15:09:59 +1000, Daniel Keep thusly wrote: See, people equate parallel execution with threads these days which is half the problem. Threads are a TERRIBLE abstraction, because they don't. There's no protection. Almost every time I express the opinion that threads are broken, people automatically assume I think we should all go back to single-core machines and cooperative multitasking. Threads come up every once in a while since they are one of the only ways to implement concurrency on the hardware level of shared memory machines. Another alternative is message passing. There just are no intelligent, dynamic low level models that provide e.g. abstractions and protection. Once you realize this, the only way to build safe concurrent systems is to provide a safe high level abstraction on top of the hardware and transform programs written using this abstraction to use low level threads and messages. As the amount of concurrent threads keeps increasing, you start to value models that prevent things like deadlocks, starvation, and accidental concurrent writes to the same location.
Re: Pure dynamic casts?
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. Shared data is always faster than message passing so you could implement real time code with it, and use messsage passing for other parts such as delegating GUI messages from the main loop. Shared data is maybe faster on shared memory machines, but this is not a fact in the general case. Shared data being harder to manage than message passing does not make it a bad thing, it just means you can have two different models for two different usages. Shared data is not a single homogenous model. Things like transactional memory work in shared memory systems, but still they have different semantics.
Re: Pure dynamic casts?
Fri, 25 Sep 2009 00:10:55 +, language_fan thusly wrote: 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. Imagine if a buggy C++ program was monitoring your health. If it crashed or corrupted data, you would die. Yes, the C++ code would be $1M cheaper to build and the hardware would also be $100K cheaper (overall $10M vs $8.9M), but people would die 95% more often. Or in banking business the systems would handle 4x as much customers and transactions, but unfortunately some transactions would just go to the bit heaven due to the 5-6 reboots the mainframe required daily.
Re: override(T)
Lionello Lunesu wrote: Andrei Alexandrescu wrote: Max Samukha wrote: On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu l...@lunesu.remove.com wrote: Daniel Keep wrote: Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places. I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud. C# uses familiar syntax to qualify the function name. I think it's natural enough. Making it look like C# has bad sides too. Explicit overriding in C# always hides the member from the public view. So this like C# can easily backfire. According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces. ++andreis_suggestion; I give my vote to C#'s syntax if D can adopt it. L. Yah. My take is that if we depart from familiarity, we ought to have a pretty darn good reason. I didn't know C# has the feature. Since it does with a reasonable notation, I'd say let's go for it. Andrei Be careful with that reasoning. What about attributes? Properties? What about C# var vs. D auto? C# using vs. D import? In fact, what about the standard library? I didn't say we need to do what C# does in particular. auto and import have precedents in other languages. A standard library is too large to copy wholesale. For myself, when learning a new programming language 10% of my time is spent on learning the language syntax and 90% on learning the standard library. Learning override(A) B vs. override A.B is NOP. Then I take it you wouldn't mind override A.B :o). Andrei
Re: Pure dynamic casts?
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. 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). Shared data is always faster than message passing so you could implement real time code with it, and use messsage passing for other parts such as delegating GUI messages from the main loop. Shared data is maybe faster on shared memory machines, but this is not a fact in the general case. Shared data being harder to manage than message passing does not make it a bad thing, it just means you can have two different models for two different usages. Shared data is not a single homogenous model. Things like transactional memory work in shared memory systems, but still they have different semantics. Yes, I am well aware of that, I don't want to favor any particular design, I prefer to learn the semantics of a few of them and implement them all. Then I get the choice of the model to use depending on my needs. Take search algorithm for example, you can pick between a binary search, b-tree r-tree, quadtree, octree, bsp, and a bunch of others along with dozens of variants of the ones mentionned depending on the data you're working with. Its the same for concurrency, I can think of vector processing, functional calls, STM, message passing and shared memory off the top of my head. All being valid models with each their pros and cons, together forming a complete all-around solution. Jeremie
Re: Pure dynamic casts?
On Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier jerem...@gmail.com wrote: [snip] Its the same for concurrency, I can think of vector processing, functional calls, STM, message passing and shared memory off the top of my head. All being valid models with each their pros and cons, together forming a complete all-around solution. Jeremie Don't forget task-based or lock-free.
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: Rich Hickey's slides from jvm lang summit - worth a read?
Thu, 24 Sep 2009 21:41:00 -0400, bearophile thusly wrote: language_fan: [lot of stuff...] Switching to Python is in one way a step in the wrong direction - you lose something you already had for free - [lot of stuff...] I know several languages but I'm usually able to write correct Python programs ( 10_000 lines long) in less time than in other languages. So what you say doesn't agree with my practical experience. (For bigger programs, or other kind of programs, or other programmers, the situation may differ). (And that post was not about Python). Agreed, without statistical facts these opinions are too subjective to draw any kinds of conclusions. I have tried Python several times and each time came back to statically typed languages where I can first define interfaces, types, invariants, automatic tests, and only after that write the code. Most modern languages come with a REPL so I do not feel like missing anything. Maybe my brain just is not wired to be used with Python. Languages like Haskell and Scala have been most useful to me for exploratory coding because of their lightweight syntax. It is easy to see that class Foo[A](var a: A) is shorter than template typename A class Foo { private: A *a; public: void setA(const A a) { this.a = a; } A *getA() const { return a; } }; In fact I am sure the C++ example above is so full of all kinds of bugs that I will not comment on this any further. When I write a sketch of a new project, I usually write 1000 - 2000 lines of information about the overall structure and types. I have not found any constructs except the comments in Python to achieve this. Maybe I am developing in a wrong way.
Re: Pure dynamic casts?
Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier thusly 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. The cost of e.g. doubling computing power depends on the domain. If you are building desktop end user applications, they usually should scale from single core atoms to 8-core high-end enthusiastic game computers. So the cpu requirements shouldn't usually be too large. Usually even most of the 1-3 previous generations' hardware runs them just nicely. Now doubling the cpu power of a low-end current generation PC does not cost $1000, but maybe $20-50. You can continue this until the cpu costs about $400-500. By then you've achieved at least tenfold speedup. On the gpu market the cheapest chips have very limited capabilities. You can buy 5 times faster graphics cards for $50-60. $150-160 will get you a 25 times faster gpu than the first one. 4..8 GB RAM is also really cheap these days, and so is a 1.5 TB hard drive. Hardly any desktop program requires that much from the hardware. The 15% or even 50% slower execution speed seems rather small a problem when you can avoid it by buying faster hardware. Hardly any program is cpu bound, not even the most demanding games are. On the server side many systems use php which is both unsafe and slow. If you have decent load balancing and cache systems, it does not even matter since the system may not be cpu bound, either. Even top10 popular sites like wikipedia run on slow php.
Re: Pure dynamic casts?
On Thu, 24 Sep 2009 20:59:23 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Robert Jacques wrote: On Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier jerem...@gmail.com wrote: [snip] Its the same for concurrency, I can think of vector processing, functional calls, STM, message passing and shared memory off the top of my head. All being valid models with each their pros and cons, together forming a complete all-around solution. Jeremie Don't forget task-based or lock-free. Oh yeah, thanks! Those were covered by Bartosz in his blog right? I think he used the term Actor for task based programming, I really enjoyed reading these articles. There are many things called Actors, but they generally boil down to a process/thread/object + message passing. It's a good model, particularly for the cloud. Task programming is generally intra-process and works on the level of a single work-task (aka function). Cilk, futures or Intel's Threading Building Blocks are the canonical examples. The nice thing (I think) about a good work-stealing runtime is that it can provide the back-end for CPU-vector processing, tasks/futures, intra-process actors and functional calls.
Re: Pure dynamic casts?
Christopher Wright wrote: 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. I agree with you about web applications, scripting languages are fast enough to serve web pages in most cases. However I did see some pretty ugly code which took over a minute to generate a page from a 1.5Gb database using only string fields without any indexes and PHP was throwing more notices and warnings than actual html. I was referring to desktop applications, where you can't just buy a second server to host your database and serve static content like images and whatnot. From the 2 years I worked in tech support the problem I saw the most often was computers slowed down to a crawl, many of them without viruses or spywares. There are so many people who upgrade their computer just so they can run new software that really doesn't have many new features, but just is written in a safer language. That 15% performance hit over all the programs they ran at once was just too much for their old processor, when 2 months ago before they upgraded the software it was working just fine. Live messenger should not take half a minute to load and perform poorly when the old msn messenger was running perfectly fine. 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. rant What happened to one man armies like John Carmack and Tim Sweeney? These were the guys who inspired me to get into coding in the first place. I just loved how they could put together entire engines on their own and carefully optimize them. What about Walter who wrote the first C++ compiler and optlink as well as dmd from which I learned so much about compiler internals, or Andrei and his extensive work on meta programming and generic programming, from which I also learned so much. There's also that one guy developing the game LOVE all on his own using only C, he wrote his tools, his engine, his model
Re: Pure dynamic casts?
Robert Jacques wrote: On Thu, 24 Sep 2009 20:59:23 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Robert Jacques wrote: On Thu, 24 Sep 2009 20:46:13 -0400, Jeremie Pelletier jerem...@gmail.com wrote: [snip] Its the same for concurrency, I can think of vector processing, functional calls, STM, message passing and shared memory off the top of my head. All being valid models with each their pros and cons, together forming a complete all-around solution. Jeremie Don't forget task-based or lock-free. Oh yeah, thanks! Those were covered by Bartosz in his blog right? I think he used the term Actor for task based programming, I really enjoyed reading these articles. There are many things called Actors, but they generally boil down to a process/thread/object + message passing. It's a good model, particularly for the cloud. Task programming is generally intra-process and works on the level of a single work-task (aka function). Cilk, futures or Intel's Threading Building Blocks are the canonical examples. The nice thing (I think) about a good work-stealing runtime is that it can provide the back-end for CPU-vector processing, tasks/futures, intra-process actors and functional calls. I think the best way to deal with actors is by making them objects. Binding them to heavyweight kernel structures such as threads and processes will greatly limit the number of concurrent actors you can execute at once. Tasks would be most likely implemented by async methods, since you don't care about knowing when they're done. On the other hand, futures are there when you need an async call and monitor its completion. A good implementation could therefore easily support tens of thousands of concurrent actors. I must admit its the first time I hear about work-stealing, I will need to do some research on that :)
Re: Is typedef an alien?
Aenigmatic wrote: Is typedef (in D) a C/C++ legacy or is the dear orphan now adopted as a first-class citizen in the US of D? typedef in D is a new feature not found in C or C++. The typedef from C/C++ has been renamed to alias and extended to non-types in D. -- Rainer Deyke - rain...@eldwood.com
Re: override(T)
Lionello Lunesu wrote: Be careful with that reasoning. What about attributes? Properties? What about C# var vs. D auto? C# using vs. D import? In fact, what about the standard library? I wouldn't wind at all if D copied more from C#, and I don't even like C#. A natively compiled C# with extra features would be much more useful (and much easier to sell) than yet another incompatible object-oriented C variant. -- Rainer Deyke - rain...@eldwood.com