Re: isCallable fails

2021-01-21 Thread frame via Digitalmars-d-learn

On Friday, 22 January 2021 at 03:40:40 UTC, tsbockman wrote:
Cars are mass-produced copies of a relatively small number of 
rather similar designs, and mechanics' customers *pay them* to 
understand and fix their cars so that the customers don't have 
to.


I knew this argument comes...


Nevertheless, I will use your analogy:

You: My car shakes when I turn left. What do you think is 
wrong with it?


Mechanic: Hard to say. Bring it in to the shop and I'll 
take a look.


No. It's more that I did say: The board computer message is 
weird, it points to one of my tires but does not tell me the 
correct error. The tire seems to be wrecked. There is a scratch - 
but what could cause it? Someone with expierence (a mechanic) 
know this kind of error? I kindly ask.


But mechanics do not listen and telling me I need to do an oil 
change and why it's important.


--

If someone is interested:

I think it's a bug that the compiler cannot handle this recursion 
correctly. By calling isCallable!S and parsing the structs "alias 
this" not the complete get() content need to be parsed as only 
the return type is relevant here - which is already known: T


I have to arrange that the problematic code is not parsed when 
calling isCallable, so the only solution was a proxy method that 
switch to get() in runtime to satisfy the compiler, not very 
pretty, but works:


struct foo(T) {
   alias proxy this;
   T delegate() p;

   // called from this(), this(this)
   void initProxy() {
  p = delegate() { return get; };
   }

   T get() {
 // problematic code
   }

   T proxy() {
 return p();
   }
}


Re: std.algorithm.splitter on a string not always bidirectional

2021-01-21 Thread Jon Degenhardt via Digitalmars-d-learn

On Friday, 22 January 2021 at 05:51:38 UTC, Jon Degenhardt wrote:
On Thursday, 21 January 2021 at 22:43:37 UTC, Steven 
Schveighoffer wrote:

auto sp1 = "a|b|c".splitter('|');

writeln(sp1.back); // ok

auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v));

writeln(sp2.back); // error, not bidirectional

Why? is it an oversight, or is there a good reason for it?

-Steve


I believe the reason is two-fold. First, splitter is lazy. 
Second, the range splitting is defined in the forward 
direction, not the reverse direction. A bidirectional range is 
only supported if it is guaranteed that the splits will occur 
at the same points in the range when run in either direction. 
That's why the single element delimiter is supported. Its 
clearly the case for the predicate function in your example. If 
that's known to be always true then perhaps it would make sense 
to enhance splitter to generate bidirectional results in this 
case.


--Jon


Note that the predicate might use a random number generator to 
pick the split points. Even for same sequence of random numbers, 
the split points would be different if run from the front than if 
run from the back.


Re: std.algorithm.splitter on a string not always bidirectional

2021-01-21 Thread Jon Degenhardt via Digitalmars-d-learn
On Thursday, 21 January 2021 at 22:43:37 UTC, Steven 
Schveighoffer wrote:

auto sp1 = "a|b|c".splitter('|');

writeln(sp1.back); // ok

auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v));

writeln(sp2.back); // error, not bidirectional

Why? is it an oversight, or is there a good reason for it?

-Steve


I believe the reason is two-fold. First, splitter is lazy. 
Second, the range splitting is defined in the forward direction, 
not the reverse direction. A bidirectional range is only 
supported if it is guaranteed that the splits will occur at the 
same points in the range when run in either direction. That's why 
the single element delimiter is supported. Its clearly the case 
for the predicate function in your example. If that's known to be 
always true then perhaps it would make sense to enhance splitter 
to generate bidirectional results in this case.


--Jon


Re: std.algorithm.splitter on a string not always bidirectional

2021-01-21 Thread Ali Çehreli via Digitalmars-d-learn

On 1/21/21 4:51 PM, H. S. Teoh wrote:

> But I wouldn't be surprised if there was some
> surprising corner case for which this doesn't work / would have onerous
> characteristics.

Likely. :) Here is one for uniq.back, which includes a link at the 
bottom for zip.back:


  https://issues.dlang.org/show_bug.cgi?id=16588

Ali



Re: isCallable fails

2021-01-21 Thread tsbockman via Digitalmars-d-learn

On Friday, 22 January 2021 at 03:08:23 UTC, frame wrote:
It's like asking your mechanican if he can guess what's causing 
the weird sound in the car and he replies with: why didn't you 
disassemble your car already?


