What is pure used for?
My understanding is that pure is used for compiler optimization in loops and expressions. It leaves out multiple calls if it figures out it is not needed. Is pure used for anything else? int * pureFunction() 1) the pointer needs to be the same. 2) the value that the pointer points to needs to be the same. I call this the "value of interest" with relation to pure. The pointer doesn't matter. 3) both the pointer and the value the pointer is pointing too needs to be the same. pureCalloc() satisfies (2) pureMalloc() violates everything. Does the D compiler do any optimizations?
Reference Counted Class
Would reference counted classes by default be too much of a change? Is it a bad idea? Currently there a changes in the language where you can avoid the reference count, right? Combination both the rc and the stop-the-world gc, for the cycles.
Re: dip1000 rule 5
On Monday, 26 November 2018 at 09:10:23 UTC, sclytrack wrote: On Sunday, 25 November 2018 at 19:22:36 UTC, sclytrack wrote: There are 4 rules listed. https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md What is rule 5? int* global_ptr; void abc() { scope int* a; int* b; scope int* c = a; // Error, rule 5 scope int* d = b; // Ok int* i = a;// Ok, scope is inferred for i global_ptr = d;// Error, lifetime(d) < lifetime(global_ptr) global_ptr = i;// Error, lifetime(i) < lifetime(global_ptr) int* j; global_ptr = j;// Ok, j is not scope } --- Are the following assumptions correct? lifetime(a) < lifetime(b) Means that b is older and lives longer than a. Or better, the data that b is pointing to is older and lives longer than the one that a is pointing too. With the exception of the null pointer which gets unlimited lifetime because it does not corrupt memory. --- scope int * a; The variable gets unlimited lifetime because the value it is pointing is assigned null. And that throws exception when trying to access the memory and because it does not corrupt memory it is assigned unlimited lifetime. Also once a variable is assigned unlimited lifetime, then it retains that unlimited lifetime during the entire reachability of the variable. scope int * c = a; works The above is allowed. You are assigning a variable that according to the compiler has unlimited lifetime. Therefore the variable c will be handled like it has unlimited lifetime by the compiler. lifetime(c) <= lifetime(a) The dip talks about longer and shorter, but is equal okay too? int * c = a; works (compiles without error and is inferred scope) The above can not be inferred because scope is only inferred when it is assigned a limited lifetime. So it is an error. Rule number 2 of the DIP1000 between quotes "2. A variable is inferred to be scope if it is initialized with a value that has a non-∞ lifetime." I made an error here. Once scope always scope. And will infer scope as much as possible. Rule two is more for local variables that haven't even been marked with scope. A pointer to them needs to be inferred scope. --- How is a person able to understand this DIP? ./dmd -betterC -dip1000 test.d --- How many DIP manager are there? I'll assume single person. When is a DIP assigned a number? ---
Re: dip1000 rule 5
On Sunday, 25 November 2018 at 19:22:36 UTC, sclytrack wrote: There are 4 rules listed. https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md What is rule 5? int* global_ptr; void abc() { scope int* a; int* b; scope int* c = a; // Error, rule 5 scope int* d = b; // Ok int* i = a;// Ok, scope is inferred for i global_ptr = d;// Error, lifetime(d) < lifetime(global_ptr) global_ptr = i;// Error, lifetime(i) < lifetime(global_ptr) int* j; global_ptr = j;// Ok, j is not scope } --- Are the following assumptions correct? lifetime(a) < lifetime(b) Means that b is older and lives longer than a. Or better, the data that b is pointing to is older and lives longer than the one that a is pointing too. With the exception of the null pointer which gets unlimited lifetime because it does not corrupt memory. --- scope int * a; The variable gets unlimited lifetime because the value it is pointing is assigned null. And that throws exception when trying to access the memory and because it does not corrupt memory it is assigned unlimited lifetime. Also once a variable is assigned unlimited lifetime, then it retains that unlimited lifetime during the entire reachability of the variable. scope int * c = a; The above is allowed. You are assigning a variable that according to the compiler has unlimited lifetime. Therefore the variable c will be handled like it has unlimited lifetime by the compiler. lifetime(c) <= lifetime(a) The dip talks about longer and shorter, but is equal okay too? int * c = a; The above can not be inferred because scope is only inferred when it is assigned a limited lifetime. So it is an error. --- How is a person able to understand this DIP? --- How many DIP manager are there? When is a DIP assigned a number? ---
Re: dip1000 rule 5
On Sunday, 25 November 2018 at 19:49:03 UTC, Stanislav Blinov wrote: On Sunday, 25 November 2018 at 19:22:36 UTC, sclytrack wrote: There are 4 rules listed. ... What is rule 5? ... Wouldn't you call it D3 because of the name mangling of DIP1000 once activated by default? That "rule 5" looks like a straight up mistake. As for D3... IMHO, no, not by a long shot. There's 1014 and 1016, 1008, there's `shared`, there are improved move-assignments, there's `__mutable` and `@__future`, there are tons of issues in Bugzilla, the standard library is long overdue for a huge look-over... Did DIP1000 go through any review process? I'm seeing it is a draft. https://github.com/dlang/DIPs/blob/master/PROCEDURE.md Keeps talking about a Drafts subdirectory. I don't see any directory named "Drafts". I only see accepted archived //old stuff rejected
dip1000 rule 5
There are 4 rules listed. https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md What is rule 5? int* global_ptr; void abc() { scope int* a; int* b; scope int* c = a; // Error, rule 5 scope int* d = b; // Ok int* i = a;// Ok, scope is inferred for i global_ptr = d;// Error, lifetime(d) < lifetime(global_ptr) global_ptr = i;// Error, lifetime(i) < lifetime(global_ptr) int* j; global_ptr = j;// Ok, j is not scope } Also it says scope inferred for i int * i = a; So inferred, does that mean? scope int *i = a; It looks very similar to the error rule 5. scope int* c = a; // Error, rule 5 When DIP1000 is in and copy constructors, then the language is more or less finished? Wouldn't you call it D3 because of the name mangling of DIP1000 once activated by default?
Re: Copy Constructor DIP
On Friday, 13 July 2018 at 11:02:57 UTC, RazvanN wrote: [...] Indeed, but this was the source of the problem also, because you could modify immutable fields that way. [...] Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks! The difference between a copy constructor and opAssign is how the type checking is performed. This leads to situations where a copy constructor is not suitable as an assignment operator. However, if a copy ... What are your opinions on this? What about going the other way? Can you use the unqualified opAssign as the unqualified copy constructor? I assume these @implicit copy constructors are normal constructors.
multiqualifier
I'm going to post this in learn in order not to disturb "the guys". Multiqualifiers --- Warning: Stop reading if you don't have time. Tail-const rant in disguise. (1) Going from immutable to mutable, one layer deep. --- In the D programming language const(int ***) means the same as const int *** const int *** source; //head-const body-tail-const or just const const (int **)* destination;//head-mutable body-tail-const destination = source; //works with ldc2 (1.2.0) Assigning the source to the destination is possible and the head which was initially const becomes mutable. This is possible because a copy is made of that head pointer. const int *** source; //const const (int *)** destination;//head-body-mutable tail-const //error destination = source; //error Assigning the source to the destination is not possible because you would have to alter the initial head. To clarify with invalid D code (no-code). //warning: Fake D code const (int ***) source; const (int *)dup(*)dupchange(*) destination; const (int ) source; const (int *)dup(*)dupchange(**) destination; So we don't do this altering of the values and go only one layer deep. The D programming language is even able to figure this one layer deep out with regard to structs. struct HeadMutableTailConst { const (int*) * pMutableHeadPointer; //head-mutable body-tail-const } const(HeadMutableTailConst) source; HeadMutableTailConst destination; //const-head to mutable-head with destination body-tail-const destination = source; //works with ldc2 (1.2.0) The important part is that the head is either mutable or const and the rest must always be body-tail-const. 1.a) Naming --- Starting to realize I need a different wording. The first pointer on the right is the head and the second pointer is the body. const(int ***)*** tailConst; //tail-const const(int **) headTailConst; //head-const body-tail-const const(int *)* bodyTailConst; //head-mutable body-tail-const Which means that body-tail-const can be either const(int **) headTailConst; //head-const body-tail-const const(int *)* bodyTailConst; //head-mutable body-tail-const body-tail-const completally ignores the head. (2) Going the other way. mutable can be assigned to const, and so does immutable. int *** source; const(int **)* destination; destination = source; //works The destination needs to be body-tail-const not just tail-const. int source; const(int*)*** destination; destination = source; //error struct Container1 { int * data; } struct Container2 { const(int) * data; } Container1 source; Container2 destination; destination = source; //error Both cases "mutable to const tail" and "const head to mutable head" with full BODY-TAIL-CONST (or recently head-mutability) (3) Multiple tails -- 3.a --- A user defined type can have multiple tails so it should have multiple qualifiers, one for each tail. I've numbered them here with $1 and $2 in fake D code or no-code. //warning: Fake D code struct MultiTail { qual$1 (int) * a; //Mandatory BODY-TAIL-QUAL$1 or head-body-tail qual$2 (int) * b; //Mandatory BODY-TAIL-QUAL$2 this()(const, immutable) { //qual$1 is const //qual$2 is immutable } } (const, immutable) MultiTail a; //impossible D code. I'm going to be verbose so. The first "$1" becomes "const" and the second "$2" becomes immutable. Field "a" defined as const(int) * a; and the second field "b" is immutable(int) * b; I will use (const) for the multiqualifier between those (). (const) vs const 3.b --- warning: fake D code struct MultiTail { qual$1 (int) * a; //mandatory applied to body-tail or head-body-tail qual$1 (int) * b; qual$1 (int) * c; qual$2 (int) * z; } (const, immutable) MultiTail a; //impossible D code. A qualifier in a multitail qualifier applying to more tails then the number of qualifiers in a multiqualifier. 3.c --- Can you determine that a type is passable to a routine by just looking at the multiqualifier? (immutable, immutable) MultiTail parameter; void routine( (const, immutable) MultiTail a) { } 3.d classes Since classes are reference types. class MultiQualifiedType { qual$1(int) field; //mandatory on head-body-tail and not just body-tail for classes qual$2(int *) other; } (immutable, const) MultiQualifiedType a; Similarly for structs //-- struct HeadQualified { qual$1(int) field; } (const) HeadQualified * a; //a is body-tail-const //-- struct HeadMutableBodyTailQualified { qual$1(int) * field; } (const) HeadMutableTailQualified * a; //a is not body-tail-const error /-- 4.
Re: Implementing tail-const in D
On Monday, 29 January 2018 at 13:07:05 UTC, Simen Kjærås wrote: On Thursday, 25 January 2018 at 21:33:10 UTC, Simen Kjærås wrote: On Thursday, 25 January 2018 at 19:54:55 UTC, H. S. Teoh wrote: In fact, if the standard implementation of opHeadMutable is basically the same across all types (or most types), it could even be provided as a mixin template in the library, then all you have to do is to `mixin headMutable` or something along those lines, and off you go. I believe this should be possible I wrote up a more formal description of what I'm suggesting: https://gist.github.com/Biotronic/c6eefeb9796309360a5e8696d91d924d -- Simen @headUnqualified struct HeadUnqualifiedType1 { HeadUnqualifiedType2 field; } tailQualifierHeadUnqualified(const) HeadUnqualifiedType1 a; //Stupid opaque data types.
Re: An idea for commercial support for D
On Monday, 12 January 2015 at 06:30:20 UTC, Zach the Mystic wrote: Convenience, to me, is one-click downloading from the home page, one click installation, and full IDE support akin to what Apple, Microsoft and any other behemoth has done for their language. The language has nothing to do with it. D can't even remotely compete with these languages in terms of convenience. It needs a new slogan, and it can't get one until it knows what it is. Here's a suggestion: "A Language for Programmers". It would obviously need to be vetted by the big wigs, but from my perspective, it's already a real brand without any extra work. I wonder if they'll agree with me? pgModeler (for postgres) sells the binaries for a small price. The source code is GPL so it is available in linux distributions. https://www.pgmodeler.com.br/ Text from their website: "pgModeler is an open source software and you can get its source code anytime if you want to compile it for yourself. As a facility, we provide compiled binary packages at a really small price. Also, if you're interested in evaluate a binary package, you can get a demo copy before proceed with the purchase. Since this is an independent project by purchasing any binary package you'll help to keep its development alive and at full speed! " There you go, full speed.
Re: DIP1000: Scoped Pointers (Discussion)
On Thursday, 11 August 2016 at 21:28:57 UTC, sclytrack wrote: On Wednesday, 10 August 2016 at 20:36:38 UTC, Dicebot wrote: [...] There is confusion between what lifetime and visibility in the DIP. (Well, I am confused) [...] What are those puppy dogs doing there? I don't have a gravatar account.
Re: DIP1000: Scoped Pointers (Discussion)
On Wednesday, 10 August 2016 at 20:36:38 UTC, Dicebot wrote: http://forum.dlang.org/post/pqsiqmkxenrwxoruz...@forum.dlang.org The first DIP has just landed into the new queue. It is a proposal from language authors and thus it bypasses usual nitpicking process and proceeds straight to requesting community (your!) feedback. Essentially, it is an attempt to solve reference lifetime problem by extending implementation of `scope` keyword. Proposal text: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md Few notes: - Please submit pull requests to adjust the markdown document if you want to propose any improvements (mentioning @WalterBright and @andralex for confirmation). - The proposal refers to a number of other documents and it is recommended to become familiar at least briefly with all of them. - At this point the question I'd personally suggest to be evaluated is "does this proposal enable enough useful designs?". A good check would be to try taking some of your projects and see if having DIP1000 approved and implemented could improve them. There is confusion between what lifetime and visibility in the DIP. (Well, I am confused) 1) infinite lifetime null int * p; The lifetime(p) is infinite while the visibility(p) starts here. It seems to be the lifetime of p is determined by the value assigned to it, which in this case is null and the lifetime of lifetime(null) is infinite. 2) Fundamentals of scope. This declares 4 scope rules as of 11 August of which the first rule is: "A scope variable can only be initialized and assigned from values that have lifetimes longer than the variable's lifetime" int global_var; int* global_ptr; void bar(scope int* input); void fun1() { scope int* a = _var; // OK per rule 1, lifetime(_var) > lifetime(a) int b; a = // Disallowed per rule 1, lifetime() < lifetime(a) Shouldn't the rule be: "A scope variable can only be initialized and assigned from values that have lifetimes longer than the variable's VISIBILITY" As in the case above. What is the lifetime(a) "scope int *a" when the _var has not yet been assigned to it? It doesn't have a lifetime yet, it gets the lifetime from _var. Peter
Re: Head Const
On Wednesday, 17 February 2016 at 12:46:08 UTC, Jonathan M Davis wrote: but violate the type system by casting away const and mutating, not realizing that unlike C++, it's undefined behavior in D. Regardless of whether Walter's (and thus D's) stance on const is the right one, it clearly doesn't jive with what a lot of folks (particularly those from C++) are looking for or expecting. - Jonathan M Davis struct (bla1, bla2) Test { int rc; bla1 int number; (bla2) Payload payload; void doSomething() (shared, immutable) { } } (shared, immutable) Test obj; bla1 becomes shared and bla2 becomes immutable, but the payload might not be immutable because it is (bla2) instead of just bla2. --- Can it be made in a way that the blablas do not participate in the static if? Could "shared", "immutable" be separated from the type int, float? (shared, immutable) Test!(int, float) obj; --- I did some "const(immutable) int" and the the compiler says basic type expected. What is the basic type from "const(shared, immutable)", would that be "const(shared const, const)"? And then the basic type from "const(const, immutable)" would be "const". --- Also would it be possible to determine the implicit conversion rules based solely on these qualifiers and not on the content of the object? (const, const) Test t = new (const, immutable) Test(); const Test t = new (const,const) Test(); ---
Re: [dlang.org] Let's talk about the logo
On Friday, 22 January 2016 at 20:28:57 UTC, anonymous wrote: On 22.01.2016 20:53, ronaldmc wrote: I don't want to start a war, but this isn't community? I mean aren't we trying to make things better, because the way you said it seems like a dictatorship. It's dictatorship insofar as Walter and Andrei have veto power. If they don't want something in, it doesn't go in. I don't think this is a problem in practice. If it was, the community could always fork the project and then play by their own rules. And of all things, the logo wouldn't be a good reason to divide over, in my opinion. Just use all 4 logos. Change them at every new D release or something. I like a bit change. My desktop background also changes a bit.
Re: Website contains a virus?
On Thursday, 21 January 2016 at 18:46:15 UTC, Dominikus Dittes Scherkl wrote: Hi. I'm using Norton Security from Symantec, and it claims that the current compiler dmd-2.069.2.exe is infected with the "Trojan.Gen.2". Not a particularly harmful virus, but nevertheless I hope that's not true or you can fix that rather soon! Does this pose a problem for the linux variant?
Re: Safe reference counting cannot be implemented as a library
On Monday, 2 November 2015 at 09:56:14 UTC, Ola Fosheim Grøstad wrote: On Sunday, 1 November 2015 at 22:04:51 UTC, deadalnix wrote: On Sunday, 1 November 2015 at 20:55:00 UTC, Martin Nowak wrote: On 11/01/2015 09:51 PM, Martin Nowak wrote: http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study The last post on the study group ended a while ago. Does that mean it is not going forward. It suggest to talk about lifetime. Is that with or without talking about reference counting simultaneously? What approach will be taken? 1) Will for every assignment to the object a hidden temporary be created by the compiler to keep the object alive. RCObject obj = new RCObject(); Item item = obj.items[x]; _temp1 = obj; //The compiler inserts this automatically and is not seen. obj=new RCObject(); 2) Will you disable the item by some magical way? Item might still be valid. RCObject obj = new RCObject(); ... Item item = obj.items[x]; obj=new RCObject(); //item is no longer accessible beyond this point. writeln(item); //error 3) Somehow disable the RCObject for the duration of the borrowing. with(Item item = RCObject.items[x]) { writeln(item) } 4) Solved by eating pizza or watching a movie ... Maybe the discussion should be a tree.
Re: Safe reference counting cannot be implemented as a library
On Thursday, 29 October 2015 at 20:31:49 UTC, Zach the Mystic wrote: On Tuesday, 27 October 2015 at 18:10:18 UTC, deadalnix wrote: I've made the claim that we should implement reference counting as a library many time, so I think I should explicit my position. Indeed, RC require some level a compiler support to be safe. That being said, the support does not need to be specific to RC. On fact, my position is that the language should provide some basic mechanism on top of which safe RC can be implemented, as a library. The problem at hand here is escape analysis. The compiler must be able to ensure that a reference doesn't escape the RC mechanism in an uncontrolled manner. I'd like to add such mechanism to the language rather than bake in reference counting, as it can be used to solve other problem we are facing today (@nogc exception for instance). Here's a link to the reference safety system I proposed some months ago: http://forum.dlang.org/post/offurllmuxjewizxe...@forum.dlang.org I'm very far from having the expertise needed to know whether it would be worth its weight in practice, but it was better to write it out than to keep it bottled up in my head. I hope it will be of some use. 1) Assignment to RCObject - { RCObject obj = new RCObject() Item item1 = obj.items[x]; _temp1 = obj; obj = new RCObject(); _temp2 = obj; obj = new RCObject(); } 2) Entering a subscope -- With this I mean entering a subscope that assigns to the RCObject. { RCObject obj2 = new RCObject() RCObject obj = new RCObject() _temp1 = obj; //(2) Entering a subscope { _temp2 = obj; //(1) Assignment to RCObject obj = new RCObject(); } } 3) Leaving a scope. --- The Item is not reference counted. { Item item1; { RCObject obj = new RCObject(); //item1 = obj.items[x]; //(3) Leaving subscope } } { RCObject obj = new RCObject(); Item item1; _temp1 = obj; //(2) Entering subscope { _temp2 = obj; //(1) Assignement to RCObject obj = new RCObject(); //item1 = obj.items[x]; //(3) Leaving subscope _temp3 = obj; //(1) Assignement to RCObject obj = new RCObject(); } } 4) RCObject joins a scope - { _temp1 = obj.field.rcobject;//(4) RCObject joins current scope. Item item1 = obj.field.rcobject.a.items[0]; //_temp1; //(2) Entering subscope { _temp3 = obj.field.rcobject;//(1) Assignment to RCObject obj.field.rcobject = new RCObject(); } _temp4 = obj.field.rcobject;//(4) RCObject joins current scope. item1 = obj.field.rcobject.a.items[2]; }
Re: Object.factory() and exe file size bloat
On Friday, 21 August 2015 at 05:24:52 UTC, BBasile wrote: On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote: This function: http://dlang.org/phobos/object.html#.Object.factory enables a program to instantiate any class defined in the program. To make it work, though, every class in the program has to have a TypeInfo generated for it: ... Other alternatives would be a pragma or an attribute to disable TypeInfo generation. @NoTI. 1. Since it is compiled in the {$M+} state, the compiler generates RTTI (Run-Time Type Information) for it and all classes that descend from it. http://freepascal.org/docs-html/rtl/classes/tpersistent.html 2. Published properties are included in RTTI, public properties aren't http://stackoverflow.com/questions/3157648/whats-the-difference-between-public-and-published-class-members-in-delphi
Re: Why aren't you using D at work?
On Thursday, 16 July 2015 at 12:04:11 UTC, Sönke Ludwig wrote: Am 15.07.2015 um 18:06 schrieb Poyeyo: On Thursday, 28 May 2015 at 14:38:51 UTC, Manu wrote: I've been using D in all my personal projects for years now, but I lament coding C at work every day, and I pine for salvation. I seem to have reasonable influence in my workplaces, and I suspect I could have my workplace adopt D, but when considering the notion with other staff, we always seem to encounter hard blockers to migration that stop us in our tracks. [...] Lack of a complete MySQL driver. No DECIMAL support that I know of. Lack of MySQL support in vibe.d. The mysql-native driver is fully vibe.d compatible. What is the postgresql variant for vibe.d? There are so many database api's for D.
Re: What wrong?
On Tuesday, 5 May 2015 at 07:41:04 UTC, sclytrack wrote: On Monday, 4 May 2015 at 01:03:43 UTC, Fyodor Ustinov wrote: On Saturday, 2 May 2015 at 20:46:32 UTC, Dennis Ritchie wrote: On Saturday, 2 May 2015 at 19:38:01 UTC, Fyodor Ustinov wrote: I see it by the lack of 42. :) But why is this receive breaks down? import std.stdio; import std.variant; struct SoMany { int number = 10; ~this() { writeln(number); } } void main() { Variant v = SoMany(); } DMD64 D Compiler v2.067.1 10 10 10 10 gdc (Debian 4.9.2-10) 4.9.2 10 10 For DMD I'm getting 4x10 and for gdc 2x10
Re: What wrong?
On Monday, 4 May 2015 at 01:03:43 UTC, Fyodor Ustinov wrote: On Saturday, 2 May 2015 at 20:46:32 UTC, Dennis Ritchie wrote: On Saturday, 2 May 2015 at 19:38:01 UTC, Fyodor Ustinov wrote: I see it by the lack of 42. :) But why is this receive breaks down? import std.stdio; import std.concurrency; struct Answer { int number = 10; ~this() { writeln(number); } } void threadRoutine() { receive( (int value){ } //handle question ); ownerTid.send( Answer() ); //answer } void main() { Tid childId = spawn(threadRoutine); childId.send(100); //question receive((Answer t) {}); //answer } //DMD64 D Compiler v2.067.1 /* 10 10 10 10 10 10 10 10 10 10 10 7080544 10 10 10 */
Re: error with std.range.put - readN
On Monday, 4 May 2015 at 14:33:23 UTC, Baz wrote: the following program fails because of the `put` function : --- import std.stdio; import std.range; size_t readN(T, Range)(ref Range src, ref Range dst, size_t n) if (isInputRange!Range isOutputRange!(Range, T)) { size_t result; while(1) { if (src.empty || result == n) break; put(dst, src.front()); // here src.popFront; ++result; } return result; } void main(string[] args) { int[] src = [1,2,3]; int[] dst = [0]; auto n = readN!int(src, dst, 2); writeln(dst); } --- If i replace `put` by a cat op (`~`) it works, however the cat op only works here because i test the template with two int[]. What's wrong ? I believe the put(R,E) calls the doPut(R, E) private void doPut(R, E)(ref R r, auto ref E e) { //... else static if (isInputRange!R) { static assert(is(typeof(r.front = e)), Cannot nativaly put a ~ E.stringof ~ into a ~ R.stringof ~ .); r.front = e; r.popFront(); } //... } So basically you put elements into the list until it is empty. import std.stdio; import std.range; void main() { int [] list = new int [10]; writeln(list);//10 zeros list.front = 5; //1 five and 9 zeroes writeln(list); list.popFront(); //9 zeroes left. writeln(list); }
Re: Interrogative: What's a good blog title?
On Tuesday, 28 April 2015 at 15:33:52 UTC, ixid wrote: Please let me know of any thoughts you might have! Thanks, Andrei Andrei to the Drescu D to the rescue The road to programming heaven. W A with a backpack, some desert landscape.
o!(const(T)) parameter.
I want a function with parameter o!(const(Form)) to accept both o!(Form) and o!(immutable(Form)) Is there a way to do it? import std.stdio; import std.traits; class Form { int number = 10; } struct o(T) { T data; this(T data) { this.data = data; } o!(const(Unqual!(T))) constify() const { return o!(const(Unqual!(T)))(data); } alias constify this; } void hello(o!(const(Form)) frm) { writeln(frm.data.number); writeln(typeof(frm.data).stringof); } void main() { writeln(This application works nicely); auto frm = o!(Form) (new Form()); // auto ifrm = o!(immutable(Form)) (new immutable Form()); hello(frm); // hello(ifrm); }
Re: o!(const(T)) parameter.
It works when you exclude the recursive alias this: static if(!is(T == const)) alias constify this; Your original program crashes the compiler, which is always a bug. I filed an issue: https://issues.dlang.org/show_bug.cgi?id=14499 Thank you, very much.
Re: using exceptions in @nogc
On Tuesday, 31 March 2015 at 01:40:54 UTC, weaselcat wrote: was this ever solved? I did some research and saw static immutable ones suggested a few times, but they can't be chained AFAIK. Reference counted exceptions. Not solved.
Re: DTanks Alpha
On Saturday, 21 March 2015 at 02:39:23 UTC, Rikki Cattermole wrote: On 21/03/2015 10:55 a.m., Kingsley wrote: In preparation for the London D meetup I have got the DTanks robot battle framework into the first alpha release state - good enough to use at the meetup anyway. https://github.com/masterthought/dtanks --K Are you aware of what turtles are? Because this looks pretty close api wise, to be used for it. Logo?
Re: is eC alot like D?
On Wednesday, 11 March 2015 at 04:10:51 UTC, Taylor Hillegeist wrote: On Wednesday, 11 March 2015 at 03:55:21 UTC, Rikki Cattermole wrote: On 11/03/2015 4:16 p.m., Taylor Hillegeist wrote: So I found http://ec-lang.org/ it seems alot like D, But it has a company backing it. It just seems interesting. There is almost no meta programming support. Let alone CTFE. And no generics in the form of e.g. Java's is not the same as D's meta-programming support. Yes, D is a very powerful language with a boatload of features. eC almost seems like a subset. but what I find fascinating is the infrastructure built around it. Of course when someone's full time job is to build infrastructure, I tends to happen more predictably. But like all things in life you have to take the good, and carry it with you into the future. I bet there is alot we can learn from eC. I wonder how compatible the two languages are, I have been experimenting with language to language porting techniques, every language is in similar in some way to another, but to varying degrees. A quote from Jerome on the eC forum. eC is yet another multiparadigm procedural/object-oriented language which has C for its foundation. This puts it alongside Java, C++, C#, D, Objective C and probably countless others less famous programming languages. What this means: - You can include C library headers directly in your .ec code, without any special keyword (like extern C in C++) - There is no special mangling going on for normal functions (C binary compatibility), which means you can interface in both directions with any language supporting C bindings. - Simply put, eC does not take anything away from C, it only adds useful features to it
Re: RCArray is unsafe
On Wednesday, 4 March 2015 at 08:56:20 UTC, Ivan Timokhin wrote: Excuse me if I miss something obvious, but: void main() { auto arr = RCArray!int([0]); foo(arr, arr[0]); } void foo(ref RCArray!int arr, ref int val) { { auto copy = arr; //arr's (and copy's) reference counts are both 2 arr = RCArray!int([]); // There is another owner, so arr // forgets about the old payload } // Last owner of the array ('copy') gets destroyed and happily // frees the payload. val = 3; // Oops. } struct PileInfo Red TOP of PILE { int refCount; RCDataBlock * top; RCDataBlock * bottom; } struct RCDataBlock Blue { PileInfo * pileInfo; RCDataBlock * next; Array * payload;//Actual Data. } struct RCArray { RCDataBlock * block; } RCArray a,b,c,d;//all different piles a = b; b = c; d = a; //makes them one single pile. What if you pile them up. Blue cubes which contain the data. And a Red cube containing the reference count equal to the sum of all references to the blue cube of the same pile. Basically a pile of blue cubes with a red cube on top. 1) RCArray a,b,c,d; // [1] x -a [1] x -b [1] x -c [1] x -d 2) a = b; // [2] x -[old b1] x -a,b [1] x -c [1] x -d 3) b = c; // [3] x -b,c x -[old b1] x -a,[old b2] [1] x -d 4) d=a; // [4] x -b,c x -[old b1] x -[old a1],[old b2] x -d,a
Re: DList.Range magically becomes empty.
On Wednesday, 25 February 2015 at 09:07:17 UTC, Tobias Pankrath wrote: import std.container; import std.stdio; void main() { DList!int list; Array!(DList!int.Range) stack; foreach(i; 0 .. 4) { list.stableInsertBack(i); stack.insertBack(list[]); } writefln(list: %s, list[]); // fine writefln(stack: %s, stack[]); //fine foreach(s; stack[]) writefln(s: %s, s); // all s are empty? writefln(stack: %s, stack[]); //not fine } It prints: list: [0, 1, 2, 3] stack: [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]] s: [] s: [] s: [] s: [] stack: [[], [], [], []] Ranges aren't containers. It's more like a view of a container that gets smaller (or empty) the more you use it. There might not be a container behind a range.
Re: tail const ?
On Thursday, 30 October 2014 at 10:28:42 UTC, Simon A wrote: I don't know about syntax, but D sure needs first-class support of tail immutability. struct A { }
Re: tail const ?
On Thursday, 30 October 2014 at 10:28:42 UTC, Simon A wrote: I don't know about syntax, but D sure needs first-class support of tail immutability. struct A { float * a; void foo() tailconst { writeln(typeof(a).stringof); //outputs const(float) * } } class B { float * a; void foo() tailconst { writeln(typeof(this).stringof); //outputs tailconst(B) writeln(typeof(a).stringof); //outputs const float * } } tailconst for struct and classes. How about this? *sorry about the previous almost empty post.
tail const ?
As Stewart Gordon mentioned before (2012) What about adding tailConst to the D programming language? tailConst MyStruct a; All fields of the MyStruct would be tailConst and ... tailConst MyClass b; would make the the pointer mutable but all the fields of b const. ...tailImmutable, ...
monodevelop mono-d versions
I can't seem to install mono-d. It always seems to want a newer version of MonoDevelop. I'm on Ubuntu 14.04 LTS and it has version 4.0.12 of MonoDevelop. Has anybody else got this to work with this version? I have this file called MonoDevelop.D-1.9.6.mpack Tools-Add In Manager-Install From File Select the MonoDevelop.D-1.9.6.mpack file. Press Open Dialog Window: The Following Packages will be Installed. D Language Binding v2.1.14 (In User Directory)
Re: If you had money to place for a bounty, what would you choose?
On Thursday, 5 December 2013 at 05:09:03 UTC, Marco Leise wrote: Am Sun, 01 Dec 2013 09:09:32 +0100 schrieb sclytrack sclytr...@fake.com: Re: If you had money to place for a bounty, what would you choose? Official debian packages for gdc, derelict, gtkd, vibed. What compiler and D version should those libraries be compiled with? The reason I ask this is that current D compilers produce incompatible ecosystems. You would need a gtkd-dmd, gtkd-gdc and gtkd-ldc package (or one big package with all three) and give what is supposedly one library three different file names to link against. gdc version. ldc seems to be stuck in unstable.
Re: Real time captioning of D presentations
On Sunday, 1 June 2014 at 20:52:16 UTC, bearophile wrote: Walter Bright: what do you guys think? The caption I'd like to see is the name of the speaker during the live transmissions. Bye, bearophile Steno? You can type in realtime? Then why the hell did I spend time learning to type using a normal keyboard with two different character sets. Plover: http://www.youtube.com/watch?v=K3MYFT6VZk8 I am wondering. Should we all start learning plover? http://www.youtube.com/watch?v=Fu7DygveoB4 Somebody can start practising for the next D Conf :-)
Re: Per popular demand, here are Adam D Ruppe's presentation slides
On Saturday, 24 May 2014 at 20:53:18 UTC, Adam D. Ruppe wrote: On Saturday, 24 May 2014 at 20:46:30 UTC, sclytrack wrote: Were there actual slides? Nope, I never actually got around to creating any. Okay, busy guy. I just had an outline on my desktop of stuff I was thinking about creating, but just didn't finish it. The paper was my recreation of that outline from memory. Here's the outline.txt stuff I didn't mention on the paper btw: * Replacing functions with the linker * Reflection: Using RTInfo's lint to enforce ownership rules (e.g. make it a compile time error to define a struct with a mutable slice. This has a few pros and a lot of cons.) * Doing a custom calling convention with naked functions and mixins * Talk about ABI details and the implementation of scope statements (e.g. scope(exit). I briefly talked about it being lowered to finally {} but didn't go into the asm like I was considering * The -betterC switch and what I want more from it. Otherwise, my memory was pretty decent for remembering what I had in mind! Then my random on-the-spot digressions padded out the time. I would have preferred slides though. I'm not so good at listening. The visual impact helps ME better at remembering. Yeah, your memory is fine. :-)
Re: Livestreaming DConf?
On Wednesday, 21 May 2014 at 03:03:11 UTC, Manu via Digitalmars-d-announce wrote: My timezone will keep me awake from 2am - 9am to watch the live streams... which I probably will do ;) Yeah, you were there. Don't do this a second night. On 21 May 2014 07:01, Nick via Digitalmars-d-announce digitalmars-d-announce@puremagic.com wrote: On Friday, 9 May 2014 at 19:48:20 UTC, Andrei Alexandrescu wrote: Hi folks, We at Facebook are very excited about the upcoming DConf 2014. In fact, so excited we're considering livestreaming the event for the benefit of the many of us who can't make it to Menlo Park, CA. Livestreaming entails additional costs so we're trying to assess the size of the online audience. Please follow up here and on twitter: https://twitter.com/D_Programming/status/464854296001933312 Thanks, Andrei I'll probably watch most of it if it's streamed. Lost sleep leads to loss of brain cells http://www.bbc.com/news/health-26630647 You need those brain cells.
Re: More radical ideas about gc and reference counting
On Sunday, 11 May 2014 at 11:42:37 UTC, ponce wrote: On Sunday, 11 May 2014 at 08:59:42 UTC, Walter Bright wrote: D also cannot be performance competitive with C++ if pervasive ARC is used and memory safety is retained. Rust is attempting to solve this problem by using 'borrowed' pointers, but this is unproven technology, see my reply to Manu about it. I work in a C++ shop and as I see it, resource management is becoming a solved problem: - resource owners holds a std::unique_ptrT on them. Resource release is taken care by C++ destructors normally. That means to be exception-safe, each resource type must better have its class. - resource users eventually borrow the resource by taking a raw pointer out of the unique pointer. What Rust would do with lifetimes here is ensure that the resource is still there since move semantics seems pervasive in this language. In C++ we ensure the resource holder outlive the users. - std::shared_ptr is not needed with such constraints. This means no cycles in the object graph. TBH I have yet to find a dependency scheme that can't be done that way. When I use D I can't help but think that releasing resources feels more manual and error-prone (oops that resource should have been a struct not a class and such traps). I do not have huge concerns about D GC, but I would be glad to have more support for owned pointers (ie. Unique!T in Phobos or better). I have no idea how to make it safe ie. ensure the resource outlive its users. I like this owner/unique, borrow thing. @ is managed (currently reference counted) ~ is owner is borrow fn example3() - int { let mut x = ~X {f: 3}; let y = x.f; x = ~X {f: 4}; // Error reported here. *y } According to Debian Rust is still too experimental to be packaged. http://web.mit.edu/rust-lang_v0.8/doc/tutorial-borrowed-ptr.html servo is written in Rust. https://github.com/mozilla/servo There is very little use of @, it's mostly and ~. Heck I didn't find any @ while casually browsing the code. It's like they are not using it at all. I don't know Rust, it is the first day I look (read documentation) at it.
Re: From slices to perfect imitators: opByValue
void main() { DemoStruct m; test(m); acceptor(immutable) i; I mean: acceptor(immutable) DemoStruct i test(i); }
Re: From slices to perfect imitators: opByValue
On Thursday, 8 May 2014 at 11:05:20 UTC, monarch_dodra wrote: On Thursday, 8 May 2014 at 07:09:24 UTC, Sönke Ludwig wrote: Just a general note: This is not only interesting for range/slice types, but for any user defined reference type (e.g. RefCounted!T or Isolated!T). Not necessarily: As soon as indirections come into play, you are basically screwed, since const is turtles all the way down. So for example, the conversion from const RefCounted!T to RefCounted!(const T) is simply not possible, because it strips the const-ness of the ref count. What we would *really* need here is NOT: const RefCounted!T = RefCounted!(const T) But rather RefCounted!T = RefCounted!(const T) The idea is to cut out the head const directly. This also applies to most ranges too BTW. Skip paragraph. Okay daedalnix. Second attempt. Started with Container!(const(T)). Thought about separating the the const. Container!(T, const) and then only one const. None of that Container!(A,B, immutable, const). Then thought about int qual(*) * a. With qual as entry point. Then decided to go tail const only, single head mutable. But then seeing that there are two cases above, decided to go acceptor, copy. --- a) I'm going to call this the copying case where the value types are copied const RefCounted!T = RefCounted!(const T) immutable int [] a = immutable (int) [] a; immutable to mutable b) Acceptor case. RefCounted!T = RefCounted!(const T) e.g a const field accepts the mutable or immutable field. --- struct DemoStruct { int * * a; acceptor int * * b; void demonstrate() acceptor { assert(typeof(a).stringof == int * *); assert(typeof(b).stringof == acceptor(int *) *); } } void test(acceptor(const) DemoStruct v) { assert(typeof(v.a).stringof == int * *); assert(typeof(v.b).stringof == const(int *) *); } void main() { DemoStruct m; test(m); acceptor(immutable) i; test(i); } Like having acceptor behave like inout or something. The acceptor field can receive the following. int * * a; immutable (int *) * b; const(int *) * acceptorfield = a; acceptorfield = b; const(int) * * oops = b; // not valid acceptor. const(int * *) meh = b; // will choose the first pointer mutable since // is a copy so meh. The acceptor field is tail const or something with the first entry being mutable. --- struct DemoStruct { int * * a; acceptor int * * b; void demonstrate() copy { assert(typeof(a).stringof == copy(int *) *); assert(typeof(b).stringof == copy(int *) *); } } void test(copy(const) DemoStruct v) { assert(typeof(v.a).stringof == const(int *) *); assert(typeof(v.b).stringof == const(int *) *); } void main() { immutable DemoStruct i; test(i); } For the copying version, immutable == mutable the acceptor is applied to all fields. Please forgive me for pressing the send button. Sclytrack
Re: More radical ideas about gc and reference counting
On Wednesday, 30 April 2014 at 21:17:23 UTC, H. S. Teoh via Digitalmars-d wrote: On Wed, Apr 30, 2014 at 02:13:32PM -0700, Andrei Alexandrescu via Digitalmars-d wrote: On 4/30/14, 2:09 PM, Timon Gehr wrote: On 04/30/2014 10:58 PM, Andrei Alexandrescu wrote: On 4/30/14, 1:56 PM, Timon Gehr wrote: struct S{ ~this(){ /* ... */ } /* ... */ } class C{ S s; } ? By hand, as I mentioned. -- Andrei I meant, is it going to be deprecated too? No, that will continue to be allowed. -- Andrei Then what is it going to do? S.~this will never get called? It gets called when the gc runs. T
Re: std.file.read returns void[] why?
On Thursday, 17 April 2014 at 14:05:50 UTC, Regan Heath wrote: On Thu, 17 Apr 2014 13:59:20 +0100, Steven Schveighoffer schvei...@yahoo.com wrote: It was never possible. You must explicitly cast to void[]. to - from? void[] makes actually little sense as the result of whole-file read that allocates. byte[] is at least usable and more accurate. In fact, it's a little dangerous to use void[], since you could assign pointer-containing values to the void[] and it should be marked as NOSCAN (no pointers inside file data). I see what you're saying, byte[] is what *is* allocated.. but my point is that it's not what those bytes actually represent. Are you saying void[] *is* currently marked NOSCAN? However, when using the more conventional read(void[]) makes a LOT of sense, since any T[] implicitly casts to void[]. Indeed. :) R auto a1 = new ubyte[10]; //NO_SCAN set auto a2 = new ubyte*[10]; // NO_SCAN not set auto a3 = new void[10]; //NO_SCAN not set auto a4 = new void *[10]; //NO_SCAN not set void [] retains = a1;//NO_SCAN REMAINS SET from the ubyte [] at creation time. Since read comes straight from the file. It contains no memory pointers and the NO_SCAN can be set.
Re: std.file.read returns void[] why?
Are you saying void[] *is* currently marked NOSCAN? import std.stdio; import core.memory; writeln(int* [], GC.query(cast(void *) arr2).attr);
Re: DIP60: @nogc attribute
On Wednesday, 16 April 2014 at 10:13:06 UTC, bearophile wrote: JN: I doubt @nogc will change anything, people will just start complaining about limitations of @nogc Having a way to say this piece of program doesn't cause heap activity is quite useful for certain piece of code. It makes a difference in both performance and safety. But not being able to call core.stdc.stdlib.alloca in a @nogc pure function sub-three is not good. Bye, bearophile What about adding custom annotations that don't do any checking by itself. Like when @nogc doesn't actually verify that the ~ is not used for strings. void hello() require(@nogc) { } Just a verification by the compiler that you use only routines that are marked with certain annotations. void boe() { } @(nasaverified) void test() { } // void hello() require(@(nasaverified)) { test(); // ok boe(); // not ok. }
Re: std.stream replacement
On Saturday, 14 December 2013 at 15:16:50 UTC, Jacob Carlborg wrote: On 2013-12-14 15:53, Steven Schveighoffer wrote: I realize this is really old, and I sort of dropped off the D cliff because all of a sudden I had 0 extra time. But I am going to get back into working on this (if it's still an issue, I still need to peruse the NG completely to see what has happened in the last few months). Yeah, it still need to be replaced. In this case you can have a look at the review queue to see what's being worked on: http://wiki.dlang.org/Review_Queue SINK, TAP - https://github.com/schveiguy/phobos/blob/new-io/std/io.d What about adding a single property named sink or tap depending on how you want the chain to be. That could be either a struct or a class. Each sink would provide another interface. struct/class ArchiveWriter(SINK) { @property sink //pointer to sink } writer.sink.sink.sink arch.sink.sink.sink.open(filename); ArchiveReader!(InputStream) * reader; Warning: As usual I don't know what I'm talking about.
Re: Appropriateness of posts
On Monday, 17 March 2014 at 10:31:54 UTC, Namespace wrote: On Monday, 17 March 2014 at 09:18:43 UTC, Andrej Mitrovic wrote: On 3/17/14, Walter Bright newshou...@digitalmars.com wrote: I'd hoped I'd never have to post this. There have been some locker room jokes that continued even after I asked it be stopped. Where? Any specific threads? I think he means the dlang.sexy thread. **xy.com in one of my fake e-mail addresses as supposed to my usual @fake.com I use the web forum so e-mail is not really visible to me. Seems like Walter wants it seriously professional. No joking around about D.
Re: Possible change to array runtime?
On Thursday, 13 March 2014 at 22:21:56 UTC, sclytrack wrote: Delayed D Language D Normal immutable int * a; int * a; immutable qual(int) * a;immutable(int) * a; immutable int qual(*) a;immutable int * a; - struct A { int a; qual(int) b; } A vari; const A cvari; vari.a = 1; cvari = vari; cvari.a = 2; cvari.b = 3;//error - qual class Test { } Delayed D D struct language immutable Test t; immutable(Test) * t; immutable qual(Test) t; immutable Test * t; - struct Array(T) { qual(T) * data; size_t length; } Array!(int) a; const Array!(int) b; void routine(const Array!(int) b) { } b = a; routine(a); I'm not sure how to understand your change proposal, you should explicit it more. But it seems that you get what the problem is (or at least, you are poking the right language constructs in your proposal). qual would be the entry point of the qualifier so immutable int * * * * qual(*) * * * data; So everything to the left would be immutable and everything to the right would be mutable. struct A { char [] a; qual(char) [] b; } When defining const A data; Again the const is delayed until the entry qual(int). So ... A data; struct A { char [] a; char [] b; } const A cdata; struct A { char [] a; const(char) [] b; } immutable A idata; struct A { char [] a; immutable(char) [] b; } All this A has a single memory layout and a single qualifier that modifies them. cdata = data; cdata = idata; --- struct B { A data; qual(A) qdata; } B bdata; struct B { A data; A qdata; } const B cbdata; struct B { A data; const(A) qdata; //struct A { char [] a; const(char) [] b; } } immutable B ibdata; struct B { A data; immutable(A) qdata; //struct A { char [] a; immutable(char) [] b; } } cbdata = bdata cbdata = ibdata For functions it the qualifier would also be delayed which means having the word const in front of it doesn't necessarily mean it is const. void routine(const A * data) { data.a = modifiable; } If we are forcing a delayed qualifier on A we are forcing the same one as the one on the pointer. const A qual(*) data; It is the same const applied to the pointer and the struct A. --- Okay now to more conventional D. These two are more or less the same type. Container!(PayloadType) Container!(PayloadType, const) The following two are different types. Container!(PayloadType) Container!(const(PayloadType)) --- Container!(PayloadType, const) The qualifier can be applied to your payload field and even none-payload fields. The thing is only PayLoadType is part of the type definition and the qualifier at the end is not. The qualifier at the end must not participate in the type definition in any way. Not in static if and so forth. By some magic needs to be prevented. Having to deal with a single qualifier is much easier than having to deal with the qualifier of every payload. Again a bit of qual code. struct Container!(PayloadType) { qual(char) [] a; PayloadType payload; } PayloadType participates in the type and sets the memory layout of the type. Here the qualifier isn't even on the payload. --- Container!(const(int), int, char [], const) The first 3 define the type. (const(int), int, char []) The last bit. The qualifier (const) of the container does not participate in the definition of the type. --- For overloading there are too many options. void routine( immutable Container!(int, const) data); //a void routine( immutable Container!(int, immutable) data); //b Here the first one (a) is not needed. In delayed qualifier D this would be. void routine(imutable qual(Container!(int)) data) //b Setting the qual in right in front of the container means that immutable applies to all the fields of the Container!(int) and not only those marked with qual. --- In Normal D style Existing style. Already possible. void routine( Container!(int, ) data); //a void routine( const Container!(int, const) data); //b void routine
Re: Good name for f.byLine.map!(x = x.idup)?
On Sunday, 16 March 2014 at 17:28:46 UTC, Jakob Ovrum wrote: On Sunday, 16 March 2014 at 16:58:36 UTC, Andrei Alexandrescu wrote: A classic idiom for reading lines and keeping them is f.byLine.map!(x = x.idup) to get strings instead of the buffer etc. The current behavior trips new users on occasion, and the idiom solving it is very frequent. So what the heck - let's put that in a function, expose and document it nicely, and call it a day. A good name would help a lot. Let's paint that bikeshed! Andrei Maybe `byUniqueLine`. We might also consider a higher order range (say, `byUnique`, in the same vein) that GC-clones elements in some generic fashion, then showing `f.byLine().byUnique()` front and centre in `byLine`'s documentation. Just a couple of half-assed ideas to get the ball rolling. f.byLineIdup();
Re: Possible change to array runtime?
On Thursday, 13 March 2014 at 21:28:46 UTC, deadalnix wrote: If I may, and as author of dcollection, you'll certainly agree, I think the way forward is improving the language when it comes to collections. That way, any behavior can be provided as user type. Patching the language in such a way is simply moving the problem around. -- If it is not in the language then maybe a design pattern. -- The #1 problem we have when it comes to collection is type qualifier for template type parameters. I consider this to be on of the top problems of D right now, if not the #1 problem. -- Number 1 problem. Noted. -- The problem is that T!ElementType is a ompletely different type than T!const(ElementType) . Because of this, if is almost -- I grasp that you need some sort of an implicit cast from T!ElementType to T!const(ElementType). void routine(T!const(ElementType) p) {} T!ElementType a; routine(a); -- Collection!(const(Element1), immutable(Element2), Element3); There are a lot of different implicit conversions that stacking up. Now separating the qualifier like this. T!(ElementType, immutable) The implicit conversions would then be based on that sole qualifier at the end. Would this not be sufficient for your collections? (Not rethorical). Collection!(const(Element1), immutable(Element2), Element3, const); -- void routine(immutable Collection!(ElementType, const)); //Meh void routine(immutable Collection!(ElementType, immutable)); I also feel like the above //Meh should not be there. -- impossible to provide anything that behave anything close to arrays. That is th reason why collection are so scarce in D, this is the reason why efforts to implement AA without the black magic -- I dunno. Not a magician. Have to think. -- involved right now are failing. This problem is a killer for the viability of D2 on the long run. I'm not saying that lightly. -- Everybody wants a solution to this. That is why everybody is jumping on this like crazy instead of responding to the finalize by default thread. (irony) Some more Collection and Const Noise. Collection!const(Noise)
Re: Possible change to array runtime?
On Thursday, 13 March 2014 at 21:28:46 UTC, deadalnix wrote: If I may, and as author of dcollection, you'll certainly agree, I think the way forward is improving the language when it comes to collections. That way, any behavior can be provided as user type. Patching the language in such a way is simply moving the problem around. The #1 problem we have when it comes to collection is type qualifier for template type parameters. I consider this to be on of the top problems of D right now, if not the #1 problem. The problem is that T!ElementType is a ompletely different type than T!const(ElementType) . Because of this, if is almost impossible to provide anything that behave anything close to arrays. That is th reason why collection are so scarce in D, this is the reason why efforts to implement AA without the black magic involved right now are failing. This problem is a killer for the viability of D2 on the long run. I'm not saying that lightly. Language changes? Like this? - Delayed D Language D Normal immutable int * a; int * a; immutable qual(int) * a;immutable(int) * a; immutable int qual(*) a;immutable int * a; - struct A { int a; qual(int) b; } A vari; const A cvari; vari.a = 1; cvari = vari; cvari.a = 2; cvari.b = 3;//error - qual class Test { } Delayed D D struct language immutable Test t; immutable(Test) * t; immutable qual(Test) t; immutable Test * t; - struct Array(T) { qual(T) * data; size_t length; } Array!(int) a; const Array!(int) b; void routine(const Array!(int) b) { } b = a; routine(a);
Re: Final version of dlang-fr released
match (in a game), litchi (a fruit), dispatcher (to dispatch) I believe you used dispatcher in the translated book. Had to look it up, because it sounded too English. Words containing tch seems to be taken for other languages. Talking about languages is going to become a habit here! My last post on the French forum got deleted prior to having the book updated. Grmbl. http://dlang-fr.org/cours/programmer-en-d/litteraux.html go fix and prosper.
Re: Nobody understands templates?
On Sunday, 2 March 2014 at 18:59:23 UTC, Steve Teale wrote: On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote: This is a pretty good primer to templates: https://semitwist.com/articles/article/view/template-primer-in-d The trouble is with most of these tutorials that they offer examples that are things you would probably never want to do. I can already add an int to an int, or a double to a double, or an int to a double. Perhaps the examples should pick on something like vector operations, but then who would be doing those with int, or some class? It would be doubles or pairs of, as in struct Coord. import std.stdio; import std.algorithm; void add(T,size_t N)(ref T[N] result, const T[N] a, const T[N] b) { result[0] = a[0]+b[0]; static if (N 1) result[1]=a[1]+b[1]; } void main() { int [2] a = [1,2]; int [2] b= [3,4]; int [2] result; result.add(a,b); writeln(result); result[] = a[] + b[]; writeln(result); } I believe readers would study documentation and examples much more carefully if they were things they might realistically want to do. And that won't be type conversion - std.conv already does a pretty good job on that. So what? We could really do with a place where template savvy open source contributors could publish interesting examples of template use. Otherwise, Joe Soap, like me, can spend a great deal of time and effort in: a) Determining when the use of a template might be advantageous, b) Hacking at test programs to determine what the documentation means, and what works, and what doesn't. c) After that, deciding whether it would be just as effective to use two or three separate methods. Steve Steve Are there any disadvantages of using a fixed size array for fixed size coordinates and vectors, over creating an actual typedef or struct Vec3?
Re: Artwork Design (suggestions)
On Wednesday, 19 February 2014 at 18:50:26 UTC, Chris wrote: I've uploaded some suggestions for sticker and t-shirt design (not necessarily for DConf). http://wendlerchristoph.wordpress.com/designs-for-d/ Feel free to comment. In case anyone is interested in one of the designs, just contact me on this forum. I have all designs as SVGs created with Inkscape, but I can create other formats too. What does the CW in the upper right corner mean? Better by Dsign is nice.
Re: Generic Span/Limits/MinMax Type
On Monday, 20 January 2014 at 19:36:13 UTC, Nordlöw wrote: Has anyone cooked up a generic D struct that groups together min and max values of a type and default-initializes them in the correct way? Something like struct Limits(T) { /* TODO: Fix purity of this by fixing Bytes.value() */ auto init() @trusted /* pure */ nothrow { return tuple(T.max, T.min); } alias _minmax this; Tuple!(T,T) _minmax; } auto limits(T)() { return Limits!T(); } unittest { Limits!int x; dln(x); } I want min and max to default initialize to T.max, T.min so they are prepared for x = min/max(x, ...) arithmetic. But the code above doesn't work because the init() function isn't called and I don't know why. And I can't use default member initialization because I want `Limits` to work also with types such as `SysTime` when min and max are only know at run-time. I'm aware of `std.datetime.span` but it isn't generic. Ideas anyone? import std.stdio; import std.typecons; struct Limits(T) { auto _minmax = tuple(T.min, T.max); alias _minmax this; } void main() { auto a = tuple(int.min, int.max); a[1] = 2; writeln(a); Limits!int x; writeln(x._minmax); writeln(x); x[0] = 1; writeln(x); writeln(end); } I'm not sure what you want to do.
Re: Programmer en D published on dlang-fr.org
On Saturday, 18 January 2014 at 13:11:45 UTC, Raphaël Jakse wrote: Le 16/01/2014 18:34, sclytrack a écrit : On Wednesday, 15 January 2014 at 20:19:51 UTC, Raphaël Jakse wrote: Le 15/01/2014 21:18, Raphaël Jakse a écrit : Fixes can come from the ***support*** you are the most at ease, it's ok for me media might be a better word ;-) Le petit travail pour ce soir. :-) Appuyer avec le souris sur voir les passages C'est la souris. J'ai par contre laissé la partie sur les imaginaires. Peut-être qu'on devrait en discuter avec Ali et toi avant de faire quoi que ce soit. Je laisse la décision à dmd. Central processing unit Central Unit Processing Unit. Central-processing unit Unit of central processing. Unité de traitement centrale Unité centrale de traitement---selon wikipedia Please note: I'm not French. Il y a des problèmes avec les liens sur le site http://dlang-fr.org/cours/programmer-en-d/expressions_logiques.html expression_logiques.html existe encore. The chapter on the if statement has a weird phrase. The reason for me to stress the guideline of always using curly brackets is because I will now show the only case where omitting the curly brackets is actually better. Maybe just change it to. I will now show the only case where omitting the curly brackets is actually better.
Re: Programmer en D published on dlang-fr.org
On Wednesday, 15 January 2014 at 20:19:51 UTC, Raphaël Jakse wrote: Le 15/01/2014 21:18, Raphaël Jakse a écrit : Fixes can come from the ***support*** you are the most at ease, it's ok for me media might be a better word ;-) Le petit travail pour ce soir. :-) Appuyer avec le souris sur voir les passages http://dlang-fr.org/cours/programmer-en-d/compilateur.html http://dlang-fr.org/cours/programmer-en-d/types.html http://dlang-fr.org/cours/programmer-en-d/variables.html ifloat, cfloat ... needs to be removed from the original English version. I might have an issue with the following phrase where a verb equals a noun. Introducing a variable to the program is called its definition. http://dlang-fr.org/cours/programmer-en-d/es.html http://dlang-fr.org/cours/programmer-en-d/expression_logiques.html expressions logiques http://dlang-fr.org/cours/programmer-en-d/corrections/expressions_logiques.html Revenir au chapitre: Expressions logiques Oops! That page can’t be found.
Re: Programmer en D published on dlang-fr.org
On Sunday, 12 January 2014 at 20:36:18 UTC, Raphaël Jakse wrote: Hello everybody, I just published the current state of Programmer en D, the French translation of Ali's Programming in D, on dlang-fr: http://dlang-fr.org/cours/programmer-en-d/ There are a lot of missing chapters and no proofread have been done yet. There's an integrated module to report any error of make any suggestion on the book. Somme recent modifications from Ali are still to apply to the translation. Enjoy, and please comment if you have anything to tell about it, any suggestion, any idea, any question. Raphaël. tests_unitaires.html il y a des raisons de penser que la fonciton ordinal est correcte fonciton Bon travail!!
Re: If you had money to place for a bounty, what would you choose?
Re: If you had money to place for a bounty, what would you choose? Official debian packages for gdc, derelict, gtkd, vibed.
Re: D french-speaking community
On Friday, 8 November 2013 at 23:31:44 UTC, deadalnix wrote: On Friday, 8 November 2013 at 21:53:18 UTC, Namespace wrote: I still hope for a German community ... :( They are so much D fan there that they put stickers on their cars ! Je crois ça va être difficile de trouver des gens qui se sont intéressés en D et qui savent parler français en même temps. BTW, I'm french. You guys have the hottest female singer in the world.
Re: A question for Mr Bright
On Friday, 4 October 2013 at 20:23:22 UTC, ProgrammingGhost wrote: Walter Bright: Did you have a beard during anytime of the the design or development of D? and if not do you regret it? Context: http://c2.com/cgi/wiki?LanguageAuthorBeardPattern If he hasn't had a beard. He should better start growing one. :-)
Re: std.allocator needs your help
On Wednesday, 25 September 2013 at 01:22:46 UTC, deadalnix wrote: On Tuesday, 24 September 2013 at 15:57:00 UTC, Andrei Alexandrescu wrote: Also, I hope we'll be able to allow allocators to define Pointer(T), Ref(T) etc. that supplant replacements for the built-in notions of pointer, reference etc. Then, user code that uses these notions instead of the built-in ones will be guaranteed some nice properties (e.g. automatic reference counting). Unfortunately I don't see a way for an allocator to enforce that its users don't do illegal things such as escaping addresses etc. So it would be a discipline-backed scheme. Notable beneficiaries will be containers. It will be fun without tail const. Do you mean something like this? struct StructName1 { int a; } struct StructName2 { const int a; } StructName1 a; StructName2 b; b = a; //does not work Struct sorta like typedef on the name. Nothing to make sure that it is the same field layout, regardless of const. struct LayoutName1, StructName1 { int a; } struct LayoutName1, StructName2 { const int a; }
Re: GC.collect bug ?
On Friday, 13 September 2013 at 16:43:01 UTC, Namespace wrote: Another use case of delete, which is unfortunately deprecated. ;) import std.stdio; import core.memory; class A { ~this() { writeln(`dtor`); }; }; void main() { auto a = new A; delete a; writeln(`after dtor`); } Ooutput: dtor after dtor //http://dlang.org/memory.html import std.c.stdlib; import core.exception; import core.memory : GC; import std.stdio; class TObject { new(size_t sz) { void* p; p = std.c.stdlib.malloc(sz); if (!p) throw new OutOfMemoryError(); GC.addRange(p, sz); writeln(Memory Allocation, sz); return p; } delete(void* p) { if (p) { GC.removeRange(p); std.c.stdlib.free(p); writeln(Memory Removal); } } } class TComponent: TObject { int number; } int main() { TComponent obj = new TComponent(); delete obj; writeln(testing the code); return 0; } //What is the replacement for delete?
Re: std.d.lexer: pre-voting review / discussion
On Thursday, 12 September 2013 at 03:31:42 UTC, H. S. Teoh wrote: On Wed, Sep 11, 2013 at 10:06:11PM -0400, Jonathan M Davis wrote: On Thursday, September 12, 2013 03:37:06 deadalnix wrote: Int, Function, Scope, Import are all valid identifiers. All of which violate Phobos' naming conventions for enum values (they must start with a lowercase letter), which is why we went with adding an _ on the end. And it's pretty much as close as you can get to the keyword without actually using the keyword, which is a plus IMHO (though from the sounds of it, H.S. Teoh would consider that a negative due to possible confusion with the keyword). [...] Actually, the main issue I have is that some of the enum values end with _ while others don't. This is inconsistent. I'd rather have consistency than superficial resemblance to the keywords as typed. Either *all* of the enum values should end with _, or *none* of them should. Having a mixture of both is an eyesore, and leads to people wondering, should I add a _ at the end or not? If people insist that the 'default' keyword absolutely must be represented as TokenType.default_ (I really don't see why), then *all* TokenType values should end with _. But honestly, I find that really ugly. Writing something like kwDefault, or tokenTypeDefault, would be far better. Sigh, Andrei was right. Once the bikeshed is up for painting, even the rainbow won't suffice. :-P T Delphi would use TokenType ttDefault MyType mtDefault
Re: new DIP47: Outlining member functions of aggregates
On Saturday, 7 September 2013 at 17:00:08 UTC, Walter Bright wrote: Outlining of member functions is the practice of placing the declaration of a member function in the struct/class/union, and placing the definition of it at global scope in the module or even in another module. http://wiki.dlang.org/DIP47 --- unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } procedure ChangeTitle(x:string); procedure ChangeOtherTitle(x: string); end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin ChangeTitle('test'); end; procedure TForm1.ChangeTitle(x: string); begin Memo1.Lines.Add(x); end; procedure TForm1.ChangeOtherTitle(x: string); begin Memo1.Lines.Add(x); end; end. Here is how it looks like in Lazarus. In the class definition you type the declaration. public { public declarations } procedure ChangeTitle(x:string); Then you press control shift c this will create the empty implementation. Use control shift up to cycle between the interface section and the implementation section. There are two keywords interface and implementation to separate the two sections. Honestly. There is not much typing going on. If you go want to go the the next procedure in the implementation section it is faster to go control shift up back to the interface section. And then go to the next method and go back control shift up to the implentation section than to press the arrow down button until you are at the next method. Lazarus does not accept changes in the name of the parameter.
Re: Top Github Languages for 2013 (so far)
On Tuesday, 3 September 2013 at 13:13:11 UTC, Elvis wrote: http://adambard.com/blog/top-github-languages-for-2013-so-far/ Well D is now a bit higher on tiobe, position 22 (August 2013). It has been, for a very long time, on position 36. Is there any push of getting vibed and gtkd in ubuntu before the LTS release?
Re: database applications
On Tuesday, 6 August 2013 at 18:05:22 UTC, John Joyus wrote: I have looked at the D language and liked it's syntax. The code looks neat and clean. But before I try to learn it thoroughly, I want to know if D is suitable to develop high level database GUI applications with drag and drop components like Delphi or Lazarus. Do we have something like that already? If not, are there any plans to develop a component based rad tool in future? Thanks, JJ Is lazarus any good, now that version 1.xx is out? Previous versions were very buggy. I wonder if we could get an extern(freepascal) or whatever name mangling lazarus uses. Peter My not caring is a reflection of my choice not to feel.
Re: Memory management design
On Tuesday, 9 July 2013 at 23:32:13 UTC, BLM768 wrote: Given all of this talk about memory management, it would seem that it's time for people to start putting forward some ideas for improved memory management designs. I've got an idea or two of my own, but I'd like to discuss my ideas before I draft a DIP so I can try to get everything fleshed out and polished. Anyway the core idea behind my design is that object lifetimes tend to be managed in one of three ways: 1. Tied to a stack frame 2. Tied to an owner object 3. Not tied to any one object (managed by the GC) To distinguish between these types of objects, one could use a set of three storage classes: 1. scope: refers to stack-allocated memory (which seems to be the original design behind scope). scope references may not be stashed anywhere where they might become invalid. Since this is the safest type of reference, any object may be passed by scope ref. 2. owned: refers to an object that is heap-allocated but manually managed by another object or by a stack frame. owned references may only be stashed in other owned references. Any non-scope object may be passed by owned ref. This storage class might not be usable in @safe code without further restrictions. 3. GC-managed: the default storage class. Fairly self-explanatory. GC-managed references may not refer to scope or owned objects. Besides helping with the memory management issue, this design could also help tame the hairy mess of auto ref; scope ref can safely take any stack-allocated object, including temporaries, so a function could have scope auto ref parameters without needing to be a template function and with greater safety than auto ref currently provides. -- 2. Tied to an owner object Why not just go manual memory. Just store everything in a tree-like structure. SuperOwner --Child1 --Child2 SubChild1 SubChild2 --Container1 --Container2 --TStringList Freeing a Child2 disposes of everything below.
Re: Are heap objects never moved by the garbage collector?
On Friday, 31 May 2013 at 16:31:39 UTC, Carl Sturtivant wrote: The D Programming Language (TDPL) p.178 asserts the following. The objects themselves stay put, that is their locations in memory never change after creation. I take this to mean that the D garbage collector doesn't move live objects and adjust all references to them the way that some garbage collectors do. That is to say, the addresses of objects are not changed by the garbage collector. Does D guarantee this? No. Quoted from the D website: http://dlang.org/garbage.html Although D does not currently use a moving garbage collector, by following the rules listed above one can be implemented. No special action is required to pin objects. A moving collector will only move objects for which there are no ambiguous references, and for which it can update those references. All other objects will be automatically pinned. I'll assume you can not move immutable pointers. Immutable pointers are not mentioned on that page. (except in the index left :)
Re: Migrating dmd to D?
On Thursday, 28 February 2013 at 01:32:58 UTC, Vladimir Panteleev wrote: On Thursday, 28 February 2013 at 00:37:50 UTC, Andrei Alexandrescu wrote: Please chime in with ideas on how to make this happen. Not an expert on the topic, but what does this mean for maintainers of integration with other backends, like GDC and LDC? For example: are there any other frontends in GCC not written in C/C++? gcc only started accepting c++ in 2010. So it will be really though to get them to accept D.
Re: What's missing from Phobos for Orbit (package manager)
On Friday, 15 February 2013 at 06:44:57 UTC, Dmitry Olshansky wrote: 15-Feb-2013 01:49, Jacob Carlborg пишет: On 2013-02-14 21:33, Dmitry Olshansky wrote: [snip] Regardless I think reducing dependencies is the important for inclusion of any new component into the D core. In general I think that the D community should embrace all developers/contributors and existing libraries. Not talking about your stuff in particular but in general - hell no. There is a line between accepting everything just because we can't lose the chance (hence current std.xml, std.json and other crappy stuff) and accepting decent stuff that was specifically following current Phobos idoms, was reviewed, etc. The latter puts quite a strain on the contributor and in the end should guarantee the quality of addition (and commitment to maintain it). That being said once package manager is there tested and solid 3-rd party libs will flow. (tested solid simply because of greater exposure factor) It cannot afford to loose contributions for petty things like this. I'd say if contributor can't be bothered to follow conventions and deal with the constraints imposed, just let him go. Coherency is all important in the core part of pretty much anything. When is D going to officially release with official third party libraries? Like synchronized with the release of dmd and bundled together in a huge (as large as possible) compressed file. Like Derelict, Gtkd, Qtd, Vibe, Apache Thrift. I mean not included in phobos but included in the release.
Re: Do we want functions to act as properties, or merely omit parens for ufcs/chaining?
On Tuesday, 29 January 2013 at 10:34:59 UTC, Sönke Ludwig wrote: Am 29.01.2013 05:16, schrieb sclytrack: On Tuesday, 29 January 2013 at 01:09:17 UTC, F i L wrote: why in the hell would you want: writeln = lolwut; to compile in the first place? If you disallow this. You will have to invent something else than opDispatch. Something that serves them both. opPropMethodDispatch maybe. template opDispatch(string name) { static if( isAProperty!name ){ @property int opDispatch() { return 0; } } else { void opDispatch() {} } } or similar should work. I meant for dynamic D where you don't know if it is a property or a method at compile time. Where you don't know if the method even exists or not. Overloading on an annotation is just weird. Either something is annotated or not. Going to eat now.
Re: Do we want functions to act as properties, or merely omit parens for ufcs/chaining?
On Tuesday, 29 January 2013 at 01:09:17 UTC, F i L wrote: why in the hell would you want: writeln = lolwut; to compile in the first place? If you disallow this. You will have to invent something else than opDispatch. Something that serves them both. opPropMethodDispatch maybe.
Re: @property - take it behind the woodshed and shoot it?
On Thursday, 24 January 2013 at 18:38:00 UTC, Adam D. Ruppe wrote: Thinking about it, this isn't quite a full circle. It does improve a bit. If we aren't going dip21, how about: === Everything stays the way it is now, except: * if a @property is called with parens, they always apply to the return value * -property hopefully dies. === If this means keeping the writeln = ; then vote++. I've got no issues with the property syntax for methods. I actually want them. Why should properties only get the shorter syntax? I don't really like it, it leaves a number of problems behind... but that would be an improvement on the status quo. I don't hate it. So: alias void delegate() Callable; Callable nonprop(); @property Callable prop(); Callable returned = nonprop; // ok, the parens are optional Callable returned = nonprop(); // ok, nonprop() just calls nonprop like any other function Callable returned = prop; // ok, no parens still calls, just like before Callable returned = prop(); // NOT GOOD: the () applies to the Callable (which returns void), not prop, because prop has @property BTW nonprop()(); // calls the Callable (this expression returns void) prop()(); // nonsense (prop() returns void, which is not callable) --- int nonprop(); @property int prop(); int returned = nonprop; // fine, optional parens int returned = nonprop(); // fine int returned = prop; // fine, we just call prop int returned = prop(); // NO GOOD: the () always applies to the return value, which in this case is int, which is not callable
Re: @property - take it behind the woodshed and shoot it?
On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote: On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote: I hate optional parentheses with a passion - Jonathan M Davis Same here. In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them. :-)
Re: The impoliteness of overriding methods
class Base { void chainMe() { ...doStuff() inner(); //calls a derived chainMe } } class Derived1:Base class Derived2:Base Derived2 der2 = new Derived2(); Derived1 der1 = cast(Derived1) der; der.chainMe(); // calls chainMe from Base. I assume it would have to call the chainMe from the Base first and not from any of the Derived. On Thursday, 20 December 2012 at 00:07:49 UTC, H. S. Teoh wrote: On Thu, Dec 20, 2012 at 12:11:34AM +0100, Andrej Mitrovic wrote: Some interesting blog post: http://journal.stuffwithstuff.com/2012/12/19/the-impoliteness-of-overriding-methods/ It's a post about a common problem in class design, I've ran into it a few times in D too. [...] Interesting concept. So polite overriding is simply a kind of override where the derived class method has a vtable entry separate from the base class method's entry (and thus needs explicit invocation from the base class), whereas the usual impolite overriding is a kind of override where the derived class method replaces the vtable entry of the base class method. I can see use cases for both kinds of overriding. Interestingly enough, in the polite overriding case, the call to inner is undefined until it's defined in the derived class. Which means that a method that calls inner is a kind of pseudo-abstract method (since abstract methods are those that *must* be implemented by the derived class). So if we were to implement this in D, we could extend the meaning of 'abstract': class Base { // The current, usual overridable method void replaceMe() { writeln(A); } // Abstract, because chain(chainMe) is undefined until // the derived class implements it. abstract void chainMe() { writeln(B); inner.chainMe(); // call derived class method // 'inner' is a tentative // keyword writeln(C); } } class Derived : Base { override replaceMe() { writeln(D); Base.replaceMe(); writeln(E); } // Base.chainMe is abstract, so we have to implement // this method. override void chainMe() { writeln(F); } } void main() { auto d = new Derived(); d.replaceMe(); // prints D A E d.chainMe();// prints B F C } T
Re: The impoliteness of overriding methods
Contract Programming :-) int chain(...) { preConstracts() inner.chain() // calls derived chain function postConstracts() return ... } Scly On Thursday, 20 December 2012 at 00:07:49 UTC, H. S. Teoh wrote: On Thu, Dec 20, 2012 at 12:11:34AM +0100, Andrej Mitrovic wrote: Some interesting blog post: http://journal.stuffwithstuff.com/2012/12/19/the-impoliteness-of-overriding-methods/ It's a post about a common problem in class design, I've ran into it a few times in D too. [...] Interesting concept. So polite overriding is simply a kind of override where the derived class method has a vtable entry separate from the base class method's entry (and thus needs explicit invocation from the base class), whereas the usual impolite overriding is a kind of override where the derived class method replaces the vtable entry of the base class method. I can see use cases for both kinds of overriding. Interestingly enough, in the polite overriding case, the call to inner is undefined until it's defined in the derived class. Which means that a method that calls inner is a kind of pseudo-abstract method (since abstract methods are those that *must* be implemented by the derived class). So if we were to implement this in D, we could extend the meaning of 'abstract': class Base { // The current, usual overridable method void replaceMe() { writeln(A); } // Abstract, because chain(chainMe) is undefined until // the derived class implements it. abstract void chainMe() { writeln(B); inner.chainMe(); // call derived class method // 'inner' is a tentative // keyword writeln(C); } } class Derived : Base { override replaceMe() { writeln(D); Base.replaceMe(); writeln(E); } // Base.chainMe is abstract, so we have to implement // this method. override void chainMe() { writeln(F); } } void main() { auto d = new Derived(); d.replaceMe(); // prints D A E d.chainMe();// prints B F C } T
Re: The impoliteness of overriding methods
On Thursday, 20 December 2012 at 09:07:35 UTC, Benjamin Thaut wrote: This polite overriding is a nice idiom. But it does not solve the most frequent problem I have at work (in C++) Assume you have a customer facing class they derive from to implement own features. abstract class Base { abstract void doStuff(); } I guess in the polite version you would make the call to the derived version here. The derived version wouldn't have to call super or anything. The customer now derives from this class and implements doStuff. Because it is abstract he does not call the base implementation. Now you have to do some changes and suddenly the doStuff method is no longer abstract and does something important that should always be executed. abstract class Base { void doStuff(){ prepareSomething(); } } The best you can do is put a line into the changelog make sure to call the base implementation of Base.doStuff Which the customer most likely won't read and thus usually will fill a issue report with the Support deparment, because the code breaks. If there would be some kind of attribute supported by the compiler, such as that the compiler ensures that the base implementation is always called if the function is annotated with this attribute the customer would automatically be reminded by the compiler, and this would not be an issue. It could look something like this: abstract class Base { @mustcall void doStuff(){ prepareSomething(); } } @mustcallbefore @mustcallafter Would these be automatically called in all derived versions? @autocallbefore @autocallafter Making a helper method that is called instead of doStuff is usually not an option, because the customer might have calls to doStuff in his code, which would still lead to a wrong execution path.
Re: Next focus: PROCESS
On Thursday, 20 December 2012 at 23:43:12 UTC, Joseph Cassman wrote: On Wednesday, 19 December 2012 at 21:30:44 UTC, Andrei Alexandrescu wrote: I agree with one stable branch. Andrei Just some food for thought. In the section about the Branching model, the wiki currently has a staging branch in addition to the master branch. From what I understand, the idea seems to be to vet a release on staging until it is considered production level and then marked as the release. Another idea could be to keep the quality of the master branch at a high level so as to be able to branch into a release at any time, directly from master. Before feature branches are merged back into master, their quality is vetted so the quality of master is maintained. I prefer this one. It's simpler, less to memorize. Staging area complicates things. I propose to go for a yearly release of the stable branches with one year support (In the beginning). So development needs to be of super high quality once a year. This idea seems similar to what is used for the vibe.d project (http://vibed.org/temp/branch-model-small.png). My apologies if I misunderstood their process. It looks like Xamarin has been using this process for a while and it seems to be working for them. http://tirania.org/blog/archive/2011/Oct-14.html Joseph
Re: Dynamic D
On Tuesday, 4 January 2011 at 16:03:28 UTC, Adam D. Ruppe wrote: Lutger Blijdestijn wrote: The restriction with calling zero-args functions is unfortunate, could this be solved by turning it into a class and dynamically checking whether the type is a function and then invoke it if it is? Maybe, but I think it'd still break the property get, which breaks setting complex types. This, and your other concern about implicit declarations are actually caused by the same root problem: the imperfect compiler implementation of properties combined with variadic opDispatch templates. (Like I said in that other thread, each of those features works quite well on its own, but the combination reveals some minor bugs.) To set a complex type, you do the: dyn.property() = some fancy thing; Which returns a property by reference, then does its opAssign template, which is much more capable of fanciness than the runtime variadic function you get without the parenthesis. Why do that? Because overloading on property and non-property doesn't work right now. Through trial and error, I found the compiler doesn't add a property assignment's type to the template argument list, but does pass it as a func argument. (Quite possibly a (minor) compiler bug itself - I may be depending on one bug to work around another!) So, if you try to do a template, it will complain about wrong number of arguments to the function. A variadic function gets that error to go away and I can handle it at runtime. This comes with trade-offs though: the big one being that it doesn't work with complex types. Like the code's comment says, I really need the compiler's help to make them work, and it isn't around by the time any of that code is actually run. The best situation would be: @property Dynamic opDispatch(string fieldName)() // getter Dynamic opDispatch(string fieldName, T...)(T t) // function call, // any num of args @property Dynamic opDispatch(string fieldName, T)(T t) // setter obj.blabla(); If those are overloadable, for a blabla known only at runtime, would you have to send it to both the property dispatcher and then afterwards the function dispatcher if it doesn't exist as a property? Then everything would Just Work, without the limitations of the runtime variadic and associated workarounds. But the first two are broken by @property not being recognized in overloads currently*, and the last is broke by the right-hand side of the property assignment not being passed as a template argument. * My preferred fix here would be to give @property one more point in overload resolution so it is slightly preferred over non-property in these situations, but otherwise do nothing. It's the most conservative solution here. I looked at dmd's code, but I don't know the compiler well enough to make it happen. I guess if @property was strengthened, I could work with that too, just by adding an opCall and leaving opDispatch to do nothing but get and set. The property assign not being passed to the template would have to be solved somehow there too though. Anyway, none of the fixes are in place today, so I had to make a choice - either setting requires a named function call or zero arg calling requires a named function. I went with the latter since I figured it is a bit prettier in usage. I would also change implicit declarations into an error, I see you have an throw statement for that but commented out. Yes, the main reason is so the ref returns don't do range violation when you are trying to do an assignment, due to the above situation. It would work with simple assignment: dynobj.name; // throws dynobj.name = 10; // works dynobj.name; // still works But complex assignment won't work there: dynobj.name = someDelegate; // this won't work right, probably // will segfault down the line if I don't throw at runtime over it So my compromise was: dynobj.name() = someDelegate; // uses the opAssign template // which works well But... if dynobj.name didn't already exist, the left hand side of that would throw a range violation, getting a property that doesn't exist. That's why the exception is commented. If I required a .set() method or something like that: dynobj.set(name, whatever you want); That would work, but it no longer looks like a dynamic language... When the compiler progresses a little more (or maybe someone will think of a nicer workaround), we can have the best of all worlds, but for now this is the best I can do while keeping a mostly dynamic language like appearance. (Now, a related question here is weak typing in general. I'm writing this to be very weakly typed - coercing all over the place. Dynamic languages can throw a runtime exception on type mismatch, but I want to basically mimic javascript here, which does not. Besides, D itself is strongly typed - if you want strong types, just use standard D types!
Re: @property needed or not needed?
int func() { return 1; } void func(int n) { } @property int prop() { return 2; } @property void prop(int n) { } void main() { // Without -property switch, all lines can compile. // With -property switch: func(); // OK - OK func(1);// OK - OK func; // OK - OK [*] func = 1; // OK - NG (fixed!) prop(); // OK - NG (fixed!) prop(1);// OK - NG (fixed!) prop; // OK - OK prop = 1; // OK - OK } DIP21: Fixing @property Nice but DIP21 does not discuss dynamic D.
Re: Deprecated Library Functions / Methods
Some modules should be deprecated as a whole, even if we do not yet have a proper replacement yet. For example we know for many years that std.xml is broken and nobody is fixing it, but we still ship it with Shouldn't the new version be called std.xml2 while leaving the old std.xml in phobos? Basically no replacement.
Re: Deprecated Library Functions / Methods
You can either stay at a given version of D. Or you could use something more stable than Phobos. Tango, for example, is very The problem with sticking to a certain version is that all the third party libraries are sticking to a previous or next version (eh ... sometimes same version). Requiring slight modifications for every (eh...) third party library.
Re: @property needed or not needed?
So is it official? We keep the d1 syntax for none property functions? Even the assignment? So for the dynamic stuff opDispatch only (for properties and methods)? The ()() syntax remains for the dynamic delegate properties.
Re: Time for std.reflection
In the latter case, the module needs to save all needed information for ri, so it should plant this: // inside std.algorithm mixin(makeModuleInfoAvailableDynamically()); Is there a way to get the current module at compile time? __traits(allMembers, pkg.modulename)
Re: Shared keyword and the GC?
How does it deal with the problem where a pointer in TLS points to global data, Need to run stop-the-world for shared heap. But it would be interesting to have blocks that have no shared pointers in them. or worse yet, a pointer in the global heap points to TLS? Could you give an example? I'm pretty sure it can't without doing a full pass over the entire heap, which seems to me like it defeats the purpose. Yeah. But I may just be missing out on some restriction (type system or whatever) Objective-C has that makes it feasible.
Re: Shared keyword and the GC?
On Friday, 19 October 2012 at 09:07:55 UTC, sclytrack wrote: How does it deal with the problem where a pointer in TLS points to global data, Need to run stop-the-world for shared heap. But it would be interesting to have blocks that have no shared pointers in them. or worse yet, a pointer in the global heap points to TLS? Could you give an example? import std.stdio; class Local { } class Global { Local data; int [] arr; } Local l2; int [] arr; //tls int main() { shared Global g = new shared(Global); //global heap Local l1 = new Local(); //future local heap // g.data = l1;//disallowed l2 = new Local(); // g.data = l2;//disallowed arr = new int[10]; //future local heap g.arr = cast(shared(int[])) arr; //bypassed. writeln(Complete); return 0; }
Re: Shared keyword and the GC?
Thread-local GC is all about improving scalability by only stopping threads that need to be stopped. If you can't even do that, then any effort towards thread-local GC is quite pointless IMO. Maybe the goal is to run the thread local garbage collectors very frequently and the stop-the-world one's just occasionally. Once your thread has shared in it must participate in the stop-the-world ones. Maybe the threads needs to register to both the thread local garbage collector and the global stop-the-world garbage collector.
Re: Shared keyword and the GC?
On Wednesday, 17 October 2012 at 08:55:55 UTC, Alex Rønne Petersen wrote: On 17-10-2012 10:29, renoX wrote: Hello, in the discussions thread in the recent blog post which summarized how GC works(*), the topic of thread-local GC was further discussed and I pointed out that by default global variables in D are thread local but I was answered that the types doesn't tell which global variable are thread local and which are shared so the GC cannot use this information, is-it true? It seems like a wasted opportunity.. BR, renoX *: http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/ Let's step back for a bit and think about what we want to achieve with thread-local garbage collection. The idea is that we look only at a single thread's heap (and stack/registers, of course) when doing a collection. This means that we can -- theoretically -- stop only one thread at a time and only when it needs to be stopped. This is clearly a huge win in scalability and raw speed. With a scheme like this, it might even be possible to get away with a simple mark-sweep or copying GC per thread instead of a complicated generational GC, mainly due to the paradigms the isolation model induces. Rust, as it is today, can do this. Tasks (or threads if you will - though they aren't the same thing) are completely isolated. Types that can potentially contain pointers into a task's heap cannot be sent to other tasks at all. Rust also does not have global variables. So, let's look at D: 1. We have global variables. 1. Only std.concurrency enforces isolation at a type system level; it's not built into the language, so the GC cannot make assumptions. 1. The shared qualifier effectively allows pointers from one thread's heap into another's. It's important to keep in mind that in order for thread-local GC (as defined above) to be possible at all, *under no circumstances whatsoever must there be a pointer in one thread's heap into another thread's heap, ever*. If this happens and you apply the above GC strategy (stop one thread at a time and scan only that thread's heap), you're effectively dealing with something very similar to the lost object problem on concurrent GC. To clarify with regards to the shared qualifier: It does absolutely nothing. It's useless. All it does is slap a pretty I can be shared arbitrarily across threads label on a type. Even if you have this knowledge in the GC, it's not going to help you, because you *still* have to deal with the problem that arbitrary pointers can be floating around in arbitrary threads. (And don't even get me started on the lack of clear semantics (and even the few semi-agreed-upon but flawed semantics) for shared.) Introduce the noshared keyword.
Re: Returning dynamic array from the function
On Wednesday, 17 October 2012 at 19:22:05 UTC, Simen Kjaeraas wrote: On 2012-10-17, 21:17, m0rph wrote: I tryed to learn how arrays works and found another strange thing: import std.stdio; int[] create() { int[5] a1 = [ 10, 20, 30, 40, 50 ]; int[] b1 = a1; writeln(b1: , b1); return b1; } void main() { int[] a2 = create(); writeln(a2: , a2); } Result of execution: b1: [10, 20, 30, 40, 50] a2: [-142625792, 32767, 4358059, 0, 5] Please explain what's wrong with this code? Why variable a2 contains crap? Is this another dmd/druntime bug or I missed something? b1 points to the exact same data as does a1. This data is stack- allocated, and thus a2 points to an overwritten stack frame. It doesn't give an error when marking the function with safe. @safe int[] create() { }
Re: Returning dynamic array from the function
On Wednesday, 17 October 2012 at 19:46:51 UTC, bearophile wrote: sclytrack: It doesn't give an error when marking the function with safe. @safe int[] create() { } I think marking it @safe is not relevant. In theory a good type system should give an error message on similar code. I don't know if D is supposed to spot similar error situations. Bye, bearophile If that's the case then they should call it safeR D instead of safe D.
Re: handful and interval
On Sunday, 2 September 2012 at 20:24:29 UTC, Walter Bright wrote: On 9/2/2012 7:45 AM, Andrei Alexandrescu wrote: On 9/2/12 4:22 PM, Andrei Alexandrescu wrote: [snip] The alternative would be to simply define these as functions: if (a.among(struct, class, union)) { ... } if (b.between(1, 100)) { ... } Is between inclusive or not of the endpoints? between inclusive in between exclusive
Re: D interface to Fortran
On 06/05/2012 06:49 AM, TJB wrote: Is it possible to interace D with Fortran code? There are old numerical codes that I would prefer to just call directly rather than rewrite them? Thanks, TJB scid https://github.com/cristicbz/scid
Re: Exception caused by calling a pure function repeatedly
On 05/30/2012 04:33 AM, ixid wrote: Having solved Project Euler 300 I wanted to explore which of the strictly superior fold set were redundant but started getting an exception thrown after a few iterations. I've changed the offending part to try to make it as impact-free as possible (my code is not pretty :)), it's now pure and the return is only used with writeln to track the progress of the function yet it still causes an exception after 4 or 5 iterations. http://pastebin.com/j6REskhd The offending function is 'solve', which I've repeatedly called to make the exception as simple as possible along with const data and limited use of the return data. I've tried making it pure/const as well as adding delete on the main data and also removing pure and calling the garbage collector. This is the stack trace crash assembler command: 7C90E8E5 push ebx Does this mean there is a stack overflow? Any ideas what on earth is going on? superior.length = matrixes.length; foreach(inum, i;matrixes.parallel) { //. superior[inum] = true; } Should superior be shared?
Re: Nimrod language
D implements slices as (ptr, length) pairs which causes issues for a GC as that invites lots of interior pointers and GCs tend to have problems with those, causing at least some overhead in the GC/memory system. The site says Nimrod allows for soft-realtime. Could you talk more about the GC.
Which template is recommended.
Below there are two routines with the same name. Apparently both can be present at the same time. Which one of the two is the recommended code? import std.stdio; interface ITest { int first(); int second(); } class Test: ITest { int first() { writeln(first); return 1; } int second() { writeln(second); return 2; } } void routine(T:ITest) (T a) { a.second(); } void routine(T) (T a) if (is(T:ITest)) { a.first(); } int main() { routine(new Test()); return 0; } --- The above example prints out first.
Re: speeding up + ctfe question
On 05/27/2012 01:18 PM, maarten van damme wrote: well, maybe, looking back at it, a range isn't the ideal way to go about generating primes easily. I'm going to implement the sieve of Atkin and make it return an array of primes up to a given number. This might be a bit more useful and fast. Is there somewhere I can catch up on ctfe? after reading andrei's book and the documentation it's still not clear to me how I could make my setquicktestsize function run at compile time. https://github.com/PhilippeSigaud/D-templates-tutorial
Re: speeding up + ctfe question
On 05/26/2012 03:49 PM, maarten van damme wrote: I finally made the primerange I wanted to make. I think I'm using a rather dumb algorithm. The idea is to store the prime we're at in curPrime and the amount of preceding primes in countPrime. Then opindex is able to calculate how many primes following or preceding curPrime we have to find to get the asked value. I'm not english so some names can be poorly chosen. Code is at http://dl.dropbox.com/u/15024434/d/primeRange.d The problem is that it's pretty slow. I wanted to find the first prime number with 10 digits and it literally takes forever (but manages it though). Is there an easy way to speed up or is this the ceiling? (better algorithms, stupidity's I've left,...) I also have an array of primes I use to quicktest to see if something is a prime. You can change it's size using setQuicktestSize at runtime. I want to make it large at compile time though. as I'm new to ctfe I have no idea as to how one can do this. See below for a rather dumb algorithm. The idea is to list a list of prime numbers. The problem is that it is pretty slow and you get a ... //src/main.d(57): Error: template instance main.isDivisable!(499,498) recursive expansion error when the number is too large. I'm not English so the names ARE poorly chosen. //writeln(primeList!(200)); //---don't pick over 200 or it goes nuts //writeln(decompose!(49,2)); template primeList(int index) { static if (index 1) { static if (isPrime!(index)) { enum int [] primeList = primeList!(index-1) ~ [index]; } else { enum int [] primeList = primeList!(index-1); } } else { enum int [] primeList = []; } } template isDivisable( int number, int divisor) { enum bool isDivisable = (number % divisor) == 0; } // 10 --- [2,5] template decompose(int number, int d = 2) { static if (d number) { static if (isDivisable!(number, d)) { enum int [] decompose = [d] ~ decompose!(number/d, d); } else { enum int [] decompose = decompose!(number, d+1); } } else { enum int [] decompose = [number]; } } template isPrimeDecompose(int number, int d = 2) { static if (d number) { static if (isDivisable!(number, d)) { enum bool isPrimeDecompose = false; } else { enum bool isPrimeDecompose = isPrimeDecompose!(number, d+1); } } else { enum bool isPrimeDecompose = true; } } template isPrime(int number) { static if (number 1) enum bool isPrime = isPrimeDecompose!(number, 2); else enum bool isPrime = false; }
Re: clear() and UFCS
On 05/25/2012 05:42 PM, Steven Schveighoffer wrote: On Fri, 25 May 2012 11:37:52 -0400, Steven Schveighoffer schvei...@yahoo.com wrote: On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen a...@lycus.org wrote: On 25-05-2012 17:23, Steven Schveighoffer wrote: On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen a...@lycus..org wrote: On 25-05-2012 16:56, Steven Schveighoffer wrote: Wow, you're right, it's not documented. That should be fixed! Before we do, we should deprecate clear and rename it to finalize, though. I don't like finalize because it's not a finalizer. I think we should mimic other languages that have a finalizer and a deterministic dispose function. -Steve But it calls rt_finalize...? Yeah, because non-deterministic destruction is part of deterministic destruction. finalize - destroy non-gc resources dispose - 1. do deterministic destruction involving possible GC resources 2. call finalize. e.g. a buffered file: finalize - close the file handle dispose - flush the GC allocated buffer into the handle, then close the handle I take it back, dispose is no good. That should be the name of the deterministic destructor in the object. Now I don't have a good name. Finalize isn't right, and neither is dispose... -Steve blank, destroy, trash, dump, zero, bleach, cleanup, sanitize, burn, nuke, eject, jetisson, discard, landfill, waste, litter, debris, recycle, obliterate, annihilate, eradicate, expunge, finish, ravage, wipe, zap, abolish, decimate, demolish, massacre, murder, ruin, slaughter, quash, scrub, splat
Re: input completion system
On 05/16/2012 04:37 AM, Katayama Hirofumi MZ wrote: Hi, everyone! Could you make input completion system for D? There is also DDT for eclipse. It works really well except for all the is(typeof({})) code which is starting to become present everywhere in libraries. Hence we are going to loose a feature.