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?
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: 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 */
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: 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: 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.
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: 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);