Orange serializer/deserializer
How can I modify the pre serialization and post serialization values? I need to transform some variables that are stored but I would like to do this easily "inline"(would be cool to be able to provide a delegate to do the transformations at the site of definition of the fields). Also, how does orange handle properties? Seems it just deals with fields and ignores all functions(does not use getter and setter of properties). This is valid, of course, just want to make sure. I still need to be able to transform values pre and post though.
How are switches optimized
What is the best optimizations that a compiler does to switches in general and in the D compilers? A switch can be seen as if statements, or safer, nested if elses. but surely the cost per case does not grow with depth in the switch? If one has a switch of N case then the last cost surely does not cost N times the cost of the first, approximately? This is the cost when implementing a switch as nested ifs. Tables can be used to give O(1) cost, are these used in D's compilers? How are they generally implemented? Hash tables? If the switch is on an enum of small values is it optimized for a simple calculating offset table? switch(e) { case E.a: ... case E.z: ... } jmp offset + val(e) Or, in general a map table can be used jmp offset + map[e] Just curious...
Re: Getter an lvalue and cannot be modified
On Sunday, 27 May 2018 at 09:28:36 UTC, Mike Franklin wrote: On Sunday, 27 May 2018 at 09:23:09 UTC, IntegratedDimensions wrote: C[] c; @property C[] get() { return c; } get ~= something; errors out, yet auto q = get; q ~= something; is fine. Why is D thinking that ~= is being applied to get, the function, rather than what it returns? Also When I converted a field in to a property, an AA, it is returning null rather than being initialized by default. Seems like properties are broke. I'd expect a property getter to behave, for all intents and purposes as if it were field. I shouldn't have to have a temp variable to be able to use it as such. You'll probably get your answer and more by reading this: https://github.com/dlang/DIPs/pull/97 I came across a few posts mentioning this after the fact. It's been this way since at least 2012 so... It's now may so not sure how much longer we'll have to wait. That pull seems to have stalled. So close but so far away ;/
Re: Code repetition
On Sunday, 27 May 2018 at 13:20:08 UTC, Adam D. Ruppe wrote: On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote: Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists. I think you might just be using the wrong kind of function. --- import std.stdio; // the helper does the setup then calls another function for specific stuff void helper(void delegate(ref int) specialized) { // setup stuff int x; scope(exit) writeln("exit ", x); // specialized stuff abstracted out specialized(x); } void foo() { helper( (ref x) { x = 34; }); } void main() { foo(); } --- Yeah, this should work. Was hoping there was just a simple way to pull the code out but I guess this provides the best alternative. Thanks.
Getter an lvalue and cannot be modified
C[] c; @property C[] get() { return c; } get ~= something; errors out, yet auto q = get; q ~= something; is fine. Why is D thinking that ~= is being applied to get, the function, rather than what it returns? Also When I converted a field in to a property, an AA, it is returning null rather than being initialized by default. Seems like properties are broke. I'd expect a property getter to behave, for all intents and purposes as if it were field. I shouldn't have to have a temp variable to be able to use it as such.
Re: Code repetition
I guess I should have mentioned that basically this is like a C macro.
Code repetition
I have some code like void foo() { // setup stuff int x; scope(exit) something; // x = 34; } void foon() { // setup stuff int x; scope(exit) something; // } All the setup stuff is virtually identical in each foo. There are slight differences such as a return value. I would like to abstract the code code so that it can be handled in one place. I have not found a way to do this in D. Template mixins do not work because of the arbitrary expressions. Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists. A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc. I'd love to have something like a template mixin where I can just do mixin template fooSetup(ret) { // setup stuff int x; scope(exit) something; } and void foo() { fooSetup(3); } void foo4() { fooSetup(13); } and everything behave as it should. I'm guessing this is going to be impossible to achieve in D?
Re: C style callbacks fix for member callbacks
Investigating further, this does not seem to be pushed on the stack but set in EAX. Hence no amount of parameter placement manipulation will work. It actually becomes an easy situation although this will be invalid as it will be be whatever value is in EAX used by the caller. One cannot set this directly though but one does not have to use it. Therefor, simply using a member function here is the same as a static and no changes have to be made. Quite an easy fix. I do not know how safe it is. The docs say this is pushed and that is probably generally true.
Re: Any way to override base type with dervived in derived type
On Saturday, 26 May 2018 at 01:11:39 UTC, crimaniak wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). ... 1) Your architecture is wrong, I recommend to rethink it. Prove it genius! I recommend you rethink your absolutes without having a clue. Go back to SO, they need more Nazi's. 2) You still can deal with it using template mixins https://dlang.org/spec/template-mixin.html I've already said templates do not work. Time to rethink your answers, they are useless and you are not an authority, quick acting like one.
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer wrote: On 5/24/18 4:24 PM, IntegratedDimensions wrote: What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } It should work, you are allowed covariant overloads. However, private functions are not virtual, you need to make them at least protected. -Steve So, I upgraded everything, tried to add the setter and get an compile time access violation: override @property T t(T v) { _t = v; return v; } Changing T v to TT v gives the violation override @property T t(TT v) { _t = v; return v; } object.Error@(0): Access Violation 0x004850C8 0x00485C96 0x0043E22A 0x0047FB50 0x0046109A 0x0052401A 0x77D0B605 in LdrQueryProcessModuleInformation 0x77D11D02 in RtlQueryProcessLockInformation 0x77D11705 in RtlQueryProcessDebugInformation 0x77CA47DF in RtlAllocateHeap While my specific use case is far more complex in design, the original essentially boils down to the dpaste I gave. Probably won't spent any time on it since I do not need the setter in this case(can use the field directly). But a bug is probably related to the code that fixed the "original bug" and possibly windows. What I do know is that 2.75 did not produce this access violation and it was the same code(I just uncommented out the setter). The original dpaste code that did pass, I though, doesn't seem to pass now. I thought it was working for 2.80 and so I changed it to 2.69 and it failed but I might have made a mistake or the page lagged. Either way, maybe you have a clue for future reference.
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer wrote: On 5/24/18 4:24 PM, IntegratedDimensions wrote: What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } It should work, you are allowed covariant overloads. However, private functions are not virtual, you need to make them at least protected. -Steve Wow, I didn't expect that! Thanks, exactly what I needed. Unfortunately property setters seem to be broken. https://dpaste.dzfl.pl/24ce8c7e0681 Seems this is a bug though that has been fix as it only happens on certain the older compilers. I had to downgrade because in the latest I get a lot of link errors ;/
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 01:42:48 UTC, Basile B. wrote: On Friday, 25 May 2018 at 01:17:45 UTC, IntegratedDimensions wrote: On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote: On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2... or if there 100 fields. This isn't a proper solution. The whole issue is not outside of C but inside Hypothetically class C : A { @property TT : T t() { return _t; } // t can be used directly as TT rather than
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote: On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2... or if there 100 fields. This isn't a proper solution. The whole issue is not outside of C but inside Hypothetically class C : A { @property TT : T t() { return _t; } // t can be used directly as TT rather than having to do (cast(TT)t) everywhere t is used. } would solve the problem and it would scale. The way it would work is that inside
Re: Any way to override base type with dervived in derived type
On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D.
Any way to override base type with dervived in derived type
class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename?
Re: Efficient idiom for fastest code
On Wednesday, 23 May 2018 at 10:55:02 UTC, Malte wrote: On Wednesday, 23 May 2018 at 02:24:08 UTC, IntegratedDimensions wrote: [...] I would just do [...] [...] Thanks, I didn't think about using a for loop like that. While it is not the most general it does solve the specific case for a simple step/toggled decision.
Re: Efficient idiom for fastest code
On Wednesday, 23 May 2018 at 03:00:17 UTC, Nicholas Wilson wrote: On Wednesday, 23 May 2018 at 02:24:08 UTC, IntegratedDimensions wrote: Many times in expensive loops one must make decisions. Decisions must be determined and the determination costs. for(int i = 0; i < N; i++) { if(decision(i)) A; else B; } the if statement costs N times the cycle cost. In some cases the decision holds for continuous ranges. For some 0 <= n <= N the decision is constant, but n is arbitrary(determined by unknown factors at compile time). One can speed up the routine by using something akin to a simplified strategy pattern where one uses functions/delegates/lambdas to code a faster version without the test: for(int i = 0; i < N; i++) { d = (){ if(decision(i)) A; else d = () { B; }; d(); } assuming you meant auto d = (int i){ if(decision(i)) A; else d = (int i) { B; };}; for(int i = 0; i < N; i++) { d(i); } this code basically reduces to for(int i = 0; i < N; i++) { B; } Once the decision fails, which we assume once it fails it always fails in this particular case. Therefor, once the decision fails it kicks in the "faster" code. Suppose decision is very slow. The cycle cost is then n times rather than N times. In general, such techniques can be used to speed up code, sometimes significantly, but are difficult to implement using a standard pattern and for more complex decision functions. Does anyone see any way to use some some of D's power to help simplify such things but not using something like a strategy pattern or complexifying the overall design(using advanced techniques such as templates, mixins is not making the code more complex). If decision is pure, consider using static foreach (iota(N).map!decision) { ... }to unroll it at compile time. even if it isn't the compiler may still be able to factor out parts of repeated calls to decision, look at the assembly/IR to confirm this. Otherwise PROFILE! (and use profile guided optimisation! this implies using a compiler other than DMD which if you care about performance you should be doing anyway) Blindly trying to optimise is just as likely to hurt performance. in particular don't underestimate the branch predictor. Even if decision is complex, if there is a pattern in evaluating iota(n).map!decision the branch predictor will pick up on it. In terms of exploiting knowledge of decision a priori that the compiler somehow lacks you really don't have much option but to do it yourself. I knew someone was going to say that and I forgot to say DON'T! Saying to profile when I clearly said these ARE cases where they are slow is just moronic. Please don't use default answers to arguments. This was a general question about cases on how to attack a problem WHEN profiling says I need to optimize. Your SO 101 answer sucks! Sorry! To prove to you that your answer is invalid: I profile my code, it says that it is very slow and shows that it is do to the decision checking... I then I have to come here and write up a post trying to explain how to solve the problem. I then get a post telling me I should profile. I then respond I did profile and that this is my problem. A lot of wasted energy when it is better to know a general attack strategy. Yes, some of us can judge if code is needed to be optimized before profiling. It is not difficult. Giving a generic answer that always does not apply and is obvious to anyone trying to do optimization is not helpful. Everyone today pretty must does not even optimize code anymore... this isn't 1979. It's not ok to keep repeating the same mantra. I guess we should turn this in to a meme? The reason I'm getting on to you is that the "profile before optimization" sounds a bit grade school, specially since I wasn't talking anything about profiling but a general programming pattern speed up code, which is always valid but not always useful(and hence that is when profiling comes in).
Efficient idiom for fastest code
Many times in expensive loops one must make decisions. Decisions must be determined and the determination costs. for(int i = 0; i < N; i++) { if(decision(i)) A; else B; } the if statement costs N times the cycle cost. In some cases the decision holds for continuous ranges. For some 0 <= n <= N the decision is constant, but n is arbitrary(determined by unknown factors at compile time). One can speed up the routine by using something akin to a simplified strategy pattern where one uses functions/delegates/lambdas to code a faster version without the test: for(int i = 0; i < N; i++) { d = (){ if(decision(i)) A; else d = () { B; }; d(); } this code basically reduces to for(int i = 0; i < N; i++) { B; } Once the decision fails, which we assume once it fails it always fails in this particular case. Therefor, once the decision fails it kicks in the "faster" code. Suppose decision is very slow. The cycle cost is then n times rather than N times. In general, such techniques can be used to speed up code, sometimes significantly, but are difficult to implement using a standard pattern and for more complex decision functions. Does anyone see any way to use some some of D's power to help simplify such things but not using something like a strategy pattern or complexifying the overall design(using advanced techniques such as templates, mixins is not making the code more complex).
Re: Locking data
On Tuesday, 22 May 2018 at 23:09:24 UTC, Sjoerd Nijboer wrote: On Tuesday, 22 May 2018 at 22:17:05 UTC, IntegratedDimensions wrote: On Tuesday, 22 May 2018 at 22:10:52 UTC, Alex wrote: On Tuesday, 22 May 2018 at 21:45:07 UTC, IntegratedDimensions wrote: an idea to lock data by removing the reference: class A { Lockable!Data data; } The idea is that when the data is going to be used, the user locks the data. The trick here is that data is a pointer to the data and the pointer is set to null when locked so no other data can use it(they see a null reference). To unlock, the data is reassigned: auto d = data.lock(); // A.data is now null deals with sync issues //use d d = data.unlock(d); // restores A.data (A.data = d;) and sets d to null so any future reference is an error(could produce bugs but should mostly be access violations) Anyone else trying to use data will see that it is null while it is locked. This basically pushes the standard locking mechanisms in to the Lockable!data(first come first serve) and code that has not captured the data see's it simply as null. Anyone use know if there exists an idiom like this and what it is called? Maybe some idiomatic code that is efficient? Ideally I'd want to be able to treat the Lockable!Data as Data. Right now I have to classes(or pointers to structs) and few weird hacks. I think what I'll have to end up doing is having a Locked!Data structure that is returned instead or use an UFCS. The idea being to attach the lock and unlock methods. Are you aware of NullableRef? https://dlang.org/library/std/typecons/nullable_ref.html Yes. Does it fit somehow? Not really. It could be used to wrap the data when used as a struct but it offers none of the locking features which is the ultimate goal. The idea is simply that one can lock the data to get exclusive access. Normally standard locking tricks are used but in this case the idea is to do all that behind the scenes. Locking the data makes all other accessors see null data(and crash or properly test). This is a first come first serve or single access type of pattern but sort of removes the data from prying eyes while it is being used. how about something like import core.atomic; class Lockable!Data { private __gshared Lockable!Data data; } struct Locked!Lockable!Data { private TailShared!Lockable!Data lockedData; private Lockable!Data lockableData; this(Lockable!Data lockableData) { this.lockableData = lockableData; while( (lockedData= atomicLoad(lockableData)) !is null) if(cas(lockedData, lockedData, null)) break; } ~this() { atomicStore(lockedData, lockableData ); } alias lockedData.data this; } With something like this you should be able to do RAII like semantics on your data. You share a Lockable!Data which you want use, and then you can access it if you instantiate a Locked!Lockable!Data struct with it. FYI, my atomics isn't all that great so don't expect this to work. This is similar to what I am doing... maybe "identical".
Re: Locking data
On Tuesday, 22 May 2018 at 22:10:52 UTC, Alex wrote: On Tuesday, 22 May 2018 at 21:45:07 UTC, IntegratedDimensions wrote: an idea to lock data by removing the reference: class A { Lockable!Data data; } The idea is that when the data is going to be used, the user locks the data. The trick here is that data is a pointer to the data and the pointer is set to null when locked so no other data can use it(they see a null reference). To unlock, the data is reassigned: auto d = data.lock(); // A.data is now null deals with sync issues //use d d = data.unlock(d); // restores A.data (A.data = d;) and sets d to null so any future reference is an error(could produce bugs but should mostly be access violations) Anyone else trying to use data will see that it is null while it is locked. This basically pushes the standard locking mechanisms in to the Lockable!data(first come first serve) and code that has not captured the data see's it simply as null. Anyone use know if there exists an idiom like this and what it is called? Maybe some idiomatic code that is efficient? Ideally I'd want to be able to treat the Lockable!Data as Data. Right now I have to classes(or pointers to structs) and few weird hacks. I think what I'll have to end up doing is having a Locked!Data structure that is returned instead or use an UFCS. The idea being to attach the lock and unlock methods. Are you aware of NullableRef? https://dlang.org/library/std/typecons/nullable_ref.html Yes. Does it fit somehow? Not really. It could be used to wrap the data when used as a struct but it offers none of the locking features which is the ultimate goal. The idea is simply that one can lock the data to get exclusive access. Normally standard locking tricks are used but in this case the idea is to do all that behind the scenes. Locking the data makes all other accessors see null data(and crash or properly test). This is a first come first serve or single access type of pattern but sort of removes the data from prying eyes while it is being used.
Locking data
an idea to lock data by removing the reference: class A { Lockable!Data data; } The idea is that when the data is going to be used, the user locks the data. The trick here is that data is a pointer to the data and the pointer is set to null when locked so no other data can use it(they see a null reference). To unlock, the data is reassigned: auto d = data.lock(); // A.data is now null deals with sync issues //use d d = data.unlock(d); // restores A.data (A.data = d;) and sets d to null so any future reference is an error(could produce bugs but should mostly be access violations) Anyone else trying to use data will see that it is null while it is locked. This basically pushes the standard locking mechanisms in to the Lockable!data(first come first serve) and code that has not captured the data see's it simply as null. Anyone use know if there exists an idiom like this and what it is called? Maybe some idiomatic code that is efficient? Ideally I'd want to be able to treat the Lockable!Data as Data. Right now I have to classes(or pointers to structs) and few weird hacks. I think what I'll have to end up doing is having a Locked!Data structure that is returned instead or use an UFCS. The idea being to attach the lock and unlock methods.
Re: C style callbacks fix for member callbacks
On Monday, 21 May 2018 at 02:23:27 UTC, ag0aep6g wrote: I tried this. Your code crashes in windows dmd x86 x64. Hm. Works for me in a virtual machine. But I'm not surprised that it's fragile. It might be completely wrong, and it just happens to look alright on my machine. https://run.dlang.io/is/CMNnJY Shows the static version produces the same code as the non-static. The code was probably compiled on linux. I can't tell though on my machine what is going on since I cannot disassemble properly and what I do see is far more complex.
Re: Real Int24
On Monday, 21 May 2018 at 15:41:21 UTC, Simen Kjærås wrote: On Saturday, 19 May 2018 at 18:44:42 UTC, IntegratedDimensions wrote: On Saturday, 19 May 2018 at 18:19:35 UTC, IntegratedDimensions wrote: Is there any way to create an int24 type that behaves just like any other built in type without having to reimplement everything? In fact, what I'd like to do is create an arbitrary type: struct atype(T) { } where atype(T) is just a "view" in to N_T bits interpreted as T, an enum. If T is bit, then the N = 1 and the interpretation is 1 bit. If T is byte, then the N = 8 and the interpretation is 7 bits followed by 1 signed bit. If T is int24, then the N = 24 and the interpretation is 23 bits followed by 1 signed bit. The idea is the storage of atype is exactly N bits. If this is not possible due to boundary issues then N can always be a multiple of 8(which is for my use cause is the smallest). D does not support types that take up less than one byte of space. It's possible to make types that represent less than one byte - bool may be considered such an example - but they still take up at least 1 byte. If you create a custom range type, you could pack more than one element in each byte, see std.bitmanip.BitArray[0] for an example. The main thing is that I would like to be able to use atype as if it were a built in type. If N = 24, 3 bytes, I want to be able to create arrays of atype!int24[] which work just as if they were arrays of bytes without any exception or special cases. atype!byte would be equivalent to byte and reduce to the compiler internals. I'm not looking to create a "view" of an array. I want a standalone type that can behave as all the desired types needed, which is most of the numerical types of D and some of the ones it neglected like 24-bit ints, 48-bit ints, etc. Ideally, any type could be used and the "most optimal" code is generated while being able to use the types using the standard model. We already have std.numeric.CustomFloat[1]. As the name implies, it only works for floats. I hacked together something somewhat equivalent for ints: https://gist.github.com/Biotronic/f6668d8ac95b70302015fee93ae9c8c1 Usage: // Two's-complement, native-endian, 24-bit int type: CustomInt!24 a; // Unsigned, native-endian, 15-bit: CustomInt!(15, Representation.Unsigned) b; // Offset (-2..5) 3-bit int: CustomInt!(3, Representation.OffsetBinary, 2) c; // You get the idea: CustomInt!(64, Representation.SignedMagnitude, 0, Endianness.BigEndian) d; Not sure this is what you're looking for, but it's at the very least inspired by your post. :) If what you want is a type that can represent something a packed array of 13-bit ints, the above is not what you're looking for - you're going to need a custom range type. -- Simen [0]: https://dlang.org/phobos/std_bitmanip#BitArray [1]: https://dlang.org/phobos/std_numeric.html#.CustomFloat Cool. I'll try it as a drop in replacement and if it works then it works! ;) Thanks. Just to be clear and to make sure this works the way it seems: All types multiple of a byte are reduced to either internal representation(byte, ubyte, short, ushort, int, uint, long, ulong) directly(becomes an alias) or the most efficient structure for the representation: unsigned 24-bit = 3 bytes and is effectively ubyte[3], usigned 128-bit is ubyte[16], etc? Non multiples are extended up one byte, so 7-bits is representing using an byte, etc. This seems to be the case from the code. Now, what I didn't see was anything to work with non byte aligned arrays of CustomInt. Would it be possible to add? I know you say that we should use bitmanip but code could be extended to support it relatively easily by treating an array of bits as an array of CustomInts and the indexer can compute the appropriate offset using the bit size. Maybe that will require CustomIntsArray? The idea is, say one has 7-bit ASCII represented in a ubyte[] then they can map that to a CustomInt!7[] which will be use CustomInt!7(but 7 bits, not 8) as representation. But, of course CustomInt!7[3] would be 8 bits. But basically it retrieves the correct value and stores it by doing the standard masking. BTW, it looks like you could extend your type to deal with floats and doubles which would make this type very robust in dealing with arbitrary primitive types. The idea is that any matching language types are aliased to and those that don't are handled appropriately.
Re: C style callbacks fix for member callbacks
On Sunday, 20 May 2018 at 23:05:47 UTC, ag0aep6g wrote: On 05/20/2018 06:48 PM, IntegratedDimensions wrote: alias callback = extern(C) int function(const(void) a, void *b, uint c, void* context); (I'm assuming that `a` is supposed to be a `const(void)*`.) Where context acts as this. I would like to assign a D method to this callback. class { callback c; /*extern(C) static*/ int foo(const(void) a, void *b, uint c, void* context); this() { c = cast(callback) } } Unless I'm misunderstanding it, the spec seems to say that the `this` pointer is passed as if it was an additional parameter past the last one [1]. But that doesn't seem to be true in the implementation. At least on Linux x86-64, `this` seems to be a hidden first parameter. So when a method is called as a `callback`, `a` becomes `this`, `b` becomes the first explicit parameter, `c` the second, and `context` the third. So this works: import std.stdio; alias Callback = extern(C) int function(const(void)* a, void* b, uint c, void* context); class C { int field = 43; extern(C) int foo(void* b, uint c, C this_) { const(void)* a = cast(void*) this; writeln(a, " ", b, " ", c, " ", this_.field); return 0; } } void main() { void* a = new int; void* b = new int; uint c = 42; auto obj = new C; Callback cb = cast(Callback) ().funcptr; cb(a, b, c, cast(void*) obj); writeln(a, " ", b, " ", c, " ", obj.field); /* For comparison. Should print the same. */ } This is all very hacky, of course. And I don't really know what I'm doing there. So obviously, I don't recommend doing this. But other than hacking it like that, I don't think you can pass a method as a `callback` directly. [1] https://dlang.org/spec/abi.html#parameters I tried this. Your code crashes in windows dmd x86 x64. It really shouldn't be hacky. The only difference is the "this" is implicit normally when in this case it is explicit and possibly in a different location than one expects.
Re: Convert mixin to function call
It should be obvious that these are simplifications. I can't pass the variables directly as parameters as in the real case the names may only be partially specified.
Re: Convert mixin to function call
https://dpaste.dzfl.pl/fb49bf834cff import std.stdio; auto Q(string A)() { auto foo() { auto d = mixin(Z!(A)()); return d; } return foo()(); } auto X(string A, string N)() { return N~" = (() { int y = 4; return "~A~" + y + 5; })();"; } auto Z(string A)() { return "() { int y = 4; return "~A~" + y + 5; }"; } void main() { int x = 3; double y = 0; pragma(msg, (X!("x", "y")())); mixin(X!("x", "y")()); y = Q!("x")(); writeln(y); } using Q is more ideomatic but foo does not have access to x which is required(since Q should behave like a string mixin as far as scope is concerned).
Re: Convert mixin to function call
Also, one thing that would help would be able to create identifier names that are unique to avoid collisions. Does D have any ability to do such a thing?
Convert mixin to function call
I have a string mixin that returns a value or function that uses the mixed in scope. Currently I have to wrap the mixin in a delegate or local function as to be able to get the value: int x = 3; int y = 1; auto foo() { mixin(X!("x")); } This allows the the mixin to see the scope but keep the mixin variables local so they do not shadow anything unintentionally. auto X(string A)() { return "int y = 4; return "~A~" + y + 5;"; } foo will just return 8 but I cannot simply mixin within the main scope or the scope will return unintentionally. int x = 3; mixin(X!("x")) // <- hidden return Using foo works fine but adds a level of indirection I feel is unnecessary. The only thing I feel can work is to rewrite X so that it uses variables with random names to reduce shadowing issues and to allow X to take a variable name to put the result in: auto X(string A, string N)() { return "{ int _342sdfs = 4; "~N~" = "~A~" + _342sdfs + 5;}"; } which complicates things significantly. My hope is that D would inline the function call. Ideally I'd like to be able to sort of use the mixin as a function and simply call it: val = mixin(X!("x"))(); which I could do by internally using a delegate inside the mixin auto X(string A)() { return "(() { int y = 4; return "~A~" + y + 5; })"; } except that the mixin syntax does not allow one to use it in an expression. Remember that the mixin must be able to see the scope it is mixed in at so one can't wrap this in a template use it as far as I know? Although, one can do mixin(X!("val", "x")); which does the ugly work. It would be nice to be able to get this process to look as much like normal D code as possible. the idea is to try to write "local" string mixins that are messy and not "C'ish" looking in to "C'ish" looking code.
Re: C style callbacks fix for member callbacks
On Sunday, 20 May 2018 at 08:40:57 UTC, MGW wrote: On Saturday, 19 May 2018 at 23:52:58 UTC, IntegratedDimensions wrote: I have a member callback that I want to use as a C callback. http://www.agner.org/optimize/calling_conventions.pdf https://www.youtube.com/watch?v=xhDS377mAc4 Sorry, I can't understand Russian(wish I could!). It also does not seem applicable for my problem. Although It is a useful idea here(using D in C++). alias callback = extern(C) int function(const(void) a, void *b, uint c, void* context); Where context acts as this. I would like to assign a D method to this callback. class { callback c; /*extern(C) static*/ int foo(const(void) a, void *b, uint c, void* context); this() { c = cast(callback) } }
Re: is ==
Furthermore: https://issues.dlang.org/show_bug.cgi?id=3889 Shows real problems. You argue from the side that the bug already exists so we must work around it because we can't go back and "fix things". Who says? D has had breaking changes in the past so it is not a deal breaker. It is also a relatively easy transition because == null is very easy to find and fix. With the mentality that one must always deal with introduced logic bugs that, if fixed, will break old code is insane. The whole point of fixing bugs is to make things work *correctly*. The fact is someone decided it was a good idea to conflate null with some dynamic array BS and that is where all the problems come from. It should have never been done and this issue will persist until someone gets the balls to fix it. After all, how do you know it won't actually make a lot of "buggy" code better?
Re: is ==
On Sunday, 20 May 2018 at 02:09:47 UTC, Jonathan M Davis wrote: On Sunday, May 20, 2018 01:51:50 IntegratedDimensions via Digitalmars-d- learn wrote: Simply require == null as is null and be done with it. That would be flat out wrong for dynamic arrays, because then auto result = arr == null and int[] nullArr; auto result = arr == nullArr; would have different semantics. The way that dynamic arrays are designed to work even if they're null mucks with this considerably here. Do you not see they are different? You think arr == nullArr and arr == null are suppose to necessarily be the same semantics? That is patently false! You should rethink your position on that because it is wrong. null is a keyword in D and has a very special meaning and hence that meaning MUST be taken in to account. There is no harm in making them different. Your logic thinks that that they should be the same but if you are wrong then your whole argument is wrong. for example, Object o = null; then o == null should not be true even though "null == null" in some sense. == null is a test of validity. One never checks if null == null and it is a meaningless case so allowing it as a possibility is meaningless. You are treating null as if it is on the same level as objects and arrays and it is not. By doing so you lose the power of it being singled out as a keyword. You can't police programmers minds and get them to program correctly. That's true, but making things that are highly likely to be wrong illegal prevents bugs. e.g. Not necessarily because you just create more bugs by doing that. Your son, the bubble boy, then does not develop an immune system that he should of developed by you trying to protect them from hurting himself. You should get out of the business of trying to prevent things that you don't even know are going to happen. It is a bad mindset to be in because, for all you know, those things will never happen. Time is better spent than trying to police everyone from doing anything wrong. 1. You can't do it. 2. You make things worse in the long run because who's policing you to keep you from screwing up? Do you know how many "bugs" are produced by people who are fixing "bugs"? We can surely bet more than zero. while(cond); is illegal in D precisely because it's error-prone. There are cases where doing something like that would be perfectly correct. e.g. while(++a != b); but you can do the exact same thing with empty parens while(++a != b) {} and all of those bugs with accidentally closing a loop with a semicolon go away, and you don't lose any expressiveness. The compiler just forces you to write it in a way that's far less error-prone. This is a different problem and therefor not applicable. Making it illegal to compare the null literal with == also prevents bug, and you don't lose any expressiveness doing it either. It's the same kind of logic. Making error-prone constructs illegal when there's a simple equivalent that isn't error-prone is good language design, because it prevents bugs without actually restricting the programmer. It's when the language starts disallowing things that aren't error-prone and/or don't have simple equivalents that you start running into problems with the compiler getting in your way and treating you like a kid. For simple stuff like this, it ultimately saves you time and effort without getting in your way. At most, you occasionally have to replace foo == null with foo is null or foo.length != 0, and it potentially saves you hours of effort tracking down a subtle bug. - Jonathan M Davis You certainly do lose expressiveness. You loose elegance because you cannot express logically related things in a logically related way. The problem is the WHOLE reason it is error prone is from who ever decided the dynamic array syntax of == null would not compare it the same way it does everything else. Basically someone thought they were going to be fancy and treat == null as the same as an allocated 0 length array. That was the problem from the get go. == null should have a very specific and consistent meaning and someone decided to change that in an irregular and inconsistent meaning and now we have less elegance in the language than we could. The reason why you are saying it is buggy is PRECISELY because of what was done wrong. Programmers assume that == null means the same thing it does everywhere else, but LO AND BEHOLD! Not in that one special case and if they don't know about that special case they hit the "bug". See, what you call bugs is really the programmers failing to know the special case that was created. The special case that really had no reason to be a special case. So, in fact, who ever decided on the rules here created more problems than they solved. Any time you create special cases you create complexity and that is what c
Re: is ==
On Sunday, 20 May 2018 at 00:19:28 UTC, Jonathan M Davis wrote: On Saturday, May 19, 2018 17:50:50 IntegratedDimensions via Digitalmars-d- learn wrote: So, ultimately what I feels like is that you are actually arguing for == null to be interpreted as is null but you don't realize it yet. Not really, no. Having foo == null be rewritten to foo is null in the non-dynamic array cases should be fine except for the fact that it's then a terrible habit to be in when you then have to deal with dynamic arrays. Using foo == null with dyanmic arrays is an enormous code smell, because the odds are extemely high that the programmer thinks that they're checking if the dynamic array is null when that's not what they're doing at all. IMHO, it should definitely be an error to use == with null and dynamic arrays because it is such a big code smell. Either the code should be using is to check whether the array is null, or it should be checking length. It should never be using == with null. But unfortunately, the compiler is completely backwards about this and treats it as an error with pointers and references but allows it with dynamic arrays. If the compiler were improved to just replace == with is in the cases that it currently treats as illegal, then that would be fine if it then treated it as illegal with dynamic arrays. But as it stands, it is still more efficient to use is with call references, so encouraging the programmer to use is is benefical, and it encourages the programmer to get in the habit of not using == with null, since it's a terrible habit to be in with dynamic arrays. But actually making it illegal for dynamic arrays would be a much better approach. If it were up to me, it would just be illgal to use == with null in general, because that's really the way it should be with dynamic arrays, and then the language would be consistent about it. But instead, the compiler screams in the case that matters far less and allows it in the case that is clearly bad. So, it's inconsistent in a dumb way. At least if it were inconsistent by allowing it for pointers and references while disallowing it for arrays, it would be prventing it in the case that truly matters, but instead, what we have is just dumb. - Jonathan M Davis Let D be a dynamic array, O a pointer or object: | Conceptually | in D D == null Invalid Valid D is null Valid Valid O == null Valid Invalid O is null Valid Valid Right? So what you are saying is you want to create 2 more invalids in the table to satisfy some weird logic which requires the programmer to remember special cases rather than make them all valid and easy to remember even though it can be done and make sense. In fact, the 2nd invalid makes sense and should be allowed so really you want to create 3 invalids for the price of one. Simply require == null as is null and be done with it. You can't police programmers minds and get them to program correctly. If you had a kid, do you box them up in a bubble room and not let them play because they might hurt themselves? How people learn is by making mistakes. It is better to provide a logical foundation that is consistent rather than produce corner cases to handle some corner case that was created to handle another corner case because someone handled a corner case.
C style callbacks fix for member callbacks
I have a member callback that I want to use as a C callback. This is impossible due to the `hidden this` passed as the "first" parameter. The callback already makes it's last value a user pointer which I use as a "this". If I make my method static extern(C) then there is no crash and everything works. The problem is that it is now a static function within the class which I want to avoid. Because there is actually a "this pointer" I can make it a member function and everything works as long as the calling convention is right. I was initially wrapping the callback in a delegate that made it all work out but I want to avoid that level of indirection since it should not be necessary. I have tried manually reversing the arguments, using various calling conventions, etc but everything crashes except when I use extern(C) static without modifying the order. extern(C) static foo(a,b,c,d) puts the parameters on the stack as d,c,b,a foo(a,b,c,d) is d,c,b,a,this (? The ABI does not make it clear what order is pushed on the stack. It uses the terminology "passes" and I assume that the calling convention is C'ish although extern(C) matters). works extern(C) static foo(a,b,c,d) does not work static foo(d,c,b,a) So something else is going on "The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met: It fits in EAX. It is not a 3 byte struct. It is not a floating point type. " Can someone clarify the exact calling convention process for C vs D along with any potential solutions to the above problem(using static is not a solution). Just to make sure we are on the same page: class { void extern(C) static foo(a,b,c,mythis); } works while class { void extern(C) foo(a,b,c); } fails. class { void foo(c,b,a); } also fails.
Re: Real Int24
On Saturday, 19 May 2018 at 18:19:35 UTC, IntegratedDimensions wrote: Is there any way to create an int24 type that behaves just like any other built in type without having to reimplement everything? In fact, what I'd like to do is create an arbitrary type: struct atype(T) { } where atype(T) is just a "view" in to N_T bits interpreted as T, an enum. If T is bit, then the N = 1 and the interpretation is 1 bit. If T is byte, then the N = 8 and the interpretation is 7 bits followed by 1 signed bit. If T is int24, then the N = 24 and the interpretation is 23 bits followed by 1 signed bit. The idea is the storage of atype is exactly N bits. If this is not possible due to boundary issues then N can always be a multiple of 8(which is for my use cause is the smallest). The main thing is that I would like to be able to use atype as if it were a built in type. If N = 24, 3 bytes, I want to be able to create arrays of atype!int24[] which work just as if they were arrays of bytes without any exception or special cases. atype!byte would be equivalent to byte and reduce to the compiler internals. I'm not looking to create a "view" of an array. I want a standalone type that can behave as all the desired types needed, which is most of the numerical types of D and some of the ones it neglected like 24-bit ints, 48-bit ints, etc. Ideally, any type could be used and the "most optimal" code is generated while being able to use the types using the standard model.
Real Int24
Is there any way to create an int24 type that behaves just like any other built in type without having to reimplement everything?
Re: is ==
On Saturday, 19 May 2018 at 01:31:38 UTC, Jonathan M Davis wrote: On Friday, May 18, 2018 23:53:12 IntegratedDimensions via Digitalmars-d- learn wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. Because == is pretty much never what you want to do with null. How much it matters depends on the types involved, but if you really want to check for null, is is definitely the right thing to use. In the case of pointers and references, is checks that they're pointing to the same thing. So, foo is null directly checks whether the reference or pointer is null. On the other hand, if you use ==, it's calling some form of opEquals. For pointers, that should generate identical code, but for class references, it means calling the free function opEquals. That function will check whether the references are null before calling opEquals on either of the class objects, but it does add unnecessary overhead (which, as I understand it, the compiler is unfortunately not currently able to optimize away) and provides no benefit over checking with is. Now, where is vs == _really_ matters (but unfortunately, the compiler does not complain about) is with dynamic arrays. If you do arr is null then the compiler will check whether the array's ptr is null. So, something like "" is null would be false. However, if you use ==, then it compares the length of the array and then only compares the ptrs if the length is non-zero. So, "" == null is true. So, with dynamic arrays, using == with null is a huge code smell. It _may_ be exactly what the programmer intends, but the odds are pretty high that they just don't properly understand the difference between is and ==, and they meant to be checking whether the array was actually null but just ended up checking whether its length was zero (which won't matter for some code but will cause subtle bugs in any code that treats null as special - e.g. if that is used to indicate that the array had not been given a value). Now, because of how == treats null like empty, it _is_ a bit risky to try and treat null as special with arrays, but anyone wanting to be clear in their code should either be checking null with is (in which case, they clearly care about null and not empty), or if they care about length == 0, they should either be calling empty on the array or explicitly checking the array's length, since that's what they care about. Much as having == work with null arrays avoids issues with segfaults due to an array be unitialized as well as avoids needing to give memory to an array just to have it be empty, you pretty much never actually care whether an array == null. You either care that its ptr is null (in which case, is checks that), or you care about whether its length is 0 (in which case empty or directly checking length checks that). arr == null is just unclear and likely buggy. So really, there are _zero_ advantages to comparing null with ==. Using == with null risks adding extra overhead, and it often makes the code less clear. On the other hand, using is makes it crystal clear what you mean and then does exactly what you mean - check whether the variable is actually null. So, maybe the compiler is being a bit pedantic by insisting that you use is rather than ==, but you really should be using is and not == when checking for null. - Jonathan M Davis I don't see your point. You claim that one should never use == null for whatever reason and that it is "wrong". So, why are you allowing wrong things in a language that can easily be fixed? Just reinterpret == null as is null and be done with it! This fixes the wrong and everyone can live happily ever after. Your logic is the same how people "ban" certain words like faggot. They don't like them for some reason, decide that no one should use it any more, and create a new word that essentially means the same thing... and it results in a loop where that new word then eventually gets "banned". == vs is might not be quite as extreme, maybe is will be the final "word". But if == null is banned by the compiler why the hell not just reinterpret to mean is null internally and be done with it and allow the syntax since it is so common? The only pitfalls is pasting code from other languages that might have a different interpretation, but those problems always exist since the languages are different. Your reasons for arrays is not good enough. First, not all types are arrays so you are banning a whole class of valid types for one case. That case, you say, is almost never meant anyways(that is, using == null is really meant as is null). So, ultimately wha
Re: is ==
On Friday, 18 May 2018 at 23:58:18 UTC, Uknown wrote: On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. D only complains of this when you use ref types (classes or AAs). For e.g: --- test.d void main() { int * p; assert (p == null && p is null); class C { int x; } C c; assert (c is null); assert (c == null); //error, c is a reference, so there is confusion between opEquals and null check } --- or pointers.
is ==
Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it.
Re: Dependency injection pattern
On Sunday, 13 May 2018 at 07:42:10 UTC, Suliman wrote: Could anybody give small example of Dependency injection pattern? I googled about it, but found only C# examples and I am not quite sure how to use them. Also I would like get some explanation/comments for code. Dependency injection is explicit dependencies are injected in to an object for use by the creator of the object rather than hard coding dependencies in to the object. For example, if you are creating an object that will lightly depend on an interface I then you can the interface and require that the object for the interface be injected(specified) by the user of the object. class X { I i; void foo() { /* uses i */ }; } Then X.i = _i; is a dependency injection of _i so that X uses _i. Usually one does not want the dependency to be freely changed as to avoid changing a dependency in the middle of it being used. Various schemes can be create to avoid these issues such as allowing injection only during construction or some special synchronization techniques to avoid usages. e.g., void foo() { I _i = i; /* uses _i */ }; Then reassignment won't change the dependency when a function is using it. Whatever means, the idea is simple: One does not want to hard code dependencies directly so that refactoring code is ultimately easier. Dependencies can be injected in to the working code by the user. This makes the code depend on the type of the dependency so any specific dependency can be injected. Top answer here says pretty much exactly what I'm saying: https://stackoverflow.com/questions/3058/what-is-inversion-of-control?utm_medium=organic_source=google_rich_qa_campaign=google_rich_qa
Re: Error: module `hello` is in file 'hello.d' which cannot be read
On Friday, 4 May 2018 at 23:29:12 UTC, Alex wrote: Hi I just installed D on my windows 10 and want to try to compile a hello world. My source is a classical import std.stdio; void main() { writeln("Hello, World!"); } And I try to compile and get C:\D>dmd hello.d Error: module `hello` is in file 'hello.d' which cannot be read import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import What do I do wrong ? D is installed at de root of C:, and the hello.d source code is at C:\D\dmd2\sources. Thank you to you Alex You need to make sure hello.d is in the current dir dir C:\D does hello.d show up? If not, then dmd can't find it and you have to tell it where it is or be in the right location. type dmd ThereIsNowFileHere12342123242231231412.d and you will get the same error message.
LDC phobos2-ldc.lib(json.obj) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'x86'
trying to compile a simple program in x86. Compiles fine in dmd and ldcx64. Seems like ldc is using the wrong lib for some reason? phobos2-ldc.lib(json.obj) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'x86' Error: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\bin\HostX86\x86\link.exe failed with status: 1112 Tried replacing the x64 dir with the x86 and it didn't change so it isn't the library arch best I can tell. Maybe this is a cross compilation issue?
Re: How to curl!
On Wednesday, 2 May 2018 at 03:03:19 UTC, ikod wrote: On Wednesday, 2 May 2018 at 00:04:49 UTC, IntegratedDimensions wrote: On Tuesday, 1 May 2018 at 23:35:42 UTC, Arun Chandrasekaran wrote: [...] Ok, first try: Unhandled exception: object.Exception can't complete call to TLS_method at requests\ssl_adapter.d(248) which says it can't find the lib. I renamed ssleay32.dll to libssl32.dll and it then passed. I am getting http 404 error though ;/ I turned off cert though, which may be the reason, I have no idea. Seems to be working through. Did you try to use full path to cacert.pem? That seemed to work. Why would it not look in the current directory by default? Maybe something to add?
Re: How to curl!
On Tuesday, 1 May 2018 at 23:35:42 UTC, Arun Chandrasekaran wrote: On Tuesday, 1 May 2018 at 21:57:22 UTC, IntegratedDimensions wrote: Trying to curl basic stuff but std.net.curl isn't cooperating: This is one of the reasons I hate D ;/ I've spent more time trying to get std.net.curl to do something that just works from the command line. std.net.curl is not quite up to date when compared to the curl command. It is not useful any non-trivial stuff. Right now I'm using ikod's dlang-requests[1] and I'm quite happy with it. I would recommend you to try it. [1] https://github.com/ikod/dlang-requests Ok, first try: Unhandled exception: object.Exception can't complete call to TLS_method at requests\ssl_adapter.d(248) which says it can't find the lib. I renamed ssleay32.dll to libssl32.dll and it then passed. I am getting http 404 error though ;/ I turned off cert though, which may be the reason, I have no idea. Seems to be working through.
Re: How to curl!
On Tuesday, 1 May 2018 at 23:02:39 UTC, Dr.No wrote: On Tuesday, 1 May 2018 at 22:51:01 UTC, IntegratedDimensions wrote: [...] those dlls: libeay32.dll libssl32.dll ssleay32.dll I'm sure they would be installed with whatever [...] I don't think so. IIRC, when I used D+curl I needed to download them manutally. This is always the case with Qt. Even using windeployqt with --webkit2 flag I still need to copy those dlls to application binary folder. [...] It isn't always the case if the dll is dynamic loaded, it might fail quietly, for example, if you deploy an Qt application with QWebKit missing those Open SSL dlls, an page with https protocol just doesn't open and didn't show any error at all. To find out whether some referenced dll by your executable is missing, people use Dependence Walker: http://www.dependencywalker.com/ I don't think this is the problem. If I use get on https://www.google.com it works fine but if I use get on https://www.googleapis.com/youtube/v3/channels it fails so it is site dependent.
Re: How to curl!
On Tuesday, 1 May 2018 at 22:08:50 UTC, Dr.No wrote: On Tuesday, 1 May 2018 at 21:57:22 UTC, IntegratedDimensions wrote: Trying to curl basic stuff but std.net.curl isn't cooperating: curl "https://www.googleapis.com/youtube/v3/channels; -G -d part=contentDetails -d forUsername=test -d key=somekey [...] Just a wild guess, do you have the SSL dlls in the same folder as your executable or (less likely) in your PATH? What SSL dlls? I'm sure they would be installed with whatever installation uses them. ssleay32.dll comes with dmd2 and it is in the path, if that is what you are talking about. If a dll was missing though and that was the problem then it needs to state that it is a missing dll rather than some other issue.
How to curl!
Trying to curl basic stuff but std.net.curl isn't cooperating: curl "https://www.googleapis.com/youtube/v3/channels; -G -d part=contentDetails -d forUsername=test -d key=somekey import std.stdio; import std.net.curl; int main(string[] argv) { auto http = HTTP(); http.caInfo("cacert.pem"); // cacert.pem installed in the bin dir http.handle.set(CurlOption.ssl_verifypeer, 1); auto content = post("https://www.googleapis.com/youtube/v3/channels;, ["part" : "contentDetails", "forUsername" : "test", "key" : "somekey"], http); return 0; } I either get the error Unhandled exception: std.net.curl.CurlException Peer certificate cannot be authenticated with given CA certificates on handle at std\net\curl.d(4343) or, when verifypeer is 0, Unhandled exception: std.net.curl.HTTPStatusException HTTP request returned status code 404 (Not Found) But the command line version works fine. (of course, if you want to test you must use a valid key and youtube user name. This is one of the reasons I hate D ;/ I've spent more time trying to get std.net.curl to do something that just works from the command line.
Re: Making an .exe that executes source file inside itself.
On Friday, 27 April 2018 at 14:57:34 UTC, BoQsc wrote: On Friday, 27 April 2018 at 04:30:32 UTC, IntegratedDimensions wrote: On Thursday, 26 April 2018 at 06:18:25 UTC, BoQsc wrote: On Wednesday, 25 April 2018 at 20:44:10 UTC, u0_a183 wrote: On Wednesday, 25 April 2018 at 19:54:26 UTC, BoQsc wrote: On Wednesday, 25 April 2018 at 19:43:31 UTC, Jonathan M Davis wrote: [...] Thank you Jonathan for a response. I was aware of this, and it certainly perfectly works where command line/terminal interface is the main tool to control the system, a good example would be linux/gnu distributions and macOS. However in Windows while installing D language, I noticed that .d source file extension is not associated with neither D compiler (dmd.exe) nor D script interpretator (rdmd.exe) So they can't be ran directly by clicking on those, nor they have any icons that show that these source codes are actually executable. This is a huge problem, because people that are not aware of D language migh be harder to understand that source script could be executable, at least - without help from some more experienced user. If the purpose is to make scripts run by clicking them you can assign a file type to .d files. On Windows 10. https://www.digitaltrends.com/computing/how-to-set-default-programs-and-file-types-in-windows-10/ Doing so would make the script engine the default program instead of a text editor so you might not want to. Or maybe assign .dxe and changing the filename before running. Executable has executable file type for a reason - it self-implies that the main function of the file - is to be executed. The problem with making source code files executable is that, source code files, might not always be monolithic executable code, but a part of a bigger interconnected program. That would lead to partily working program execution, and most of the times guess work of whether source code file was supposed to be executed. This is wrong. All code must be included. All library source code is included. If this is infeasible then simply the binaries are included. It would be no different than dynamic linking that already exists. It doesn't create any new problems. Sure certain things would need to be worked out properly to optimize the experience, but that is obvious. One can't make everything perfect though and one shouldn't expect it... The clear alternative would be: .exe file on which, if rightclicked - would open context menu showing posibility of "edit/improve this executable". Which would not create additional problem mentioned above. Yes, all the source code and required source code to make everything work must be included. And where would all the code mentioned before should be stored? It must be stored in a an single self extracting archive, self executing archive, that is self-implying that it is an executable code, which means it can't be .d file extension, but an .exe file extension. (or any other, if anyone come up with more common or self explaining extension name) If we use the same .d file extension on this self-executable, self-extracting archive, it would confused people weather it is executable or some novice programmer's written module/script. No, it would have to be an exe on windows. an exe is basically a self executing container. Almost all exe's only contain the binary but they can contain data. For example, zip files can be saved as self-unzipping executable. It is not a big deal to package the data in the exe and make it all work. Initially, it is not necessary to worry about. What happens is that the actual initial binary that will run will essentially decide what needs to be done and unpack everything and deal with it. You can think of the exe as a small file system that contains all the files necessary and a binary that handles whatever needs to be done which is run by the OS. Several binaries in the file would be things like the IDE/debugger and the compiled source code. If the user just wants to run the app like any normal app then the compiled source code would be extracted either to a temp exe file or to memory and ran. (so the initial process just does some unpacking and passes control) If debugging and modification is to be done then the initial process will have to do more work such as compile the source with debugging symbols, special hooks, and all that. The files would have to be extracted in memory or on disk. The ide would be ran, etc. For example, android apps are actually special zip files. All of this stuff is childs play. The real work is having a proper design that integrates everything well. Nothing would be technically challenging but just a lot of work to get everything done. I do think that apps that were designed to be used this way would need to be structured and designed in a way that makes it conducive to debugging and modifying easily and quickly.
Re: Making an .exe that executes source file inside itself.
On Thursday, 26 April 2018 at 06:18:25 UTC, BoQsc wrote: On Wednesday, 25 April 2018 at 20:44:10 UTC, u0_a183 wrote: On Wednesday, 25 April 2018 at 19:54:26 UTC, BoQsc wrote: On Wednesday, 25 April 2018 at 19:43:31 UTC, Jonathan M Davis wrote: On Wednesday, April 25, 2018 19:19:58 BoQsc via Digitalmars-d-learn wrote: So there has been idea I've got for around few months now: making a software which executable would contain a source file. A software that anyone could modify by opening an executable and quickly change a few lines of it, rerun an executable, see the changes. Could this be easily possible with D language, considering that sources files can be ran without long slow compilation process? The normal way to do that is to just write a script. In the case of D, you can just use rdmd to do it. e.g. if you're on a POSIX system, just put #!/usr/bin/env rdmd at the top of your .d file and chmod it so that it's executable, and it'll run like any other script. - Jonathan M Davis Thank you Jonathan for a response. I was aware of this, and it certainly perfectly works where command line/terminal interface is the main tool to control the system, a good example would be linux/gnu distributions and macOS. However in Windows while installing D language, I noticed that .d source file extension is not associated with neither D compiler (dmd.exe) nor D script interpretator (rdmd.exe) So they can't be ran directly by clicking on those, nor they have any icons that show that these source codes are actually executable. This is a huge problem, because people that are not aware of D language migh be harder to understand that source script could be executable, at least - without help from some more experienced user. If the purpose is to make scripts run by clicking them you can assign a file type to .d files. On Windows 10. https://www.digitaltrends.com/computing/how-to-set-default-programs-and-file-types-in-windows-10/ Doing so would make the script engine the default program instead of a text editor so you might not want to. Or maybe assign .dxe and changing the filename before running. Executable has executable file type for a reason - it self-implies that the main function of the file - is to be executed. The problem with making source code files executable is that, source code files, might not always be monolithic executable code, but a part of a bigger interconnected program. That would lead to partily working program execution, and most of the times guess work of whether source code file was supposed to be executed. This is wrong. All code must be included. All library source code is included. If this is infeasible then simply the binaries are included. It would be no different than dynamic linking that already exists. It doesn't create any new problems. Sure certain things would need to be worked out properly to optimize the experience, but that is obvious. One can't make everything perfect though and one shouldn't expect it... The clear alternative would be: .exe file on which, if rightclicked - would open context menu showing posibility of "edit/improve this executable". Which would not create additional problem mentioned above.
Re: Making an .exe that executes source file inside itself.
On Wednesday, 25 April 2018 at 19:19:58 UTC, BoQsc wrote: So there has been idea I've got for around few months now: making a software which executable would contain a source file. A software that anyone could modify by opening an executable and quickly change a few lines of it, rerun an executable, see the changes. Could this be easily possible with D language, considering that sources files can be ran without long slow compilation process? I had a similar idea a few months ago too, coincidence? The idea is that all apps have the source code embedded so that they can be debugged and modified by the user at will. Each app has a built in IDE and debugger(or can trigger an external one for space). When an error occurs it will jump to the debugger for debugging purposes. If some functionality is to be modified(e.g., change the size of a button or add some new feature) the user can trigger the IDE(hot key) to proceed. The point of having it all self contained is to allow future revision and debugging without having to worry about version issues. The point of the debugging is so the user can fix bugs that plague software. While on the whole most software may work for most users, it is very annoying when some minor bug prevents a program from working for a specific user. Many more people know how to program than ever and it will only become more and more common. Also, with such capabilities, the user can add additional functionality. It is very annoying when programs don't support simple stuff. A few lines of code could make the program much more effective for a user that wants to do something that was not thought of if they could just add it. e.g., even just display something, change the location of a widget, or modify how a text file is read so it can support a new format. One can argue that platforms such as Linux make this easy... but only marginally. If one get actually get the code to compile without having to waste many hours, one must also generally sift through the code to find the relevant parts then try and understand them. Usually because of the trial and error process is long this generally is a deterrent for "normal" people with "normal" lives. If apps are properly structured with such goals in mind then it would be of great benefit, although only a few of us like you and me have the wherewithal to extrapolate out. It would not be difficult to do(it is more about organization than about technological problem solving). With proper ide design, debugger, and such, one could make app writing self contained, so to speak. That is, the IDE and debugger are used directly to write the program instead of using the traditional methods such as vim, emacs, visual studio, coedit, etc. What is packaged in an binary are the IDE Debugger Profiling Source Code(with history, VCS included) Compiled Code(possibly optimized version) Debugging Data Scripting Generally, without debugging, the executable just runs the compiled code as if it were a normal app. When triggered, the ide/debugger can be brought up that takes over and displays the desired source code(triggers can be used). I believe the main issues for proper development would be the ability for quick code replacement(hot swapping, injection, etc) which is tricky since some code would require a full restart which will slow things down. Most of the other programs are just gluing everything together and providing certain mechanisms that allow for robustness such as being able to replace the IDE or debugger, extract the source code for repackaging. While it would be time consuming to implement well it would be very useful. There are many many times I have used programs that simply do not function correctly or are missing simple functionality that would take me a just a few minutes to write a few lines of code to fix. Having the above would make it possible to do. One could also then "upload" patches/fixes/enhancements to the cloud or download others. This way people can tailor applications to their own use rather than being stuck with what the developers(which generally are somewhat clueless as their main goal is to ship the product rather than provide all the functionality their users want).