Cars are mass-produced copies of a relatively small number of 
rather similar designs, and mechanics' customers *pay them* to 
understand and fix their cars so that the customers don't have 
to. By contrast, computer programs are tremendously more diverse 
than car designs, you are not paying anyone here, and we 
participate here to pass our skills and knowledge on to others, 
not just to do their work for them.


Nevertheless, I will use your analogy:

You: My car shakes when I turn left. What do you think is 
wrong with it?


Mechanic: Hard to say. Bring it in to the shop and I'll take 
a look.


You: It's a simple question! I shouldn't have to bring it in 
to the shop.


Mechanic: Fine. If it was my car, here's how I would go about 
finding the problem... (Detailed explanation follows.) Do that, 
and if you still can't tell what's wrong, come back and talk to 
me again.


You: That's too much work. This is ridiculous. It's a simple 
question: just tell me what's wrong with my car!


Mechanic: Why do you think I can diagnose the problem with 
*even less information than you have*? If it's so simple, why do 
you need help?


You: Rude! I'm outa here...


Re: isCallable fails

2021-01-21 Thread frame via Digitalmars-d-learn

On Friday, 22 January 2021 at 02:43:44 UTC, tsbockman wrote:

No, we're just used to helping each other get to the bottom of 
things like this. No one asked you for anything different from 
what we generally expect of each other in this context. This 
specific expectation mostly exists because, often, without a 
self-contained example we *truly don't know how to help you*.


Please stop. I am very thankful for every hint, links to docs, 
tools etc. But if somebody writes "wasting his time" than it's 
personally (at least for me). I know it wasn't intend, somebody 
can have a bad day too but thats not helpful.


It's like asking your mechanican if he can guess what's causing 
the weird sound in the car and he replies with: why didn't you 
disassemble your car already?


But discusing about such missteps isn't helpful either and I hate 
it to discover such a post while searching in the web for a 
simple hint myself, so I will close this mentally. May someone 
filter out the necessary information about without wasting time.







Re: isCallable fails

2021-01-21 Thread tsbockman via Digitalmars-d-learn

On Friday, 22 January 2021 at 02:18:11 UTC, frame wrote:
Anyway. It was a simple question not a prove that there is a 
bug in the compiler.


isCallable is intended to either evaluate to a boolean, or give a 
clear compile-time error message. Since it did neither of those 
things for you, I suspect that something is wrong in the D 
project's code in addition to, or instead of, your code.


You guys confuse a forum post question with a public 
examination.


No, we're just used to helping each other get to the bottom of 
things like this. No one asked you for anything different from 
what we generally expect of each other in this context. This 
specific expectation mostly exists because, often, without a 
self-contained example we *truly don't know how to help you*.


You are of course free to decide that our methods aren't worth 
your time, but please don't take it personally.


Re: isCallable fails

2021-01-21 Thread frame via Digitalmars-d-learn

On Friday, 22 January 2021 at 00:59:32 UTC, tsbockman wrote:

Generally, I don't need to know what causes an error in order 
to produce an MCVE. I have successfully done so on many 
occasions. It's annoying and slow, but usually very possible.


I know that I have to debug it myself, but if somebody already 
know this kind of error I would still ask about first since the 
first message makes no sense. The second error indeed explains 
whats going on.


Anyway. It was a simple question not a prove that there is a bug 
in the compiler. You guys confuse a forum post question with a 
public examination.


The simple answer if any for somebody can just be: "void" can 
also be the data type if the compiler has problems resolving a 
symbol by running into a recursion while parsing.


Re: isCallable fails

2021-01-21 Thread tsbockman via Digitalmars-d-learn

On Friday, 22 January 2021 at 00:59:32 UTC, tsbockman wrote:
2) Remove, simplify, or mock up/stub out (like for unit tests) 
some large chunk of the remaining code in the program, from a 
part of the program that I *think* is unrelated to the error.

3) Re-test the program.
a) If the failure goes away, goto (2) and try again by 
removing a different part of the program.


I should clarify here that when I say "try again" I mean from a 
backup of the last version of the reduction-in-progress that 
*did* demonstrate the failure.


Re: isCallable fails

2021-01-21 Thread tsbockman via Digitalmars-d-learn

On Thursday, 21 January 2021 at 05:20:27 UTC, frame wrote:
I was not asking here to re-produce my code or debug since it 
cannot provide a snippet if I do not know what could cause the 
error.


Generally, I don't need to know what causes an error in order to 
produce an MCVE. I have successfully done so on many occasions. 
It's annoying and slow, but usually very possible.


If it seems like it's going to be really difficult for a 
particular bug, it's fine to try asking others without an MCVE 
first. But, you should think of MCVE discovery as a valuable 
skill, not an impossibility.


