Re: size_t index=-1;
On Thursday, 17 March 2016 at 17:09:46 UTC, Steven Schveighoffer wrote: On 3/16/16 6:37 PM, Mathias Lang wrote: On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer wrote: No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this. I'm not talking about removing it completely. The implicit conversion should only happen when it's safe: ``` int s; if (s >= 0) // VRP saves the day { uint u = s; } ``` ``` uint u; if (u > short.max) throw new Exception("Argument out of range"); // Or `assert` short s = u; ``` Converting unsigned to signed or vice versa (of the same size type) is safe. No information is lost. Strictly speaking yes, but typically, an `int` isn't used as a bit-pattern but as an integer (it's in the name). Such behaviour is very undesirable for integers. It's the comparison between the two which confuses the heck out of people. I think we can solve 80% of the problems by just fixing that. That's probably true, anyway.
Re: Obtaining argument names in (variadic) functions
On Thursday, 17 March 2016 at 13:53:00 UTC, JR wrote: Interesting, any idea if it is possible to do assignment within template.. Either: printVars!(int abc=5,string def="58")(); or something like printVars!("abc","def",ghi)(5,"58"); What would the use-cases for those be? I don't think the first is valid grammar, and I'm not sure what you want the second to do. Resolve symbols by string literals of their names? That might need a string mixin as they wouldn't be in scope when in the called template function, but I've never tried it. Both use cases are when you want a named parameter, without having to assign it first. I know the first is not valid grammar, was just wondering if you might be smarter than me and see a way to make it valid :) Second one is another possible alternative that I have been thinking about. Basically, say I want to have the named (optional) parameters x and y. In your initial example I would be required to do: ``` int x = 1; string y = "2"; doSomethingWithNamedPars!(x,y)(); ``` I just hoped to shorten that to a one liner similar to: ``` doSomethingWithNamedPars!(x=1,y="2")(); ``` or alternatively ``` doSomethingWithNamedPars!("x","y")(1,"2"); ``` (where doSomethingWithNamedPars's behaviour depends on which named parameters it is passed) Just as a reference, my current approach (in ggplotd) is with named tuples, but that is slightly more verbose than I had hoped: ``` doSomethingWithNamedPars( Tuple!(int, "x", string, "y")( 1, 2 ) ); ```
Re: size_t index=-1;
On 3/16/16 6:37 PM, Mathias Lang wrote: On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer wrote: No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this. I'm not talking about removing it completely. The implicit conversion should only happen when it's safe: ``` int s; if (s >= 0) // VRP saves the day { uint u = s; } ``` ``` uint u; if (u > short.max) throw new Exception("Argument out of range"); // Or `assert` short s = u; ``` Converting unsigned to signed or vice versa (of the same size type) is safe. No information is lost. It's the comparison between the two which confuses the heck out of people. I think we can solve 80% of the problems by just fixing that. And the bug report says it's preapproved from Walter and Andrei. VRP on steroids would be nice, but I don't think it's as trivial to solve. -Steve
Re: size_t index=-1;
On Wednesday, 16 March 2016 at 18:40:56 UTC, Laeeth Isharc wrote: should it be a compiler warning to assign a negative literal to an unsigned without a cast ? yes it should. https://issues.dlang.org/show_bug.cgi?id=3468
immutable array in constructor
In the following code, I explicitly declare array as immutable. But it compiles with the error shown below in the comment. The array object is declared immutable, so how can the compiler say it is a mutable object? In summary, how to pass an immutable array to an immutable constructor? class C { int i; this(immutable int[] array) immutable { i = array[0]; } } void func() { immutable int[] array = [1]; auto c = new C(array); // Error: immutable method C.this is not callable using a mutable object }
Re: Solution to "statement is not reachable" depending on template variables?
On Wednesday, 16 March 2016 at 11:22:02 UTC, rikki cattermole wrote: Change those static if's to just plain old ifs. But then this wouldn't compile, would it? ``` static if(__traits(compiles, __traits(getMember, a, "b"))) { return a.b; } ``` (real code, I am not making this up) Imagine those foreach loops being unrolled and what that happens there isn't just one return there, imagine many many many of them and all of them valid. Yep :-) Perhaps the only solution is to be able to annotate the code to "shut up" DMD about it.
Whitch can replace std::bind/boost::bind ?
foreach (i ; 0..4) { auto th = new Thread(delegate(){listRun(i);});//this is erro _thread[i]= th; th.start(); } void listRun(int i) { writeln("i = ", i); // the value is not(0,1,2,3), it all is 2. } I want to know how to use it like std::bind.
Re: string and char[] in Phobos
On Friday, March 18, 2016 08:24:24 Puming via Digitalmars-d-learn wrote: > Hi, > > I saw from the forum that functions with string like arguments > better use `in char[]` instead of `string` type, because then it > can accept both string and char[] types. > > But recently when actually using D, I found that many phobos > functions/constructors use `string`, while many returns `char[]`, > causing me to do a lot of conv.to!string. And many times I have > to fight with the excessive template error messages. > > Is there a reason to use `string` instead of `in char[]` in > function arguments? Do you tend to change those phobos functions? When a function accepts const(char)[] than it can accept char[], const(char)[], const(char[]), immutable(char)[], and immutable(char[]), which, whereas if it accepts string, then all it accepts are immutable(char)[] and immutable(char[]). So, it's more restrictive, but if you need to return a slice of the array you passed in, if your function accepts const rather than mutable or immutable, then the slice has to be const, and you've lost the type information, which is why inout exists - e.g. if you have inout(char)[] and return the array that you're given, then its constness doesn't change. But inout only works when you return the same type as you pass in, and the function needed to store the string somewhere (e.g. this if it were a property function for setting a member variable), then accepting string would make more sense if it stores string. Otherwise, it would have to allocate a new string (and storing const(char)[] would risk having it change after it was passed to the function). So, the exact constness that should be used depends heavily on what the function is doing. Ali's dconf 2013 talk discusses some of these issues: http://dconf.org/2013/talks/cehreli.html Most functions in Phobos that operate on strings actually are templatized so that they work with varying constness and character type - either that, or they're templatized and operate on arbitrary ranges and not arrays specifically at all. That avoids most of these issues but does mean that the function needs to be templated. I don't know what you're using in Phobos that takes string and returns char[]. That implies an allocation, and if the function is pure, char[] may have been selected, because it could be implicitly converted to string thanks to the fact that the compiler could prove that the char[] being returned had to have been allocated in the function and that there could be no other references to that array. But without knowing exactly which functions you're talking about, I can't really say. In general though, the solution that we've gone with is to templatize functions that operate on strings, and a function that's taking a string explicitly is most likely storing it, in which case, it needs an explicit type, and using an immutable value ensures that it doesn't change later. If you want better insight into what the functions you're referring to do and why, then you'll need to be specific about which ones you're talking about. In any case, in general, the approach that Phobos takes is to operate on ranges of characters and only occasionally uses arrays specifically - except in cases where the value needs to be stored, in which case, string is typically what's used. It used to be that explicit strings were used more, but we've been moving to using ranges as much as possible, so actually seeing string in Phobos should be fairly rare and getting rarer. On a side note, I'd strongly argue against using "in" on function arguments that aren't delegates. in is equivalent to const scope, and scope currently does nothing for any types other than delegates - but it might later, in which case, you could be forced to change your code, depending on the exact semantics of scope for non-delegates. But it does _nothing_ now with non-delegate types regardless, so it's a meaningless attribute that might change meaning later, which makes using it a very bad idea IMHO. Just use const if you want const and leave scope for delegates. I'd actually love to see in deprecated, because it adds no value to the language (since it's equivalent to const scope, which you can use explicitly), and it hides the fact that scope is used. - Jonathan M Davis
Re: size_t index=-1;
On Friday, 18 March 2016 at 14:51:34 UTC, Steven Schveighoffer wrote: Note, I have made these mistakes myself, and I understand what you are asking for and why you are asking for it. But these are bugs. The user is telling the compiler to do one thing, and expecting it to do something else. It's not difficult to fix, and in fact, many lines of code are written specifically to take advantage of these rules. This is why we cannot remove them. The benefit is not worth the cost. Actually, I think I confused things for you by mentioning to `cast(ulong)`. I'm not asking for a Java-style "no unsigned" system (I hate that; it's one of my biggest annoyances with Java). Rather, I'm picking on *implicit* conversions between signed and unsigned. I'm basically saying, "because information is lost when casting between signed and unsigned, all such casts should be explicit". This could make code rather verbose - except that from my experiments, with decent VRP the compiler can actually be surprisingly smart about warning only in those cases where implicit casting is really a bad idea.
Re: size_t index=-1;
On Friday, March 18, 2016 23:48:32 tsbockman via Digitalmars-d-learn wrote: > I'm basically saying, "because information is lost when casting > between signed and unsigned, all such casts should be explicit". See. Here's the fundamental disagreement. _No_ information is lost when converting between signed and unsigned integers. e.g. int i = -1; uint ui = i; int j = i; assert(j == -1); But even if you convinced us, you'd have to convince Walter. And based on previously discussions on this subject, I think that you have an _extremely_ low chance of that. He doesn't even think that there's a problem that void foo(bool bar) {} void foo(long bar) {} foo(1); resulted in call to the bool overload was a problem when pretty much everyone else did. The only thing that I'm aware of that Walter has thought _might_ be something that we should change is allowing the comparison between signed and unsigned integers, and if you read what he says in the bug report for it, he clearly doesn't think it's a big problem: https://issues.dlang.org/show_bug.cgi?id=259 And that's something that clearly causes bugs in way that converting between signed and unsigned integers does not. You're fighting for a lost cause on this one. - Jonathan M Davis
Re: size_t index=-1;
On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer wrote: No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this. -Steve I agree, but implicitly allowing for comparisons between the two allows for easy and *silent* mistakes. Also for comparisons of less-than-zero, for those functions we have that return -1 on failure. import std.string : indexOf; size_t pos = "banana".indexOf("c"); if (pos > 0) { // oops } The above is naturally a programmer error but it's not something that will net you an immediate crash. It will just silently not behave as you meant, and you'll find yourself with a lot of fake bananas.
size_t index=-1;
should it be a compiler warning to assign a negative literal to an unsigned without a cast ?
Re: Obtaining argument names in (variadic) functions
On Wednesday, 16 March 2016 at 20:43:09 UTC, jkpl wrote: I try to anticipate the reason why you want this. [...] I use something *kinda* sort of similar in my toy project to print all fields of a struct, for debugging purposes when stuff goes wrong. Getting the names of the member variables is crucial then. http://dpaste.dzfl.pl/748c4dd97de6
Re: immutable array in constructor
On Thursday, 17 March 2016 at 10:11:43 UTC, Jeff Thompson wrote: This is a simplified example from a larger class I have where I need an immutable constructor. This is because I need to construct an object an pass it to other functions which take an immutable object. So, how to keep an immutable constructor? In that case, new immutable C() should work I believe. Also, if you mark the constructor as pure, new C() should be implicitly convertible to an immutable C.
Re: size_t index=-1;
On Friday, 18 March 2016 at 05:20:35 UTC, Ola Fosheim Grøstaf wrote: Only providing modular arithmetics is a significant language design flaw, but as long as all integers are defined to be modular then there is no fundamental semantic difference either. `ulong.max` and `-1L` are fundamentally different semantically, even with two's complement modular arithmetic. Just because a few operations (addition and subtraction, mainly) can use a common implementation for both, does not change that. Division, for example, cannot be done correctly without knowing whether the inputs are signed or not.