Re: Deprecation
On 1/18/19 5:53 PM, Ali wrote: Hello. I am having an issue with the code below. the out put after compiling is this : Deprecation: foreach: loop index implicitly converted from size_t to uint the code is : auto available = new int[cast(uint) max - min]; foreach (uint i, ref a; available) foreach (i, ref a; available) a = min + i; a = cast(uint)(min + i); Any help would be highly appreciated. -Steve
Re: Deprecation
On Fri, 18 Jan 2019 22:53:23 +, Ali wrote: > Hello. I am having an issue with the code below. the out put after > compiling is this : > > Deprecation: foreach: loop index implicitly converted from size_t to > uint > > the code is : > > auto available = new int[cast(uint) max - min]; > foreach (uint i, ref a; available) > a = min + i; > > Any help would be highly appreciated. You are trying to use a uint (max value 2^32-1) to give an index for an array (which might be more than 2^32-1 elements long). That's deprecated and will be gone from the language in a few releases. Instead, write: foreach (size_t i, ref a; available) a = cast(uint)(min + i);
Re: Deprecation
On Fri, Jan 18, 2019 at 10:53:23PM +, Ali via Digitalmars-d-learn wrote: > Hello. I am having an issue with the code below. the out put after > compiling is this : > > Deprecation: foreach: loop index implicitly converted from size_t to > uint > > the code is : > > auto available = new int[cast(uint) max - min]; Replace uint with size_t. > foreach (uint i, ref a; available) Ditto. > a = min + i; > > Any help would be highly appreciated. T -- Study gravitation, it's a field with a lot of potential.
Deprecation
Hello. I am having an issue with the code below. the out put after compiling is this : Deprecation: foreach: loop index implicitly converted from size_t to uint the code is : auto available = new int[cast(uint) max - min]; foreach (uint i, ref a; available) a = min + i; Any help would be highly appreciated.
Re: depreciated function delete
On Friday, 18 January 2019 at 21:37:38 UTC, Steven Schveighoffer wrote: On 1/18/19 4:32 PM, Ali wrote: On Friday, 18 January 2019 at 21:13:34 UTC, Steven Schveighoffer wrote: On 1/18/19 3:48 PM, alik wrote: Hi there. as you know delete function is depreciated. so I tried to use the __delete function for the code below: if (this.parse_buffer.length > this.parse_size) { __delete(this.parse_buffer); this.parse_buffer.length = this.parse_size; } but in return after I compile code I get the error like : Undefined identifier. when I use destroy instead I don't get any errors. but I want to use __delete because of the garbage collector as it frees up the memory thanks in advance. import core.memory: __delete; thank you for your quick answer. I did it for my own files but should I change something in here : /root/.dub/packages/undead-1.0.9/undead/src/undead/regexp.d(370,17): Deprecation: The delete keyword has been deprecated. Use object.destroy() (and core.memory.GC.free() if applicable) instead. Yeah that should be updated to use __delete, feel free to submit a PR, or raise an issue. -Steve did it but now it shows me another deprecated functions: Deprecation: Symbol object.string is not visible from module math because it is privately imported in module string Deprecation: foreach: loop index implicitly converted from size_t to int /root/.dub/packages/undead-1.0.9/undead/src/undead/socketstream.d(124,32): Deprecation: undead.socketstream.SocketStream.seek cannot be annotated with @disable because it is overriding a function in the base class instead of @disable I dont have any idea what to use.
Re: depreciated function delete
On 1/18/19 4:32 PM, Ali wrote: On Friday, 18 January 2019 at 21:13:34 UTC, Steven Schveighoffer wrote: On 1/18/19 3:48 PM, alik wrote: Hi there. as you know delete function is depreciated. so I tried to use the __delete function for the code below: if (this.parse_buffer.length > this.parse_size) { __delete(this.parse_buffer); this.parse_buffer.length = this.parse_size; } but in return after I compile code I get the error like : Undefined identifier. when I use destroy instead I don't get any errors. but I want to use __delete because of the garbage collector as it frees up the memory thanks in advance. import core.memory: __delete; thank you for your quick answer. I did it for my own files but should I change something in here : /root/.dub/packages/undead-1.0.9/undead/src/undead/regexp.d(370,17): Deprecation: The delete keyword has been deprecated. Use object.destroy() (and core.memory.GC.free() if applicable) instead. Yeah that should be updated to use __delete, feel free to submit a PR, or raise an issue. -Steve
Re: depreciated function delete
On Friday, 18 January 2019 at 21:13:34 UTC, Steven Schveighoffer wrote: On 1/18/19 3:48 PM, alik wrote: Hi there. as you know delete function is depreciated. so I tried to use the __delete function for the code below: if (this.parse_buffer.length > this.parse_size) { __delete(this.parse_buffer); this.parse_buffer.length = this.parse_size; } but in return after I compile code I get the error like : Undefined identifier. when I use destroy instead I don't get any errors. but I want to use __delete because of the garbage collector as it frees up the memory thanks in advance. import core.memory: __delete; -Steve thank you for your quick answer. I did it for my own files but should I change something in here : /root/.dub/packages/undead-1.0.9/undead/src/undead/regexp.d(370,17): Deprecation: The delete keyword has been deprecated. Use object.destroy() (and core.memory.GC.free() if applicable) instead.
Re: depreciated function delete
On 1/18/19 3:48 PM, alik wrote: Hi there. as you know delete function is depreciated. so I tried to use the __delete function for the code below: if (this.parse_buffer.length > this.parse_size) { __delete(this.parse_buffer); this.parse_buffer.length = this.parse_size; } but in return after I compile code I get the error like : Undefined identifier. when I use destroy instead I don't get any errors. but I want to use __delete because of the garbage collector as it frees up the memory thanks in advance. import core.memory: __delete; -Steve
depreciated function delete
Hi there. as you know delete function is depreciated. so I tried to use the __delete function for the code below: if (this.parse_buffer.length > this.parse_size) { __delete(this.parse_buffer); this.parse_buffer.length = this.parse_size; } but in return after I compile code I get the error like : Undefined identifier. when I use destroy instead I don't get any errors. but I want to use __delete because of the garbage collector as it frees up the memory thanks in advance.
Re: byte + byte = int: why?
On Fri, Jan 18, 2019 at 01:49:23PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 1/18/19 12:26 PM, Mek101 wrote: [...] > > Then why isn't int + int = long? If i did the example above, they > > wouldn't fit in a int for sure, yet the result is of the same type. > > Why should byte be any different? > > There are other inconsistencies too, like += (which works on byte += > byte). > > As others have said, those are the rules D has for historical reasons, > you just have to deal with them. [...] Or use my nopromote module. ;-) T -- Nearly all men can stand adversity, but if you want to test a man's character, give him power. -- Abraham Lincoln
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, January 18, 2019 8:34:22 AM MST Michael via Digitalmars-d-learn wrote: > On Friday, 18 January 2019 at 13:29:29 UTC, Adam D. Ruppe wrote: > > On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote: > >> This, to be, looks like quite the explicit conversion, no? > > > > Yeah, I agree. But the language is silly. I just leave the type > > out of foreach and explicitly cast it inside the body. > > Thank you all for the concise explanations and suggestions, I > think that's fairly straightforward. I thought perhaps I was > doing the sensible thing of dealing with the conversion inside > the foreach statement, but I guess not! Well, you were really doing the equivalent of simply declaring a variable without a cast. e.g. int i = arr.length; rather than int i = cast(int)arr.length; In general, if the compiler treated giving the foreach variable an explicit type as being a cast, it would make it really easy to screw up and unknowingly give a different type than the actual type of the values and end up with an invisible cast, which could cause subtle bugs. IIRC, the only case where foreach treats giving an explict type as anything like a cast is when you're iterating over a string type, and you give a character type different from the character type of the string. In that case, it actually decodes the string from one Unicode encoding and encodes it in the other. Whether the language should have done that rather than requiring that a library solution be used is debatable (I believe that it far predates Phobos having the Unicode handling that it does now), but at least it can't result in stuff like silent truncation. Worst case, it has a silent performance hit, or you get an unexpected UnicodeException at runtime due to invalid Unicode. - Jonathan M Davis
Re: byte + byte = int: why?
On 1/18/19 12:26 PM, Mek101 wrote: On Friday, 18 January 2019 at 17:15:09 UTC, Steven Schveighoffer wrote: What is 127 + 127? Answer: 254. Which if converted to a byte is -127. Not what you might expect if you are doing addition. Quite similar to int.max + int.max Indeed. But this is where C drew the line, so it's where D draws the line as well. In fact, D promotes all integral types smaller than int to int to do arithmetic. And if the result might not fit into what you are assigning it to, it requires a cast or mask. Then why isn't int + int = long? If i did the example above, they wouldn't fit in a int for sure, yet the result is of the same type. Why should byte be any different? There are other inconsistencies too, like += (which works on byte += byte). As others have said, those are the rules D has for historical reasons, you just have to deal with them. -Steve
Re: Alternative to Interfaces
On Friday, January 18, 2019 8:08:47 AM MST Kagamin via Digitalmars-d-learn wrote: > On Friday, 18 January 2019 at 00:08:00 UTC, 1001Days wrote: > > It works, but I have two questions regarding its efficacy: is > > it viable in the long run, and is it now possible to use > > delegates without the GC? > > GC is just a handy memory management approach, it even works for > C and C++, (example: gcc), nothing in D needs GC if you manage > memory in a different way. In fact there are D libraries that > rely solely on manual memory management. Yes, but some D features will use the GC, and you can't really stop that aside from simply not using those features. The list of such features is short, but delegates are on it. scope will get around the allocations in some cases, but in general, if you use delegates, you're going to allocate with the GC. There are alternatives to using delegates which will get you similar behavior allocating (e.g. functors), but the allocations that happen for delegates and lambdas is one of the biggest reasons that some folks avoid std.algorithm and complain that it allocates. That's what happens when you pass stuff that the compiler decides has to have closures allocated for it. Completely avoiding the GC with D is possible, but it tends to require that you be very careful and have a good understanding of where D needs to use the GC to do what it does (though the fact that we now have @nogc, and it screams at you if the code allocates does help you catch GC usage when you didn't realize that it was there). - Jonathan M Davis
Re: How to include curl.lib?
On Friday, 18 January 2019 at 15:49:09 UTC, Head Scratcher wrote: On Thursday, 17 January 2019 at 20:42:48 UTC, Andre Pany wrote: You do not need to specify curl.lib but you have to bundle your executable with curl.dll. Recent Windows 10 versions might even come with curl.dll but I am not 100% sure. Thank you for your reply, Andre. My computer has curl.exe in the Windows\System32 folder, but I'm not sure I can guarantee that any users of my EXE will have that. I am writing a utility program that performs FTP. According to the std.curl source code, curl.lib can be statically linked. Is that not the case? I thought also the libcurl.dll is available but it doesn't seems so. The curl executable does not have any use in your case. I am not an expert in this area but I think it should be possible, but I do not how. I can only give you the advice to start with the dll approach. At any point later you can just switch to the static linking approach. Depending on the license type of your application you might also check whether you are allowed to statically bind curl. Kind regards Andre
Re: byte + byte = int: why?
On Friday, 18 January 2019 at 17:26:35 UTC, Mek101 wrote: Then why isn't int + int = long? If i did the example above, they wouldn't fit in a int for sure, yet the result is of the same type. Why should byte be any different? Because C didn't define it that way. And C didn't define it that way because of convenience and efficiency on common hardware biased toward int (and nowadays with 64 bit, we kept int at 32 for compatibility basically, the inertia set in). We have proposed to change it before, but the main policy D has right now is "if it looks like C, it works like C or doesn't compile at all", so programmer habits and such don't silently bite them.
Re: byte + byte = int: why?
On Fri, Jan 18, 2019 at 05:26:35PM +, Mek101 via Digitalmars-d-learn wrote: > On Friday, 18 January 2019 at 17:15:09 UTC, Steven Schveighoffer wrote: > > What is 127 + 127? Answer: 254. Which if converted to a byte is > > -127. Not what you might expect if you are doing addition. > > Quite similar to int.max + int.max > > > In fact, D promotes all integral types smaller than int to int to do > > arithmetic. And if the result might not fit into what you are > > assigning it to, it requires a cast or mask. > > Then why isn't int + int = long? If i did the example above, they > wouldn't fit in a int for sure, yet the result is of the same type. > Why should byte be any different? It's historical baggage from C's integer promotion rules, that's all there is to it. Many people seem to think that's a good thing. I personally think it sucks, and so I've written a nopromote module to work around the autopromotion (see my other post). OTOH if you're concerned about int overflow, just cast to long: int x = int.max, y = int.max; auto result = cast(long)x + y; Of course, eventually you run out of options, e.g., if you try to add ulong.max to ulong.max. Generally most people won't run into that, but if you're concerned about that, you could pull out the big guns and import std.bigint. :-D T -- Music critic: "That's an imitation fugue!"
Re: byte + byte = int: why?
On Fri, Jan 18, 2019 at 05:09:52PM +, Mek101 via Digitalmars-d-learn wrote: > I have the following line of code: > > temp[fowardI] = temp[fowardI] + temp[backwardI]; > > Where temp is a byte array (byte[]). When I try to compile it dmd > gives me this error: > > source/hash.d(11,25): Error: cannot implicitly convert expression > `cast(int)temp[fowardI] + cast(int)temp[backwardI]` of type `int` to `byte` > /usr/bin/dmd failed with exit code 1. > > Meaning that the byte type doesn't have a + operator. I know by > experience that the pitfall came from C# (which I also use), and the > absence of the operator was justified because the CLI didn't support > addition between values smaller than an int, and also byte wasn't > enough "numberish" to be used as such, and I should have used int > instead. > > But why the D language doesn't implement the operator on byte? For much the same reasons, and also that both C# and C inherited (to various extents) C's integer promotion rules. Personally, I hate it, but it's what we have, and changing it now would break too many things, so we're stuck with it. Basically, arithmetic on everything smaller than an int will implicitly promote to int first. Which means the result will be int. But unlike C, where you can implicitly narrow it back to a byte, in D the narrowing must be explicit (to avoid accidental overflow when a narrow int type like byte or short is too small to store the result), resulting in the annoying situation where byte + byte != byte. To work around this, you can use my nopromote module (code included below), that implements a wrapper type that automatically casts back to the narrow int type: ubyte x = 1; ubyte y = 2; auto z = x.np + y; // np stands for "no promote" static assert(is(typeof(x) == ubyte)); assert(z == 3); x = 255; z = x.np + y; // don't promote to int, so this will wrap assert(z == 1); // wrapped around to 1 Check the unittests for more examples. OT1H, having to write .np everywhere is annoying, but OTOH it does document intent in the code, that you're expecting wraparound and have presumably taken the necessary precautions to mitigate any ill-effects that wrapping may have, so in that sense it's a good thing. T -- It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels. ---snip-- /** * Truncating wrapper around built-in narrow ints to work around stupid casts. */ module nopromote; enum isNarrowInt(T) = is(T : int) || is(T : uint); /** * A wrapper around a built-in narrow int that truncates the result of * arithmetic operations to the narrow type, overriding built-in int promotion * rules. */ struct Np(T) if (isNarrowInt!T) { T impl; alias impl this; /** * Truncating binary operator. */ Np opBinary(string op, U)(U u) if (is(typeof((T x, U y) => mixin("x " ~ op ~ " y" { return Np(cast(T) mixin("this.impl " ~ op ~ " u")); } /** * Truncating unary operator. */ Np opUnary(string op)() if (is(typeof((T x) => mixin(op ~ "cast(int) x" { return Np(cast(T) mixin(op ~ " cast(int) this.impl")); } /** * Infectiousness: any expression containing Np should automatically use Np * operator semantics. */ Np opBinaryRight(string op, U)(U u) if (is(typeof((T x, U y) => mixin("x " ~ op ~ " y" { return Np(cast(T) mixin("u " ~ op ~ " this.impl")); } } /** * Returns: A lightweight wrapped type that overrides built-in arithmetic * operators to always truncate to the given type without promoting to int or * uint. */ auto np(T)(T t) if (isNarrowInt!T) { return Np!T(t); } // Test binary ops @safe unittest { ubyte x = 1; ubyte y = 2; auto z = x.np + y; static assert(is(typeof(z) : ubyte)); assert(z == 3); byte zz = x.np + y; assert(zz == 3); x = 255; z = x.np + y; assert(z == 1); } @safe unittest { byte x = 123; byte y = 5; auto z = x.np + y; static assert(is(typeof(z) : byte)); assert(z == byte.min); byte zz = x.np + y; assert(zz == byte.min); } @safe unittest { import std.random; short x = cast(short) uniform(0, 10); short y = 10; auto z = x.np + y; static assert(is(typeof(z) : short)); assert(z == x + 10); short s = x.np + y; assert(s == x + 10); } // Test unary ops @safe unittest { byte b = 10; auto c = -b.np; static assert(is(typeof(c) : byte)); assert(c == -10); ubyte ub = 16; auto uc = -ub.np; static assert(is(typeof(uc) : ubyte)); assert(uc == 0xF0); } version(unittest) { // These tests are put here as actual module functions, to force optimizer // not to discard calls to
Re: byte + byte = int: why?
On Friday, 18 January 2019 at 17:09:52 UTC, Mek101 wrote: Where temp is a byte array (byte[]) Oh btw, D's byte is signed, range -128 to 127, unlike C# where it is unsigned. C#'s `byte` is represented as D's `ubyte` (meaning "unsigned byte"), range 0-255.
Re: byte + byte = int: why?
On Friday, 18 January 2019 at 17:15:09 UTC, Steven Schveighoffer wrote: What is 127 + 127? Answer: 254. Which if converted to a byte is -127. Not what you might expect if you are doing addition. Quite similar to int.max + int.max In fact, D promotes all integral types smaller than int to int to do arithmetic. And if the result might not fit into what you are assigning it to, it requires a cast or mask. Then why isn't int + int = long? If i did the example above, they wouldn't fit in a int for sure, yet the result is of the same type. Why should byte be any different?
Re: byte + byte = int: why?
On Friday, 18 January 2019 at 17:09:52 UTC, Mek101 wrote: Meaning that the byte type doesn't have a + operator. Well, it DOES have a + operator, it just returns int that can be squished to a size if and only if the compiler proves it fits. A bit of background: the C language was designed on a machine that did arithmetic in a fixed size register. It defined `int` to be at least the size of this register and for all arithmetic to be expanded to at least that same size. In other words, anything smaller than an `int` is converted to an `int` before operations are done to it. D (and C# via the CLR being designed in the same way, among other languages) inherited this rule from C. So a + a will be converted to int for anything smaller than int, like byte or short. Now the difference between C and D is that C would let you assign that result right back to the small type without complaining, whereas D issues the error. Why? The reason is the carry bit. Consider the case of 127 + 127. The answer is too big to fit in a signed byte; one bit will carry over and be dropped. D considers this potential data loss and wants you to make a conscious choice about it via an explicit cast. If the compiler knows for certain the numbers will fit, it allows it. Like 64 + 5 will implicitly cast to a byte because the compiler sees the size of the result. But for runtime values, it is usually unsure and forces you to do the cast. temp[fowardI] = cast(byte) (temp[fowardI] + temp[backwardI]); that will work.
Re: byte + byte = int: why?
On 1/18/19 12:09 PM, Mek101 wrote: I have the following line of code: temp[fowardI] = temp[fowardI] + temp[backwardI]; Where temp is a byte array (byte[]). When I try to compile it dmd gives me this error: source/hash.d(11,25): Error: cannot implicitly convert expression `cast(int)temp[fowardI] + cast(int)temp[backwardI]` of type `int` to `byte` /usr/bin/dmd failed with exit code 1. Meaning that the byte type doesn't have a + operator. I know by experience that the pitfall came from C# (which I also use), and the absence of the operator was justified because the CLI didn't support addition between values smaller than an int, and also byte wasn't enough "numberish" to be used as such, and I should have used int instead. But why the D language doesn't implement the operator on byte? What is 127 + 127? Answer: 254. Which if converted to a byte is -127. Not what you might expect if you are doing addition. In fact, D promotes all integral types smaller than int to int to do arithmetic. And if the result might not fit into what you are assigning it to, it requires a cast or mask. See documentation here: https://dlang.org/spec/type.html#usual-arithmetic-conversions -Steve
byte + byte = int: why?
I have the following line of code: temp[fowardI] = temp[fowardI] + temp[backwardI]; Where temp is a byte array (byte[]). When I try to compile it dmd gives me this error: source/hash.d(11,25): Error: cannot implicitly convert expression `cast(int)temp[fowardI] + cast(int)temp[backwardI]` of type `int` to `byte` /usr/bin/dmd failed with exit code 1. Meaning that the byte type doesn't have a + operator. I know by experience that the pitfall came from C# (which I also use), and the absence of the operator was justified because the CLI didn't support addition between values smaller than an int, and also byte wasn't enough "numberish" to be used as such, and I should have used int instead. But why the D language doesn't implement the operator on byte?
Re: How to include curl.lib?
On Thursday, 17 January 2019 at 20:42:48 UTC, Andre Pany wrote: You do not need to specify curl.lib but you have to bundle your executable with curl.dll. Recent Windows 10 versions might even come with curl.dll but I am not 100% sure. Thank you for your reply, Andre. My computer has curl.exe in the Windows\System32 folder, but I'm not sure I can guarantee that any users of my EXE will have that. I am writing a utility program that performs FTP. According to the std.curl source code, curl.lib can be statically linked. Is that not the case?
Re: Runtime heterogeneous collections?
On Thursday, 17 January 2019 at 02:21:21 UTC, Steven O wrote: void main() { alias Rec_type = Tuple!(int, "x", int, "y", int, "z"); RedBlackTree!Rec_type[1] test; } alias Rec_type1 = Tuple!(int, "x", int, "y", int, "z"); alias Rec_type2 = Tuple!(int, "x", int, "y", string, "z"); Tuple!(RedBlackTree!Rec_type1, "x", RedBlackTree!Rec_type2, "z") test; Similar questions were asked before, usually such heterogeneous collections are not the best solution to the problem at hand.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 18 January 2019 at 13:29:29 UTC, Adam D. Ruppe wrote: On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote: This, to be, looks like quite the explicit conversion, no? Yeah, I agree. But the language is silly. I just leave the type out of foreach and explicitly cast it inside the body. Thank you all for the concise explanations and suggestions, I think that's fairly straightforward. I thought perhaps I was doing the sensible thing of dealing with the conversion inside the foreach statement, but I guess not!
Re: Runtime heterogeneous collections?
On Friday, 18 January 2019 at 15:07:41 UTC, Steven Schveighoffer wrote: On 1/18/19 9:58 AM, Alex wrote: On Friday, 18 January 2019 at 13:31:28 UTC, Steven Schveighoffer wrote: [...] In this case, I would say Phobos lacks an appropriate interface definition, what do you think? But what is the common interface between those 2 types? Even in Dcollections, where RedBlackTree came from, there was no interfaces that didn't specify the type they were dealing with. In other words, there is no common interface for sets of 2 different types. -Steve Aha... I see... all important methods are templated on the element type... hmm.
Re: Runtime heterogeneous collections?
On 1/18/19 10:10 AM, Neia Neutuladh wrote: On Fri, 18 Jan 2019 10:07:41 -0500, Steven Schveighoffer wrote: But what is the common interface between those 2 types? Even in Dcollections, where RedBlackTree came from, there was no interfaces that didn't specify the type they were dealing with. In other words, there is no common interface for sets of 2 different types. ..empty(), .clear(), .length(), and .toString(sink, formatspec). Which is kind of anemic. Might as well use Object. Yeah, I didn't bother with any of those as base interfaces. Probably the most basic interface for dcollections was Iterator(V): https://github.com/schveiguy/dcollections/blob/master/dcollections/model/Iterator.d#L40-L58 -Steve
Re: Is there a nice syntax to achieve optional named parameters?
On Fri, 18 Jan 2019 09:39:31 +, John Burton wrote: > On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote: > >> struct Config { >> string title; >> int width; >> } >> >> struct Window { >> this(Config config) > > It likely is a bad idea for a small struct like this but if it was much > bigger would it makes sense to write this as :- > > this(const ref Config config) > > Which is what you might do in C++ or does D handle this differently? Creating a window is the dominating cost here. If you're creating enough windows that copying them is a problem, you're doing something seriously weird and it might be more productive to step back and think about that than to switch to const ref.
Re: Runtime heterogeneous collections?
On Fri, 18 Jan 2019 10:07:41 -0500, Steven Schveighoffer wrote: > But what is the common interface between those 2 types? Even in > Dcollections, where RedBlackTree came from, there was no interfaces that > didn't specify the type they were dealing with. In other words, there is > no common interface for sets of 2 different types. .empty(), .clear(), .length(), and .toString(sink, formatspec). Which is kind of anemic. Might as well use Object.
Re: Alternative to Interfaces
On Friday, 18 January 2019 at 00:08:00 UTC, 1001Days wrote: It works, but I have two questions regarding its efficacy: is it viable in the long run, and is it now possible to use delegates without the GC? GC is just a handy memory management approach, it even works for C and C++, (example: gcc), nothing in D needs GC if you manage memory in a different way. In fact there are D libraries that rely solely on manual memory management.
Re: Runtime heterogeneous collections?
On 1/18/19 9:58 AM, Alex wrote: On Friday, 18 January 2019 at 13:31:28 UTC, Steven Schveighoffer wrote: To answer the OP, what he wants is an array of different RedBlackTrees. Since RedBlackTree is a class, his code is not far off from something that works. This does compile, and produces an Object[]: auto arr = [ redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, "abc")), redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3)) ]; Then you have to cast each object into it's appropriate type to use it. That is not as easy, as you have to know the exact instantiation of tree type. In this case, I would say Phobos lacks an appropriate interface definition, what do you think? But what is the common interface between those 2 types? Even in Dcollections, where RedBlackTree came from, there was no interfaces that didn't specify the type they were dealing with. In other words, there is no common interface for sets of 2 different types. -Steve
Re: Runtime heterogeneous collections?
On Friday, 18 January 2019 at 13:31:28 UTC, Steven Schveighoffer wrote: To answer the OP, what he wants is an array of different RedBlackTrees. Since RedBlackTree is a class, his code is not far off from something that works. This does compile, and produces an Object[]: auto arr = [ redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, "abc")), redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3)) ]; Then you have to cast each object into it's appropriate type to use it. That is not as easy, as you have to know the exact instantiation of tree type. In this case, I would say Phobos lacks an appropriate interface definition, what do you think?
Re: Is there a nice syntax to achieve optional named parameters?
On Friday, 18 January 2019 at 09:39:31 UTC, John Burton wrote: It likely is a bad idea for a small struct like this but if it was much bigger would it makes sense to write this as :- this(const ref Config config) Which is what you might do in C++ or does D handle this differently? For big Config struct it probably doesn't matter, but ref parameters don't accept rvalues.
Re: Runtime heterogeneous collections?
On 1/17/19 11:06 PM, Jonathan M Davis wrote: On Thursday, January 17, 2019 1:21:41 AM MST Dukc via Digitalmars-d-learn wrote: On Thursday, 17 January 2019 at 02:27:20 UTC, Neia Neutuladh wrote: 1. Make a wrapper class. Now you can store Object[], or you can make a base class or base interface and use that. 2. Use Variant, which can wrap anything, or the related Algebraic, which can wrap a fixed collection of types. 3. Use an union. However, only do this if you always know from outside what type of data is stored in each node. If you need to memoize the type of data for each node, better resort to 1. or 2. Variant types are really just user-friendly wrappers around unions. So, pedantically, using a variant type such as Variant or Albegbraic and using a union are fundamentally the same thing, though obviously, the actual usage in terms of the code that you write is not the same, since if you use a union directly, you have to deal with the union directly (including figuring out how to know which type the union currently holds), whereas with a Variant, you're using its API rather than dealing with the union directly. In general, it's probably better to use Variant rather than union simply because Variant deals with the type safety for you. A variant is not a union. Algebraic is a union, but Variant can hold ANY type, even types your code doesn't know about. To answer the OP, what he wants is an array of different RedBlackTrees. Since RedBlackTree is a class, his code is not far off from something that works. This does compile, and produces an Object[]: auto arr = [ redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, "abc")), redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3)) ]; Then you have to cast each object into it's appropriate type to use it. That is not as easy, as you have to know the exact instantiation of tree type. In this case, you are better off using a union, or an Algebraic as your array element type. If you use something like https://code.dlang.org/packages/taggedalgebraic it could be quite usable. -Steve
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote: This, to be, looks like quite the explicit conversion, no? Yeah, I agree. But the language is silly. I just leave the type out of foreach and explicitly cast it inside the body.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote: Hello all, I am getting this deprecation warning when compiling using DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what the problem is, however, because the code producing these warnings tends to be of the form: foreach (int i, ref prop; props) This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? Thanks, Michael. foreach (int i, ref prop; props) All you need to do is foreach (i, ref prop; props) The reason for the deprecation is that if your array props is > 2GB int can't span the range of indices necessary because it will overflow.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On 1/18/19 7:27 AM, Michael wrote: Hello all, I am getting this deprecation warning when compiling using DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what the problem is, however, because the code producing these warnings tends to be of the form: foreach (int i, ref prop; props) This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? That's one possibility. You can avoid to!int by using a mask or a cast: foreach(_i, ref prop; props) { int i = _i & 0x_; auto i2 = cast(int)_i; } It's less than ideal, but the reason is that there is a possibility that props could have 2^31 or more elements, in which case int will not cut it. It's forcing you to make that decision that it's OK vs. the compiler making that assumption. Any time the compiler is throwing away data without a cast, D tends to require buy in from the developer. Note that this is much more of a problem with smaller types (short or byte), but it would be inconsistent not to also flag int as problematic. I would recommend just using foreach(i, ref prop; props) and casting only where it's absolutely necessary. -Steve
Deprecation: foreach: loop index implicitly converted from size_t to int
Hello all, I am getting this deprecation warning when compiling using DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what the problem is, however, because the code producing these warnings tends to be of the form: foreach (int i, ref prop; props) This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? Thanks, Michael.
Re: Is there a nice syntax to achieve optional named parameters?
On Friday, 18 January 2019 at 09:39:31 UTC, John Burton wrote: On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote: struct Config { string title; int width; } struct Window { this(Config config) It likely is a bad idea for a small struct like this but if it was much bigger would it makes sense to write this as :- this(const ref Config config) Which is what you might do in C++ or does D handle this differently? You'd better profile and only then act. Seriously, whatever you know and familiar with in C++ might not work with D, you'll just end up with C++'ish code that just happens to be written in D. D is not C++, and such premature optimizations might cause more harm if applied on occassion or out of habit. IIRC D structs are all movable, so doing const refs here and there or using writing to ref parameter instead normal return(RVO) is likely bad for your code. D has its own ABI, it's not even compatible with C++, so when you pass structs by value it may or may not produce similar asm as C++ compilers does. When struct contains strings/arrays they are anyway managed by GC(unless you allocated it on your own), but this is something that more seasoned D users can explain in better details and cleaner explanation than me, if it means anything at all. Even without all this, do you really want to mess up your codebase with implementation details about how it should do it, or write clean (self)documented code? Is it really going to be a bottleneck in your program? Passing one big struct at widget's creation on program startup and some rare events really going to kill performance? Why not just write working code first and then identify bottlenecks and optimize when it absolutely ultimately necessary? Btw I don't remember much ref parameters in phobos, just look at it... I found only 4 ref consts it in std.file, 3 in std.array, other modules more likely to have them in comparison operators(I have no idea why, to not introduce potential RVO case?) and in unit tests for testing correct behavior. Again, D is not C++, what might work or even considered "good practice" there may or may not work here. So just profile it!
Re: Is there a nice syntax to achieve optional named parameters?
On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote: struct Config { string title; int width; } struct Window { this(Config config) It likely is a bad idea for a small struct like this but if it was much bigger would it makes sense to write this as :- this(const ref Config config) Which is what you might do in C++ or does D handle this differently?
Re: Read a text file in any position.
On Friday, 18 January 2019 at 08:49:08 UTC, bauss wrote: On Friday, 18 January 2019 at 08:10:25 UTC, Giovanni Di Maria wrote: Hi All I have a text file like this: 11 22 33 44 55 66 77 .. I execute these functions: i = archive.readln(); i = archive.readln(); i = archive.readln(); i = archive.readln(); so "i" is 44. Is there a method to move the pointer of file to beginning of file or to any position (for example back to 2nd row), without to close the file? Thank you very much. Regards Giovanni Use File (https://dlang.org/library/std/stdio/file.html) And seek() (https://dlang.org/library/std/stdio/file.seek.html) And then one of its read functions. rawRead will let you read the raw bytes at the position. Thank you very very much. Giovanni
Re: Read a text file in any position.
On Friday, 18 January 2019 at 08:10:25 UTC, Giovanni Di Maria wrote: Hi All I have a text file like this: 11 22 33 44 55 66 77 .. I execute these functions: i = archive.readln(); i = archive.readln(); i = archive.readln(); i = archive.readln(); so "i" is 44. Is there a method to move the pointer of file to beginning of file or to any position (for example back to 2nd row), without to close the file? Thank you very much. Regards Giovanni Use File (https://dlang.org/library/std/stdio/file.html) And seek() (https://dlang.org/library/std/stdio/file.seek.html) And then one of its read functions. rawRead will let you read the raw bytes at the position.
Read a text file in any position.
Hi All I have a text file like this: 11 22 33 44 55 66 77 .. I execute these functions: i = archive.readln(); i = archive.readln(); i = archive.readln(); i = archive.readln(); so "i" is 44. Is there a method to move the pointer of file to beginning of file or to any position (for example back to 2nd row), without to close the file? Thank you very much. Regards Giovanni