My technique works like this:

0) Make note of the symptoms/message for the specific failure 
that I am trying to isolate.
1) Make a separate copy of the program's source code which I can 
freely destroy.
2) Remove, simplify, or mock up/stub out (like for unit tests) 
some large chunk of the remaining code in the program, from a 
part of the program that I *think* is unrelated to the error.

3) Re-test the program.
a) If the failure goes away, goto (2) and try again by 
removing a different part of the program.
b) If the failure is still present and I think there is more 
that could be removed or simplified, goto (2).
c) If the failure is still present, and I don't see anything 
else to remove or simplify, then I'm done. Whatever is left of 
the source code (hopefully something short and non-proprietary) 
is my MCVE.


It's sort of a guess-and-check binary search for the minimum code 
that triggers the error. This process can be quite tedious, but 
it often does not require already knowing the cause of the error. 
(dustmite is a tool that partially automates this.)


Sometimes it's worth going through, because having an MCVE is 
*really* useful, especially for other people who don't know the 
rest of your project's mostly-unrelated code base and 
dependencies well.


Re: std.algorithm.splitter on a string not always bidirectional

2021-01-21 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 21, 2021 at 05:43:37PM -0500, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> auto sp1 = "a|b|c".splitter('|');
> 
> writeln(sp1.back); // ok
> 
> auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v));
> 
> writeln(sp2.back); // error, not bidirectional
> 
> Why? is it an oversight, or is there a good reason for it?
[...]

Likely an oversight.  But I wouldn't be surprised if there was some
surprising corner case for which this doesn't work / would have onerous
characteristics.


T

-- 
MSDOS = MicroSoft's Denial Of Service


Re: opIndex negative index?

2021-01-21 Thread tsbockman via Digitalmars-d-learn

On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:

I'm a bit unsure if this is reasonable or not.

Thoughts?


Signed indexes are fine, if there is a principled reason to use 
them. Just make sure that you are consistent by making `length`, 
`opDollar`, etc. use signed types, as well.


Otherwise, you're laying a trap for users of the API who may 
accidentally write code with mixed signed-unsigned integer 
operations. That's a big problem, because mixed signed-unsigned 
integer operations are done incorrectly by default, often with no 
warnings, in D and some other C-like languages.


Consistently using signed types for lengths and indexes will make 
the API incompatible with some Phobos (D's `std`) range code, but 
you should get a compile-time error message. Mixing signed and 
unsigned, on the other hand, is likely to result in subtly wrong 
code that compiles without error, but sometimes does the wrong 
thing.


std.algorithm.splitter on a string not always bidirectional

2021-01-21 Thread Steven Schveighoffer via Digitalmars-d-learn

auto sp1 = "a|b|c".splitter('|');

writeln(sp1.back); // ok

auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v));

writeln(sp2.back); // error, not bidirectional

Why? is it an oversight, or is there a good reason for it?

-Steve


Re: opIndex negative index?

2021-01-21 Thread cerjones via Digitalmars-d-learn

On Thursday, 21 January 2021 at 15:55:02 UTC, IGotD- wrote:

On Thursday, 21 January 2021 at 15:49:02 UTC, IGotD- wrote:

On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:


ohreally?


I thought you were talking about the built in arrays.


Since you create your own implementation just as you showed you 
are basically free to do anything. That also includes that you 
are free to create your own iterator as well.


Tbh I was just a bit uneasy about negative indexes from a design 
point of view, you know when something just doesnt feel right. So 
anyway I coded it up and decided I didnt like it anyway, just 
looks weird having


doSomthing(path[-1].x, path[-1].y);

so im going to stick with it as it is.



Re: A variation of issue 11977?

2021-01-21 Thread z via Digitalmars-d-learn

On Thursday, 21 January 2021 at 14:11:15 UTC, kdevel wrote:

Creating a scope
works around the issue.


Another way to work around the issue is to use «asm {jmp label;}» 
(replace jmp by whatever equivalent is there on the target 
architecture.)

Yes it's ugly, but it bypasses the arbitrary limitation perfectly.


Re: opIndex negative index?

2021-01-21 Thread IGotD- via Digitalmars-d-learn

On Thursday, 21 January 2021 at 15:49:02 UTC, IGotD- wrote:

On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:


ohreally?


I thought you were talking about the built in arrays.


Since you create your own implementation just as you showed you 
are basically free to do anything. That also includes that you 
are free to create your own iterator as well.


Re: opIndex negative index?

2021-01-21 Thread IGotD- via Digitalmars-d-learn

On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:


ohreally?


