Re: Treat memory as a file with a name.
If it's the same librsvg as below, then it looks like it has an API function which can also load a SVG from memory: https://developer.gnome.org/rsvg/2.40/RsvgHandle.html#rsvg-handle-new-from-data To answer your original question, I think the best way to do this is to create a pipe on the filesystem. Once created, you can feed data through it without touching the disk. Thanks Vladimir, My librsvg is 2.36, but rsvg-handle-new-from-data pre-dates that, so it should be good. Thanks for the link - I had clearly been looking at some crap documentation. Thanks for the pipe idea too - it will come in handy one day, and I'd completely forgotten about pipes. Steve
Why does object creation give segmentation fault in DLL?
I have written a DLL file in Linux (x86_64). It is as below: File: lib.dll = class A{} extern(C) void foo(){ Object obj = new Object(); // test 1 A objA = new A(); // test 2 char[] c = new char[ 1024 ]; // test 3 } Compilation code is below: dmd -c lib.d -fPIC -debug gcc --shared lib.o -o lib.so Output of programme is like that: library is loaded now foo() function is found unloading libdll.so Segmentation fault (core dumped) Situation is that if either only the `test 1` or `test 3` code is available in the function, there is no error at all. But once I use `test 2` code, it starts giving segmentation fault. Please notice that both `test 1` and `test 2` are creating an object already. And all of them allocates memory with `new` keyword. But only the `test 2` fails. Why is this happening?
Re: Why does object creation give segmentation fault in DLL?
On Saturday, 22 February 2014 at 09:09:42 UTC, Tolga Cakiroglu wrote: I have written a DLL file in Linux (x86_64). It is as below: File: lib.dll = class A{} extern(C) void foo(){ Object obj = new Object(); // test 1 A objA = new A(); // test 2 char[] c = new char[ 1024 ]; // test 3 } Compilation code is below: dmd -c lib.d -fPIC -debug gcc --shared lib.o -o lib.so Output of programme is like that: library is loaded now foo() function is found unloading libdll.so Segmentation fault (core dumped) Situation is that if either only the `test 1` or `test 3` code is available in the function, there is no error at all. But once I use `test 2` code, it starts giving segmentation fault. Please notice that both `test 1` and `test 2` are creating an object already. And all of them allocates memory with `new` keyword. But only the `test 2` fails. Why is this happening? you should init runtime in library and set gc proxy for it(if implemented on linux, otherwise you would have two gc's running simultaneously) so add following methods to your lib. // lib side void initRT() { import core.runtime(); Runtime.initilize(); } extern(C) void gc_setProxy(void* p); void setGCProxy(void* gc) { gc_setProxy(gc); } // executable side extern(C) void* gc_getProxy(); void main() { // load lib here initRT(); setGCProxy(gc_getProxy()); // do stuff here... }
Re: Optimize my code =)
Hiho, as I used the ldmd wrapper for ldc2 I was able to use the same arguments given via the cmdfile. These were: -release -noboundscheck -O and -inline. Robin
Re: Why does object creation give segmentation fault in DLL?
On Saturday, 22 February 2014 at 11:08:41 UTC, evilrat wrote: On Saturday, 22 February 2014 at 09:09:42 UTC, Tolga Cakiroglu wrote: I have written a DLL file in Linux (x86_64). It is as below: File: lib.dll = class A{} extern(C) void foo(){ Object obj = new Object(); // test 1 A objA = new A(); // test 2 char[] c = new char[ 1024 ]; // test 3 } Compilation code is below: dmd -c lib.d -fPIC -debug gcc --shared lib.o -o lib.so Output of programme is like that: library is loaded now foo() function is found unloading libdll.so Segmentation fault (core dumped) Situation is that if either only the `test 1` or `test 3` code is available in the function, there is no error at all. But once I use `test 2` code, it starts giving segmentation fault. Please notice that both `test 1` and `test 2` are creating an object already. And all of them allocates memory with `new` keyword. But only the `test 2` fails. Why is this happening? you should init runtime in library and set gc proxy for it(if implemented on linux, otherwise you would have two gc's running simultaneously) so add following methods to your lib. // lib side void initRT() { import core.runtime(); Runtime.initilize(); } extern(C) void gc_setProxy(void* p); void setGCProxy(void* gc) { gc_setProxy(gc); } // executable side extern(C) void* gc_getProxy(); void main() { // load lib here initRT(); setGCProxy(gc_getProxy()); // do stuff here... } After doing these, even without `test 2` segmentation fault started coming. I actually do not want to share GC between them right now.
Range Construction Pattern
Assumed I have the following code SysTime[] times; const n = 3; foreach (i; 0..n) times ~= Clock.currTime; is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal?
Re: Range Construction Pattern
On Saturday, 22 February 2014 at 12:29:11 UTC, Nordlöw wrote: Assumed I have the following code SysTime[] times; const n = 3; foreach (i; 0..n) times ~= Clock.currTime; is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal? What's Clock.currTime exactly, a function? -- times = iota(3).map!(x = Clock.currTime).array; --
Re: Is there kind of associative tuple - like syntax in D?
On 02/21/14 18:57, Uranuz wrote: In my template functions, classes it's necessary to write variadic template parameter list, where elements are options to this class/function changing it's behaviour. But they are optional and may be not set at all. These options may be folowed by variadic template parameter list that will be processed in static foreach loop. What I'm thinking about is creating some sort of key-value tuple syntax like in associative arrays. For example I could set components or options of my template in easy-to-read manner. You could wrap all the options in special types, as already suggested. If you don't want to do that, and only need them to affect /local/ behavior, something like this will work: class Foo(string OPTS, A...) { private static { auto _getOpts() { struct O { byte opt1; string opt2 = def; bool b; string[string] extra; } struct ON { mixin(enum ~OPTS~;); } O o; foreach (N; __traits(allMembers, ON)) mixin(o. ~N~ = ON. ~N~;); return o; } enum opts = _getOpts(); auto _getExtra(K)(K k) { if (auto p = k in opts.extra) return *p; return null; } } static if (opts.opt19) { /*...*/ pragma(msg, opts.opt1); } static if (opts.b opts.opt2!=def) { /*...*/ pragma(msg, opts.opt2); } static if (_getExtra(b)) { /*...*/ pragma(msg, opts.extra[b]); } /* handle 'A'... */ /*...*/ } void main() { alias MyFoo1 = Foo!q{opt1 = 42, opt2 = blah, b = true, extra = [a:b, b:c]}; alias MyFoo2 = Foo!(q{b = false}, MyFoo1, 3.14, etc); } Not ideal, but right now I can't think of a simpler solution, using today's D. artur
Re: Range Construction Pattern
On Saturday, 22 February 2014 at 12:40:42 UTC, Tobias Pankrath wrote: On Saturday, 22 February 2014 at 12:29:11 UTC, Nordlöw wrote: Assumed I have the following code SysTime[] times; const n = 3; foreach (i; 0..n) times ~= Clock.currTime; is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal? What's Clock.currTime exactly, a function? -- times = iota(3).map!(x = Clock.currTime).array; -- Great! See also: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416
Re: Range Construction Pattern
times = iota(3).map!(x = Clock.currTime).array; -- Ok here's my try so far: auto create(alias fun)(size_t n) { import std.range: iota, map; return n.iota.map!(n = fun); } Now what remains is to retstrict create to only take a fun with *no* input arguments and a non-void return. How do I do that?
Re: Range Construction Pattern
Great! See also: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416 I don't think that 'create' is a good name for a function, that basically lazily evaluates another function foo n times. Maybe std.range.repeat should have an overload that takes an alias to a callable, so you don't need this rather awkward use of iota.
Re: Range Construction Pattern
Now what remains is to retstrict create to only take a fun with *no* input arguments and a non-void return. How do I do that? With a template contraint. Not tested: import std.traits: isCallable, ParameterTypeTuple, ReturnType; auto create(alias fun)(size_t n) if (isCallable!fun ParameterTypeTuple!(fun).length == 0 !is(ReturnType!fun == void)) { import std.range: iota, map; return n.iota.map!(n = fun); }
Re: Range Construction Pattern
On Saturday, 22 February 2014 at 14:03:11 UTC, Philippe Sigaud wrote: Now what remains is to retstrict create to only take a fun with *no* input arguments and a non-void return. How do I do that? With a template contraint. Not tested: import std.traits: isCallable, ParameterTypeTuple, ReturnType; auto create(alias fun)(size_t n) if (isCallable!fun ParameterTypeTuple!(fun).length == 0 !is(ReturnType!fun == void)) { import std.range: iota, map; return n.iota.map!(n = fun); } Your solution with ParameterTypeTuple!(fun).length == 0 doesn't work here because currTime takes a defaulted argument. I believe we need a new std.trait, say arityMin, for this. Any ideas on how to implement that? Perhaps using __traits(compiles...? See also my update at: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416
Re: Range Construction Pattern
I believe we need a new std.trait, say arityMin, for this. Any ideas on how to implement that? Perhaps using __traits(compiles...? See also my update at: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416 In the meantime you can use an is-expression: -- int foo() { return 12; } void bar() { } void baz(int x) { } void main() { pragma(msg, is(typeof(foo()) == void)); pragma(msg, is(typeof(bar()) == void)); pragma(msg, is(typeof(baz()) == void)); } -- You can check if arbitrary code compiles with the if-typeof-delegate-trick: -- static if(is(typeof({ code} { // code compiles } --
Re: Range Construction Pattern
You can check if arbitrary code compiles with the if-typeof-delegate-trick: -- static if(is(typeof({ code} { // code compiles } -- Or with __traits(compiles, code), which better documents the intent.
Re: Range Construction Pattern
My try so far: import std.traits: isCallable, ReturnType, arity, ParameterTypeTuple; enum arityMin0(alias fun) = __traits(compiles, fun()); // new syntax in 2.064 auto repeat(alias fun)(size_t n) if (isCallable!fun arityMin0!fun !is(ReturnType!fun == void)) { import std.range: iota, map; return n.iota.map!(n = fun); }
Re: Range Construction Pattern
per.nordlow: My try so far: import std.traits: isCallable, ReturnType, arity, ParameterTypeTuple; enum arityMin0(alias fun) = __traits(compiles, fun()); // new syntax in 2.064 auto repeat(alias fun)(size_t n) if (isCallable!fun arityMin0!fun !is(ReturnType!fun == void)) { import std.range: iota, map; return n.iota.map!(n = fun); } For a nullary function, this solution is certainly OK: short and understandable. I found a way to parse an entire function param list, including default args, but I don't remember right now how I did that. Maybe by parsing 'fun.stringof' Maybe this exists in Phobos now? btw, I'd call this template 'apply', because repeat already exists in Phobos with a different use.
Re: Range Construction Pattern
btw, I'd call this template 'apply', because repeat already exists in Phobos with a different use. Good idea! I'll rename it. I have a pile of extensions to std.algorithm, std.traits, std.numeric, I'll pull some day when I get the time... /Per
Scalability in std.parallelism
In the following test code given below of std.parallelism I get some interesting results: when compiled as dmd -release -noboundscheck -O -inline -w -wi -wi ~/Work/justd/t_parallelism.d -oft_parallelism My scalability measures says the following 3.14159 took 221[ms] 3.14159 took 727[ms] Speedup 3.28959 -5.80829e+09 took 33[ms] -5.80829e+09 took 201[ms] Speedup 6.09091 Why do I get a larger speed for a simpler map function? Shouldn't it be the opposite? I've always read that the more calculations I perform on each memory access the better the speedup... Anyhow the speedups are great! I'm sitting on a Intel Quad core with 8 hyperthreads. Sample code follows: import std.algorithm, std.parallelism, std.range, std.datetime, std.stdio; void test1 () { immutable n = 100_000_000; immutable delta = 1.0 / n; auto piTerm(int i) { immutable x = (i - 0.5) * delta; return delta / (1.0 + x*x); } auto nums = n.iota.map!piTerm; // numbers StopWatch sw; sw.reset(); sw.start(); immutable pi = 4.0*taskPool.reduce!a+b(nums); sw.stop(); immutable ms = sw.peek().msecs; writeln(pi, took , ms, [ms]); sw.reset(); sw.start(); immutable pi_ = 4.0*std.algorithm.reduce!a+b(nums); sw.stop(); immutable ms_ = sw.peek().msecs; writeln(pi_, took , ms_, [ms]); writeln(Speedup , cast(real)ms_ / ms); } auto square(T)(T i) @safe pure nothrow { return i*i; } void test2 () { immutable n = 100_000_000; immutable delta = 1.0 / n; auto nums = n.iota.map!square; // numbers StopWatch sw; sw.reset(); sw.start(); immutable pi = 4.0*taskPool.reduce!a+b(nums); sw.stop(); immutable ms = sw.peek().msecs; writeln(pi, took , ms, [ms]); sw.reset(); sw.start(); immutable pi_ = 4.0*std.algorithm.reduce!a+b(nums); sw.stop(); immutable ms_ = sw.peek().msecs; writeln(pi_, took , ms_, [ms]); writeln(Speedup , cast(real)ms_ / ms); } void main () { test1(); test2(); }
Re: Range Construction Pattern
I have a pile of extensions to std.algorithm, std.traits, std.numeric, I'll pull some day when I get the time... I mean push...
hiding a class property behind a method
It seems to me that the following code should be illegal, but I am uncertain of it so I am posting here for a confirmation before I post it on bug tracker: http://dpaste.dzfl.pl/dae728734cc6 import std.stdio; class A { string x () { return A; }; } class B : A { override string x () { return B; }; } class C : A { string x = C; // should this be illegal? } void main () { A o1 = new B(); writeln(o1.x); // B A o2 = new C(); writeln(o2.x); // A }
Bug with references (no casting used)
Hi everyone, I was trying to get my vector struct to use extensively references for passing parameters and I found a subtle bug which make me lose a few hour. A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux) I think that the code is wrong and dmd does not recognize it: opBinary() allocates a struct on the stack which is then accepted by reference in opOpAssign. I'd like to know if currently there are correct ways to pass rvalue structs by reference or if I should pass everything by value and hope the compiler optimizes all reduntant copies.
Re: hiding a class property behind a method
On 02/22/2014 06:21 PM, luka8088 wrote: import std.stdio; class A { string x () { return A; }; } class B : A { override string x () { return B; }; } class C : A { string x = C; // should this be illegal? } void main () { A o1 = new B(); writeln(o1.x); // B A o2 = new C(); writeln(o2.x); // A } Just an addition. The following line shows the problem: writeln((cast(C)o2).x); // C
Re: hiding a class property behind a method
On 02/22/2014 09:21 AM, luka8088 wrote: It seems to me that the following code should be illegal, but I am uncertain of it so I am posting here for a confirmation before I post it on bug tracker: http://dpaste.dzfl.pl/dae728734cc6 import std.stdio; class A { string x () { return A; }; } class B : A { override string x () { return B; }; } class C : A { string x = C; // should this be illegal? } void main () { A o1 = new B(); writeln(o1.x); // B A o2 = new C(); writeln(o2.x); // A } The code uses the two objects through the A interface and x() is a virtual function on that interface. When the C interface is used then we get C.x, which happens to be hiding the x() function of the base class. It looks normal to me. Ali
Re: hiding a class property behind a method
On Saturday, 22 February 2014 at 17:41:58 UTC, Ali Çehreli wrote: The code uses the two objects through the A interface and x() is a virtual function on that interface. When the C interface is used then we get C.x, which happens to be hiding the x() function of the base class. It looks normal to me. Ali Spec is silent on this, so this is indeed a question. Actually A is not interface, so I don't understand why you mention it. And there is neither 'taking C interface' because static type is A, so A function is called, neither it hides function of the base class because it is base class function which is called. I don't understand you completely. AFAIK this feature exists for many years, at least 3, possibly roots to D1. What happens is follows: since there is no function, base class virtual is not replaced, so virtual table of C looks like A, so A member function is called. If example is modified, then import std.stdio; class A { //string x () { return A; }; string x = A; } class B : A { //override string x () { return B; }; string x = B; } class C : A { //string x = C; // should this be illegal? string x () { return C; } } void main () { A o1 = new B(); A o2 = new C(); writeln(o1.x); // A writeln(o2.x); //A } so it appears that data member have priority over function. Probably this should be filed as a spec or compiler bug.
Re: Bug with references (no casting used)
On Saturday, 22 February 2014 at 17:22:51 UTC, andrea9940 wrote: Hi everyone, I was trying to get my vector struct to use extensively references for passing parameters and I found a subtle bug which make me lose a few hour. A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux) I think that the code is wrong and dmd does not recognize it: opBinary() allocates a struct on the stack which is then accepted by reference in opOpAssign. I'd like to know if currently there are correct ways to pass rvalue structs by reference or if I should pass everything by value and hope the compiler optimizes all reduntant copies. Looks like compiler bug.
Re: Bug with references (no casting used)
On Saturday, 22 February 2014 at 17:22:51 UTC, andrea9940 wrote: Hi everyone, I was trying to get my vector struct to use extensively references for passing parameters and I found a subtle bug which make me lose a few hour. A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux) I think that the code is wrong and dmd does not recognize it: opBinary() allocates a struct on the stack which is then accepted by reference in opOpAssign. Clarifying: The bug is that opBinary returns a reference to a local (vector), which is invalid. I don't know if dmd should see that, as it's hidden behind a call. I'd like to know if currently there are correct ways to pass rvalue structs by reference or if I should pass everything by value and hope the compiler optimizes all reduntant copies. There isn't. But adding an overload that forwards to the ref version is trivial (as long as there's only one parameter): --- auto opOpAssign(string op)(const Vector rhs) if (op == + || op == -) { return opOpAssign!op(rhs); } --- I don't know if the ref even buys you anything performance-wise, though.
Build Hash from Array in one statement ?
Hello, Is there a way to quickly build a hash from the values of an array? A one-statement equivalent of: T[] array_values ; int[T] hash_values; hash_values = map!() (array_values) ; Instead of: for (v; array_values) { hash_values[v] = 1; } in Perl, that would be: %hash = map { $_ = 1 } @array; --- Or, put differently, is there a way to convert values in an array to keys of hash in one statement ? Thanks! -gordon
Re: Bug with references (no casting used)
On 02/22/14 18:22, andrea9940 wrote: I was trying to get my vector struct to use extensively references for passing parameters and I found a subtle bug which make me lose a few hour. A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux) I think that the code is wrong and dmd does not recognize it: opBinary() allocates a struct on the stack which is then accepted by reference in opOpAssign. That is ok; the problem is that opBinary returns a local stack-allocated object by reference. Make it return by value, and with some help from RVO you should get only one copy (which is necessary because you create a new Vector instance). IOW: Vector opBinary(string op)(T rhs) const; ref Vector opOpAssign(string op)(T rhs); ref Vector opOpAssign(string op)(auto ref const Vector rhs); artur
Re: Build Hash from Array in one statement ?
--- Or, put differently, is there a way to convert values in an array to keys of hash in one statement ? Thanks! -gordon std.array.assocArray. -- T[] keys; auto aa = zip(keys, repeat(true)).assocArray;
Re: hiding a class property behind a method
The code uses the two objects through the A interface and x() is a virtual function on that interface. [...] Ali The book Programming in D (r651) says in chapter 57.7 Using the subclass in place of the superclass, in the example about Clock and AlarmClock : void use(Clock clock) { ... } (sic) In other words, although use() uses the object as a Clock, the actual object may be an inherited type that behaves in its own special way. Should'nt we understand that the first object is a B, the second object is a C and then should both behave like a B and a C, not like two A ?
Re: Cannot implicitly convert derived type
On Saturday, 22 February 2014 at 01:03:22 UTC, Steven Schveighoffer wrote: On Fri, 21 Feb 2014 17:54:06 -0500, Frustrated c1514...@drdrb.com wrote: interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? What you are trying to do is not legal. e.g.: class RogueButton : iButton { } iGui gui = new WindowsGui; gui.button = new RogueButton; Note that setting gui.button to any iButton is legal, but the derived type REQUIRES a WindowsButton. This would have to be rejected at runtime, because the compile-time type is implicitly convertible. There are two types of variance that are logical, contravariance and covariance. covariance allows you to *return* a more derived type than the base. In other words, this would be legal (assume same iButton/WindowsButton structure): interface iGui { @property iButton button(); } class WindowsGui : iGui { @property WindowsButton button() {...}; } This works, because whenever you return a WindowsButton, you ALSO are returning an iButton. In fact, D supports this. The opposite is contravariance, and that's used on *input* parameters. In this case, the derived method can accept a base of the parameter that the base class defines: interface iGui { void button(WindowsButton); // please humor me, I know you don't want to do this :) } class WindowsGui : iGui { void button(iButton); } This is logically sound, because the actual implementation only requires an iButton. Therefore, passing a WindowsButton into the iGui interface still satisfies that requirement. However, D does NOT support contravariance. 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. This is actually the correct mechanism if you want to use polymorphism. However, in some cases, a templated system may be more advantageous than an interface system. One other possibility is to use overloading -- i.e.: class WindowsGui { @property WindowsButton button(WindowsButton b) { return _button = b;} @property WindowsButton button(iButton b) { if(auto wb = cast(WindowsButton)b) button = wb; else throw new ButtonException; } } This is not really an attractive solution, but it could be easily generated as a mixed-in solution. -Steve It is legal exactly because I will always guarantee that the proper button will be used. It is not logically legal as mentioned several times... no one needs to mention that. But it is legal within the context of the code. I'll never use a RogueButton so why force me to code for the chance I might? Again, WindowsGui only uses WindowsButton which is a iButton type. So why force me to always use iButton and cast it to WindowsButton? Why can't I relax the condition to use the base type? The only reason it is illegal is because I could use a RogueButton, BUT I WON'T! If I do, then it is an error. Basically, the point is, the compiler could enforce the above but make the code more readable. e.g., I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } One is very clean, the other is not. If by chance I use the wrong button(a Rogue button) then it results in an error(hopefully user controlled). One allows me to program in a natural way while the other makes me jump through hoops which litters the code with a bunch of casts and checks which are only there in the odd event that I assign the wrong type(which, I'm not going to do on purpose). Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could absolutely guarantee that I won't pass them then there should be no problem(no asserts). Since I can't guarantee it I have to litter my code with checks? The compiler could do this for me.
Re: Cannot implicitly convert derived type
On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote: Generic? I don't see how this would help. I'd have to specify every concrete type in the creation of the object which might be significant. I can't use a generic virtual method so that doesn't help either. It would be nice to have something like T foo(T : iButton)(T button); Which then I override with WindowsButton foo(WindowsButton button) { } Since WindowsButton is derived from iButton. The compiler would have to insert a type check to make sure when I called the first one(from the interface) that it was a windows button that was passed(since any iButton could be passed) when using the WindowsGui. The main point of all this is simply efficiency. I have to liter the code with checks and casts when it is entirely possible to get the compiler to automate it all. By doing so one can program the concrete class in a much more natural way.
Re: hiding a class property behind a method
On 02/22/2014 12:06 PM, Nynn007 wrote: The code uses the two objects through the A interface and x() is a virtual function on that interface. [...] Ali I agree. :) The book Programming in D (r651) says in chapter 57.7 Using the subclass in place of the superclass, in the example about Clock and AlarmClock : void use(Clock clock) { ... } (sic) In other words, although use() uses the object as a Clock, the actual object may be an inherited type that behaves in its own special way. I obviously agree with that as well. :) Should'nt we understand that the first object is a B, the second object is a C and then should both behave like a B and a C, not like two A ? You are correct. What I meant above is that the code uses the two object as two As, which involves the interface of A. The behaviors may be different. Ali
Re: hiding a class property behind a method
On 02/22/2014 10:00 AM, Maxim Fomin wrote: On Saturday, 22 February 2014 at 17:41:58 UTC, Ali Çehreli wrote: The code uses the two objects through the A interface and x() is a virtual function on that interface. When the C interface is used then we get C.x, which happens to be hiding the x() function of the base class. Sorry. I meant If the C interface is used, not When the. It looks normal to me. Ali Spec is silent on this, so this is indeed a question. Actually A is not interface, so I don't understand why you mention it. I did not mean D's feature 'interface'. The code explicitly specifies the objects as As, comitting to A's class interface. (As in, every used defined type defines an interface.) And there is neither 'taking C interface' because static type is A, so A function is called, neither it hides function of the base class because it is base class function which is called. I don't understand you completely. I agree with all of that. since there is no function, base class virtual is not replaced, so virtual table of C looks like A, so A member function is called. Exactly. Otherwise, when faced with such a situation the compiler would have to synthesize a virtual function for C's virtual table. string x() { return member_x; } so it appears that data member have priority over function. It looks like name hiding, which I am familiar from C++. Name hiding does not differentiate between functions and variables. Ali
Re: Build Hash from Array in one statement ?
On 02/22/2014 11:26 AM, Gordon wrote: Is there a way to quickly build a hash from the values of an array? If I am allowed to misunderstand :) it as a *single* hash from all of the values, then you can use D's internal hash algorithm for arrays: import std.stdio; void main() { auto arr = [ 1, 2, 3 ]; writeln(typeid(arr).getHash(arr)); } Ali
Re: hiding a class property behind a method
On 02/22/2014 09:43 PM, Ali Çehreli wrote: It looks like name hiding, which I am familiar from C++. Name hiding does not differentiate between functions and variables. Ali The problem is that hiding a name *is* a problem. When you are hiding a name, then a class would no longer behave as you would expect. It breaks LSP in a pretty awful way, and suddenly the *type* of a symbol changes based on what superclass you happened to use for a reference. class A { void f() {} } class B : A { int f; } A b = new B(); writeln(typeof(b.f).stringof); // void() B veryB = cast(B)b; writeln(typeof(veryB.f).stringof); // int Now suddenly, it's very important to use B as the type for a reference. This is very dangerous behavior in my opinion, and I think I've only used it *once* in C# - which requires you to be explicit about it - and I still feel dirty. Now what if a superclass implements a symbol that you are using in a subclass? I say we force it to be explicit as we finally did with `override`, which is shows some of the same issues, although not nearly as dangerous and hidden. I think member hiding is nearly always a bug, and we should be very explicit about it.
Re: hiding a class property behind a method
On Saturday, 22 February 2014 at 17:21:50 UTC, luka8088 wrote: It seems to me that the following code should be illegal, but I am uncertain of it so I am posting here for a confirmation before I post it on bug tracker: [snip] Nice find. I guess we could add this to the list of ugly code caused by calling functions without parenthesis. If parenthesis were not optional, I don't think that the code would behave in such a horrible way, right?
Re: hiding a class property behind a method
On 02/22/2014 11:33 PM, Francesco Cattoglio wrote: On Saturday, 22 February 2014 at 17:21:50 UTC, luka8088 wrote: It seems to me that the following code should be illegal, but I am uncertain of it so I am posting here for a confirmation before I post it on bug tracker: [snip] Nice find. I guess we could add this to the list of ugly code caused by calling functions without parenthesis. If parenthesis were not optional, I don't think that the code would behave in such a horrible way, right? The problem isn't about optional parenthesis or properties. It's the fact that you can redefine a symbol to be something entierly different, and that this difference will only be seen if you are looking at the symbol through the correct type. C# also allows has this feature, but you have to state explicitly that you are hiding an existing symbol. D as a safe-by-default language should also require this.
Re: hiding a class property behind a method
On Saturday, 22 February 2014 at 22:42:24 UTC, simendsjo wrote: The problem isn't about optional parenthesis or properties. It's the fact that you can redefine a symbol to be something entierly different, and that this difference will only be seen if you are looking at the symbol through the correct type. You are right. I thought that if we had forced parenthesis, the compiler would at least be able to understand what symbol you were referring to, but this is actually not the case.
Re: Cannot implicitly convert derived type
On Sat, 22 Feb 2014 15:17:37 -0500, Frustrated c1514...@drdrb.com wrote: It is legal exactly because I will always guarantee that the proper button will be used. Static typing says it's not legal. D does not do dynamic type checking upon calling virtual functions. It is not logically legal as mentioned several times... no one needs to mention that. But it is legal within the context of the code. I'll never use a RogueButton so why force me to code for the chance I might? You may not be the only one using WindowsGui. You can't guarantee other code won't do it. In any case, the compiler cannot possibly know your intentions. Basically, the point is, the compiler could enforce the above but make the code more readable. e.g., I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } This solution is not as efficient as the one I outlined. If you have a WindowsGui object, no need to accept iButton when you require WindowsButton. One allows me to program in a natural way while the other makes me jump through hoops which litters the code with a bunch of casts and checks which are only there in the odd event that I assign the wrong type(which, I'm not going to do on purpose). Sorry, if you want a dynamically typed language, use one. D is not that. Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could absolutely guarantee that I won't pass them then there should be no problem(no asserts). Since I can't guarantee it I have to litter my code with checks? The compiler could do this for me. You can't guarantee it. That is the point. The compiler could do the checks for you, but D is not dynamically typed. The best you can do is encapsulate the type checking code as a mixin. -Steve
IFTI with value / template value parameter shadowing
Hi everyone, I recently end up with the following code: import std.stdio; T IFTI_Type(T)(T value) { return value; } int IFTI_Value(int n)(int n) { return n; } int Shadowing_FTW(int n)() { writeln(n); int n = 42; // Will print 6 return n; } voidmain() { writeln(IFTI_Type(5));// Will print 5 writeln(Shadowing_FTW!6()); // Will print 42 // This doesn't compile //writeln(IFTI_Value(5)); writeln(IFTI_Value!5(8)); // Will print 8 } This will print: 5 6 42 8 So from the commented call to IFTI_Value, I guessed that IFTI is not working for values. Is that intended behavior, or a bug ? In addition it looks like template parameter are not considered while looking if a symbol with shadow another one. I didn't find anything on the bugtracker but (this)[https://d.puremagic.com/issues/show_bug.cgi?id=6980], but it's only related.
Re: Cannot implicitly convert derived type
On 02/22/2014 12:17 PM, Frustrated wrote: Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! Thinking that way, many rules of a statically type-checked language like D would be unnecessary. ;) WindowsGui only uses WindowsButton which is a iButton type. WindowsGui is totally free to use any type it wants. However, it cannot both claim to implement an interface without actually obeying its requirements. Why can't I relax the condition to use the base type? The users of iGui don't even know what a WindowsButton is: interface iGui { @property iButton button(ref iButton button); } Imagine the following that I write: void foo(WindowsGui gui, iButton b) { gui.button(b); } Is the call legal or not? How would I know and why should I care? I have a WindowsGui, which happens to be an iGui and I have an iButton. According to the contract of the interface I should be able to call it without fear of type problems. Even, I can create my own iButton and pass it to that WindowsGui: gui.button(new MyButton()); I should be able to do all of that just because WindowsGui promises to be an iGui. Getting back to what I said above: WindowsGui is totally free to use any type it wants. That's why both Steven and I made it take its button as a constructor parameter. Then, you also mentioned a setter. That's fine too. As long as WindowsGui allows me to give it an iButton when I call button(), it is all fine. Ali
Re: Cannot implicitly convert derived type
interface iButton { } class WindowsButton : iButton { } interface iGui(T) { @property T button(ref T button); } class WindowsGui : iGui!(WindowsButton) { @property WindowsButton button(ref WindowsButton button) { return button; } } Frustrated c1514...@drdrb.com On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote: Generic? I don't see how this would help. I'd have to specify every concrete type in the creation of the object which might be significant. I can't use a generic virtual method so that doesn't help either. It would be nice to have something like T foo(T : iButton)(T button); Which then I override with WindowsButton foo(WindowsButton button) { } Since WindowsButton is derived from iButton. The compiler would have to insert a type check to make sure when I called the first one(from the interface) that it was a windows button that was passed(since any iButton could be passed) when using the WindowsGui. The main point of all this is simply efficiency. I have to liter the code with checks and casts when it is entirely possible to get the compiler to automate it all. By doing so one can program the concrete class in a much more natural way.