I thought you were talking about the built in arrays.


Re: A variation of issue 11977?

2021-01-21 Thread kdevel via Digitalmars-d-learn

On Thursday, 21 January 2021 at 13:55:48 UTC, kdevel wrote:

[...]

created https://issues.dlang.org/show_bug.cgi?id=21571


Re: opIndex negative index?

2021-01-21 Thread cerjones via Digitalmars-d-learn

On Thursday, 21 January 2021 at 14:25:41 UTC, IGotD- wrote:

On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:

Not possible, indexes are of type size_t which is unsigned. If 
you want negative indexes you need to wrap arrays in your own 
implementation and offset 0 so that negative indexes can be 
used.


import std;

struct Foo
{
int opIndex(int idx)
{
return idx;
}
}

void main()
{
Foo foo;
writeln(foo[-1]);
}

prints:

-1

And just for weirdness...

import std;

struct Foo
{
string opIndex(string s)
{
return s;
}
}

void main()
{
Foo foo;
writeln(foo["ohrealy?"]);
}

prints:

ohreally?


Re: opIndex negative index?

2021-01-21 Thread IGotD- via Digitalmars-d-learn

On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:
I have an iterator that steps along a 2D vector path command by 
command and uses opIndex to give access to the points for the 
current command. The issue is that there's a shared point 
between commands, so when the iterator is on a given command, 
it also needs to also allow access to the end point of the 
previous command. Currently the iterator juggles the indexes so 
that for a cubic you use 0,1,2,3, and 0 gives the previous end 
point. But it would simplify a few things if [-1] was for 
accessing the previous end point, so a cubic would allow 
indexes -1,0,1,2.


I'm a bit unsure if this is reasonable or not.

Thoughts?


Not possible, indexes are of type size_t which is unsigned. If 
you want negative indexes you need to wrap arrays in your own 
implementation and offset 0 so that negative indexes can be used.


Re: A variation of issue 11977?

2021-01-21 Thread kdevel via Digitalmars-d-learn

On Thursday, 21 January 2021 at 13:55:48 UTC, kdevel wrote:

   goto A;   // line 4
   aa["X"] = "Y";// line 5
A:


Creating a scope

   { aa["X"] = "Y"; }  // line 5

works around the issue.


Re: A variation of issue 11977?

2021-01-21 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 21 January 2021 at 13:55:48 UTC, kdevel wrote:

~~~gotoskip.d
int main ()
{
   string[string] aa;
   goto A;   // line 4
   aa["X"] = "Y";// line 5
A:
   return 0;
}
~~~

$ dmd gotoskip.d
gotoskip.d(4): Error: goto skips declaration of variable 
gotoskip.main.__aaval2 at gotoskip.d(5)


What's wrong here? Only found Issue 11977 [1] in which a 
declaration and
initialization is jumped over. However, the statement in line 5 
is neither

a declaration nor an initialization.

[1] https://issues.dlang.org/show_bug.cgi?id=11977


__aaval2 is a compiler-generated temporary variable. If you 
comment out the `goto A;` (so that the code compiles) and use the 
compiler flag -vcg-ast, you can see its declaration:


int main()
{
string[string] aa = null;
// goto A;
(string __aaval2 = "Y";) , aa["X"] = __aaval2;
A:
return 0;
}


opIndex negative index?

2021-01-21 Thread cerjones via Digitalmars-d-learn
I have an iterator that steps along a 2D vector path command by 
command and uses opIndex to give access to the points for the 
current command. The issue is that there's a shared point between 
commands, so when the iterator is on a given command, it also 
needs to also allow access to the end point of the previous 
command. Currently the iterator juggles the indexes so that for a 
cubic you use 0,1,2,3, and 0 gives the previous end point. But it 
would simplify a few things if [-1] was for accessing the 
previous end point, so a cubic would allow indexes -1,0,1,2.


I'm a bit unsure if this is reasonable or not.

Thoughts?


A variation of issue 11977?

2021-01-21 Thread kdevel via Digitalmars-d-learn

~~~gotoskip.d
int main ()
{
   string[string] aa;
   goto A;   // line 4
   aa["X"] = "Y";// line 5
A:
   return 0;
}
~~~

$ dmd gotoskip.d
gotoskip.d(4): Error: goto skips declaration of variable 
gotoskip.main.__aaval2 at gotoskip.d(5)


What's wrong here? Only found Issue 11977 [1] in which a 
declaration and
initialization is jumped over. However, the statement in line 5 
is neither

a declaration nor an initialization.

[1] https://issues.dlang.org/show_bug.cgi?id=11977