Re: looking for hint to debug a strange multi-thread bug (grpc-d-core)

2023-06-13 Thread mw via Digitalmars-d-learn
UPDATE: life is too short to debug dlang built-in AA to right, 
let's just use HashMap from emsi_containers


https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L25
```
HashMap!(string, ServiceHandlerInterface) services;
```

After this change, the problem goes away.

I think there are some bugs in the builtin AA implementation, as 
demo-ed in this multi-threaded program (maybe also related to 
GC?).




looking for hint to debug a strange multi-thread bug (grpc-d-core)

2023-06-13 Thread mw via Digitalmars-d-learn

Hi,

I recently found and started playing with the grpc-d-core[1] 
package, and my program structure looks like this:


https://github.com/mw66/grpc-demo/blob/master/source/main.d

If I run L64 alone (without L66 ~ 79 grpc-d part):
```
64: auto t = new Thread({fun();}).start();
```
it works fine.

If I run L66 ~ 79 grpc-d part alone (without L64), it also works 
fine.


But if I run both, the program received signal SIGSEGV, 
Segmentation fault at here:


https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L94

with LDC, the print out of `services.keys` shows its corrupted 
with some strange values.


under DMD, it fails at:

https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L99

while the `services.keys` seems fine.

What puzzles me is that: these two parts of the code are actually 
independent, does not know each other at all (as I just started 
to add the grpc-d skeleton code with dummy returns, and no client 
connected or made any rpc calls).


And the `services` defined here is a private class field:

https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L21

So how can it be corrupted by `fun()`?


Any suggestions where should I look into?

Thanks.


[1] https://code.dlang.org/packages/grpc-d-core




Re: Bug in D!!!

2017-09-04 Thread crimaniak via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 20:47:12 UTC, EntangledQuanta 
wrote:



interface I
{   
void Go(T)(S!T s);

static final I New()
{
return new C();
}
}

abstract class A : I
{

}


class C : A
{
void Go(T)(S!T s)
{

}
}



This is a blocker for me! Can someone open a ticket?
  Judging by the length of the thread that I did not read, the 
real problem was not spotted, otherwise, it would be shorter. The 
problem is called "virtual method in the interface" anti-pattern. 
Just never do that, and life will be easier. In this case, I 
recommend to move Go to A and make it just dispatcher for 
specialized private non-templated virtual functions. You don't 
need all this mess with string templates for it.




Re: Bug in D!!!

2017-09-03 Thread Moritz Maxeiner via Digitalmars-d-learn
On Monday, 4 September 2017 at 03:08:50 UTC, EntangledQuanta 
wrote:
On Monday, 4 September 2017 at 01:50:48 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 23:25:47 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 11:48:38 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 04:18:03 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz 
Maxeiner wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, 
EntangledQuanta wrote:

[...]


The contexts being independent of each other doesn't 
change that we would still be overloading the same keyword 
with three vastly different meanings. Two is already bad 
enough imho (and if I had a good idea with what to replace 
the "in" for AA's I'd propose removing that meaning).


Why? Don't you realize that the contexts matters and [...]


Because instead of seeing the keyword and knowing its one 
meaning you also have to consider the context it appears in. 
That is intrinsically more work (though the difference may 
be very small) and thus harder.


...


Yes, In an absolute sense, it will take more time to have to 
parse the context. But that sounds like a case of 
"pre-optimization".


I don't agree, because once something is in the language 
syntax, removing it is a long deprecation process (years), so 
these things have to be considered well beforehand.


That's true. But I don't see how it matters to much in the 
current argument. Remember, I'm not advocating using 'in' ;) 
[...]


It matters, because that makes it not be _early_ optimization.






If we are worried about saving time then what about the 
tooling? compiler speed? IDE startup time? etc?
All these take time too and optimizing one single aspect, as 
you know, won't necessarily save much time.


Their speed generally does not affect the time one has to 
spend to understand a piece of code.


Yes, but you are picking and choosing. [...]


I'm not (in this case), as the picking is implied by discussing 
PL syntax.


So, in this case I have to go with the practical of saying 
that it may be theoretically slower, but it is such an 
insignificant cost that it is an over optimization. I think 
you would agree, at least in this case.


Which is why I stated I'm opposing overloading `in` here as a 
matter of principle, because even small costs sum up in the 
long run if we get into the habit of just overloading.




I know, You just haven't convinced me enough to change my 
opinion that it really matters at the end of the day. It's 
going to be hard to convince me since I really don't feel as 
strongly as you do about it. That might seem like a 
contradiction, but


I'm not trying to convince you of anything.



Again, the exact syntax is not import to me. If you really 
think it matters that much to you and it does(you are not 
tricking yourself), then use a different keyword.


My proposal remains to not use a keyword and just upgrade 
existing template specialization.


[...]

You just really haven't stated that principle in any clear way 
for me to understand what you mean until now. i.e., Stating 
something like "... of a matter of principle" without stating 
which principle is ambiguous. Because some principles are not 
real. Some base their principles on fictitious things, some on 
abstract ideals, etc. Basing something on a principle that is 
firmly established is meaningful.


I've stated the principle several times in varied forms of 
"syntax changes need to be worth the cost".


I have a logical argument against your absolute restriction 
though... in that it causes one to have to use more 
symbols. I would imagine you are against stuff like using 
"in1", "in2", etc because they visibly are to close to each 
other.


It's not an absolute restriction, it's an absolute position 
from which I argue against including such overloading on 
principle.
If it can be overcome by demonstrating that it can't 
sensibly be done without more overloading and that it adds 
enough value to be worth the increases overloading, I'd be 
fine with inclusion.


[...]

To simplify it down: Do you have the sample problems with all 
the ambiguities that already exist in almost all programming 
languages that everyone is ok with on a practical level on a 
daily basis?


Again, you seem to mix ambiguity and context sensitivity.
W.r.t. the latter: I have a problem with  those occurences 
where I don't think the costs I associate with it are 
outweighed by its benefits (e.g. with the `in` keyword 
overloaded meaning for AA's).


Not mixing, I exclude real ambiguities because have no real 
meaning. I thought I mentioned something about that way back 
when, but who knows... Although, I'd be curious if any 
programming languages existed who's grammar was ambiguous and 
actually could be realized?


Sure, see the dangling else problem I mentioned. It's just that 
people basically all agree on one of the choices and all stick 
with it (despite the grammar being formally 

Re: Bug in D!!!

2017-09-03 Thread EntangledQuanta via Digitalmars-d-learn
On Monday, 4 September 2017 at 01:50:48 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 23:25:47 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 11:48:38 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 04:18:03 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, 
EntangledQuanta wrote:

[...]


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with 
three vastly different meanings. Two is already bad enough 
imho (and if I had a good idea with what to replace the 
"in" for AA's I'd propose removing that meaning).


Why? Don't you realize that the contexts matters and [...]


Because instead of seeing the keyword and knowing its one 
meaning you also have to consider the context it appears in. 
That is intrinsically more work (though the difference may be 
very small) and thus harder.


...


Yes, In an absolute sense, it will take more time to have to 
parse the context. But that sounds like a case of 
"pre-optimization".


I don't agree, because once something is in the language 
syntax, removing it is a long deprecation process (years), so 
these things have to be considered well beforehand.


That's true. But I don't see how it matters to much in the 
current argument. Remember, I'm not advocating using 'in' ;) I'm 
only saying it doesn't matter in a theoretical sense. If humans 
were as logical as they should be, it would matter less. For 
example, a computer has no issue with using `in`, and it doesn't 
really take any more processing(maybe a cycle, but the context 
makes it clear). But, of course, we are not computers. So, in a 
practical sense, yes, the line has to be draw somewhere, even if, 
IMO, it is not the best place. You agree with this because you 
say it's ok for parenthesis but not in. You didn't seem to answer 
anything about my statements and question about images though. 
But, I'm ok with people drawing lines in the sand, that really 
isn't what I'm arguing. We have to draw lines. My point is, we 
should know we are drawing lines. You seem to know this on some 
significant level, but I don't think most people do. So, what 
would happen, if we argued for the next 10 years, we would just 
come to some refinement of our current opinions and experiences 
about the idea. That's a good thing in a sense, but I don't have 
10 years to waste on such a trivial concept that really doesn't 
matter much ;) (again, remember, I'm not advocating in, I'm 
advocating anything, but against doing nothing.)





If we are worried about saving time then what about the 
tooling? compiler speed? IDE startup time? etc?
All these take time too and optimizing one single aspect, as 
you know, won't necessarily save much time.


Their speed generally does not affect the time one has to spend 
to understand a piece of code.


Yes, but you are picking and choosing. To understand code, you 
have to write code, to write code you need a compiler, ide, etc. 
You need a book, the internet, or other resources to learn things 
too. It's a much much bigger can of worms than you realize or 
want to get in to. Everything is interdependent. It's nice to 
make believe that we can separate everything in to nice little 
quanta, but we can't, and when we ultimately try we get results 
that make no sense.  But, of course, it's about the best we can 
do with where humans are at in their evolution currently. The 
ramifications of one minor change can change everything... See 
the butterfly effect. Life is fractal-life, IMO(I can't prove it 
but the evidence is staggering).


I mean, when you say "read code faster" I assume you mean the 
moment you start to read a piece of code with your eyes to the 
end of the code... But do you realize that, in some sense, that 
is meaningless? What about the time it takes to turn on your 
computer? Why are you not including that? Or the time to scroll 
your mouse? These things matter because surely you are trying to 
save time in the "absolute" sense?


e.g., so you have more time to spend with your family at the end 
of the day? Or spend more time hitting a little white ball in a 
hole? or whatever? If all you did was read code and had no other 
factors involved in the absolute time, then you would be 100% 
correct. But all those other factors do add up too.


Of course, the more code you read the more important it becomes 
and the less the other factors become, but then why are you 
reading so much code if you think it's a waste of time? So you 
can save some more time to read more code? If your goal is to 
truly read as much code as you can in your life span, then I 
think your analysis is 99.999...% correct.  If you only code as a 
means to an end for other things, then I think your answer is 
about 10-40% correct(with a high degree of error and dependent on 
context).


For me, and the way I 

Re: Bug in D!!!

2017-09-03 Thread Moritz Maxeiner via Digitalmars-d-learn
On Sunday, 3 September 2017 at 23:25:47 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 11:48:38 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 04:18:03 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, 
EntangledQuanta wrote:

[...]


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with 
three vastly different meanings. Two is already bad enough 
imho (and if I had a good idea with what to replace the "in" 
for AA's I'd propose removing that meaning).


Why? Don't you realize that the contexts matters and [...]


Because instead of seeing the keyword and knowing its one 
meaning you also have to consider the context it appears in. 
That is intrinsically more work (though the difference may be 
very small) and thus harder.


...


Yes, In an absolute sense, it will take more time to have to 
parse the context. But that sounds like a case of 
"pre-optimization".


I don't agree, because once something is in the language syntax, 
removing it is a long deprecation process (years), so these 
things have to be considered well beforehand.


If we are worried about saving time then what about the 
tooling? compiler speed? IDE startup time? etc?
All these take time too and optimizing one single aspect, as 
you know, won't necessarily save much time.


Their speed generally does not affect the time one has to spend 
to understand a piece of code.




Maybe the language itself should be designed so there are no 
ambiguities at all? A single simple for each function? A new 
keyboard design should be implemented(ultimately a direct brain 
to editor interface for the fastest time, excluding the time 
for development and learning)?


I assume you mean "without context sensitive meanings" instead of 
"no ambiguities", because the latter should be the case as a 
matter of course (and mostly is, with few exceptions such as the 
dangling else ambiguity in C and friends).
Assuming the former: As I stated earlier, it needs to be worth 
the cost.




So, in this case I have to go with the practical of saying that 
it may be theoretically slower, but it is such an insignificant 
cost that it is an over optimization. I think you would agree, 
at least in this case.


Which is why I stated I'm opposing overloading `in` here as a 
matter of principle, because even small costs sum up in the long 
run if we get into the habit of just overloading.


Again, the exact syntax is not import to me. If you really 
think it matters that much to you and it does(you are not 
tricking yourself), then use a different keyword.


My proposal remains to not use a keyword and just upgrade 
existing template specialization.




When I see something I try to see it at once rather [...]




To really counter your argument: What about parenthesis? They 
too have the same problem with in. They have perceived 
ambiguity... but they are not ambiguity. So your argument 
should be said about them too and you should be against them 
also, but are you? [To be clear here: foo()() and (3+4) have 3 
different use cases of ()'s... The first is templated 
arguments, the second is function arguments, and the third is 
expression grouping]


That doesn't counter my argument, it just states that parentheses 
have these costs, as well (which they do). The primary question 
would still be if they're worth that cost, which imho they are. 
Regardless of that, though, since they are already part of the 
language syntax (and are not going to be up for change), this is 
not something we could do something about, even if we agreed they 
weren't worth the cost.
New syntax, however, is up for that kind of discussion, because 
once it's in it's essentially set in stone (not quite, but *very* 
slow to remove/change because of backwards compatibility).



[...]


Well, yes, as I wrote, I think it is unambiguous (and can 
thus be used), I just think it shouldn't be used.


Yes, but you have only given the reason that it shouldn't be 
used because you believe that one shouldn't overload keywords 
because it makes it harder to parse the meaning. My rebuttal, 
as I have said, is that it is not harder, so your argument is 
not valid. All you could do is claim that it is hard and we 
would have to find out who is more right.


As I countered that in the above, I don't think your rebuttal 
is valid.


Well, hopefully I countered that in my rebuttal of your 
rebuttal of my rebuttal ;)


Not as far as I see it, though I'm willing to agree to disagree :)


I have a logical argument against your absolute restriction 
though... in that it causes one to have to use more symbols. 
I would imagine you are against stuff like using "in1", 
"in2", etc because they visibly are to close to each other.


It's not an absolute restriction, it's an absolute position 
from which I argue against including such overloading 

Re: Bug in D!!!

2017-09-03 Thread EntangledQuanta via Digitalmars-d-learn
On Sunday, 3 September 2017 at 11:48:38 UTC, Moritz Maxeiner 
wrote:
On Sunday, 3 September 2017 at 04:18:03 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, 
EntangledQuanta wrote:

[...]


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with 
three vastly different meanings. Two is already bad enough 
imho (and if I had a good idea with what to replace the "in" 
for AA's I'd propose removing that meaning).


Why? Don't you realize that the contexts matters and [...]


Because instead of seeing the keyword and knowing its one 
meaning you also have to consider the context it appears in. 
That is intrinsically more work (though the difference may be 
very small) and thus harder.


...


Yes, In an absolute sense, it will take more time to have to 
parse the context. But that sounds like a case of 
"pre-optimization". If we are worried about saving time then what 
about the tooling? compiler speed? IDE startup time? etc? All 
these take time too and optimizing one single aspect, as you 
know, won't necessarily save much time.


Maybe the language itself should be designed so there are no 
ambiguities at all? A single simple for each function? A new 
keyboard design should be implemented(ultimately a direct brain 
to editor interface for the fastest time, excluding the time for 
development and learning)?


So, in this case I have to go with the practical of saying that 
it may be theoretically slower, but it is such an insignificant 
cost that it is an over optimization. I think you would agree, at 
least in this case. Again, the exact syntax is not import to me. 
If you really think it matters that much to you and it does(you 
are not tricking yourself), then use a different keyword.


When I see something I try to see it at once rather than reading 
it left to right. It is how music is read properly, for example. 
One can't read left to right and process the notes in real time 
fast enough. You must "see at once" a large chunk.


When I see foo(A in B)() I see it at once, not in parts or 
sub-symbols(subconsciously that may be what happens, but it 
either is so quick or my brain has learned to see differently 
that I do not feel it to be any slower).


that is, I do not read it like f, o, o (, A,  , i,...

but just like how one sees an image. Sure, there are clustering 
such as foo and (...), and I do sub-parse those at some point, 
but the context is derived very quickly. Now, of course, I do 
make assumptions to be able to do that. Obviously I have to sorta 
assume I'm reading D code and that the expression is a templated 
function, etc. But that is required regardless.


It's like seeing a picture of an ocean. You can see the global 
characteristics immediately without getting bogged down in the 
details until you need it. You can determine the approximate time 
of day(morning, noon, evening, night) relatively instantaneously 
without even knowing much else.


To really counter your argument: What about parenthesis? They too 
have the same problem with in. They have perceived ambiguity... 
but they are not ambiguity. So your argument should be said about 
them too and you should be against them also, but are you? [To be 
clear here: foo()() and (3+4) have 3 different use cases of 
()'s... The first is templated arguments, the second is function 
arguments, and the third is expression grouping]


If you are, then you are being logical and consistent, If you are 
not, then you are not being logical nor consistent. If you fall 
in the latter case, I suggest you re-evaluate the way you think 
about such things because you are picking and choosing.


Now, if you are just stating a mathematical fast that it takes 
longer, then I can't really deny that, although I can't 
technically prove it either as you can't because we would require 
knowing exactly how the brain processes the information.












[...]


Well, yes, as I wrote, I think it is unambiguous (and can 
thus be used), I just think it shouldn't be used.


Yes, but you have only given the reason that it shouldn't be 
used because you believe that one shouldn't overload keywords 
because it makes it harder to parse the meaning. My rebuttal, 
as I have said, is that it is not harder, so your argument is 
not valid. All you could do is claim that it is hard and we 
would have to find out who is more right.


As I countered that in the above, I don't think your rebuttal 
is valid.


Well, hopefully I countered that in my rebuttal of your rebuttal 
of my rebuttal ;) Again, you don't actually know how the brain 
processes information(no one does, it is all educated guesses). 
You use the concept that the more information one has to process 
the more time it takes... which seems logical, but it is not 
necessarily applicable directly to the interpretation of written 
symbols. Think of an 

Re: Bug in D!!!

2017-09-03 Thread Moritz Maxeiner via Digitalmars-d-learn
On Sunday, 3 September 2017 at 04:18:03 UTC, EntangledQuanta 
wrote:
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
wrote:

[...]


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with three 
vastly different meanings. Two is already bad enough imho (and 
if I had a good idea with what to replace the "in" for AA's 
I'd propose removing that meaning).


Why? Don't you realize that the contexts matters and [...]


Because instead of seeing the keyword and knowing its one meaning 
you also have to consider the context it appears in. That is 
intrinsically more work (though the difference may be very small) 
and thus harder.




Again, I'm not necessarily arguing for them, just saying that 
one shouldn't avoid them just to avoid them.






[...]


It's not about ambiguity for me, it's about readability. The 
more significantly different meanings you overload some 
keyword - or symbol, for that matter - with, the harder it 
becomes to read.


I don't think that is true. Everything is hard to read. It's 
about experience. The more you experience something the more 
clear it becomes. Only with true  ambiguity is something 
impossible. I realize that in one can design a language to be 
hard to parse due to apparent ambiguities, but am I am talking 
about cases where they can be resolved immediately(at most a 
few milliseconds).


Experience helps, of course, but it doesn't change that it's 
still just that little bit slower. And everytime we encourage 
such overloading encourages more, which in the end sums up.




You are making general statements, and it is not that I 
disagree, but it depends on context(everything does). In this 
specific case, I think it is extremely clear what in means, so 
it is effectively like using a different token. Again, everyone 
is different though and have different experiences that help 
them parse things more naturally. I'm sure there are things 
that you might find easy that I would find hard. But that 
shouldn't stop me from learning about them. It makes me 
"smarter", to simplify the discussion.


I am, because I believe it to be generally true for "1 keyword 
|-> 1 meaning" to be easier to read than "1 keyword and 1 context 
|-> 1 meaning" as the former inherently takes less time.






[...]


Well, yes, as I wrote, I think it is unambiguous (and can thus 
be used), I just think it shouldn't be used.


Yes, but you have only given the reason that it shouldn't be 
used because you believe that one shouldn't overload keywords 
because it makes it harder to parse the meaning. My rebuttal, 
as I have said, is that it is not harder, so your argument is 
not valid. All you could do is claim that it is hard and we 
would have to find out who is more right.


As I countered that in the above, I don't think your rebuttal is 
valid.




I have a logical argument against your absolute restriction 
though... in that it causes one to have to use more symbols. I 
would imagine you are against stuff like using "in1", "in2", 
etc because they visibly are to close to each other.


It's not an absolute restriction, it's an absolute position from 
which I argue against including such overloading on principle.
If it can be overcome by demonstrating that it can't sensibly be 
done without more overloading and that it adds enough value to be 
worth the increases overloading, I'd be fine with inclusion.





[...]


I would much rather see it as a generalization of existing 
template specialization syntax [1], which this is t.b.h. just 
a superset of (current syntax allows limiting to exactly one, 
you propose limiting to 'n'):


---
foo(T: char)  // Existing syntax: Limit T to the single 
type `char`
foo(T: (A, B, C)) // New syntax:  Limit T to one of A, B, 
or C

---


Yes, if this worked, I'd be fine with it. Again, I could care 
less. `:` == `in` for me as long as `:` has the correct meaning 
of "can be one of the following" or whatever.


But AFAIK, : is not "can be one of the following"(which is "in" 
or "element of" in the mathematical sense) but can also mean 
"is a derived type of".


Right, ":" is indeed an overloaded symbol in D (and ironically, 
instead of with "in", I think all its meanings are valuable 
enough to be worth the cost). I don't see how that would 
interfere in this context, though, as we don't actually overload 
a new meaning (it's still "restrict this type to the thing to the 
right").








If that is the case then go for it ;) It is not a concern of 
mine. You tell me the syntax and I will use it. (I'd have no 
choice, of course, but if it's short and sweet then I won't 
have any problem).


I'm discussing this as a matter of theory, I don't have a use for 
it.





[...]


Quoting a certain person (you know who you are) from DConf 
2017: "Write a DIP".
I'm quite happy to discuss this idea, but at the end of 

Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
wrote:
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, 
EntangledQuanta wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and 
I hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have 
a finite known set of T unless you tell it.


But lets assume we've told the compiler that it is 
compiling all the source code and it does not need to 
compile for future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of 
each other; so this feature could be specified to work 
within the same module or new semantics can be written up 
of how the compiler modifies already compiled modules and 
those which reference the compiled modules (the object 
sizes would be changing due to the v-table modifications)


With those three simple changes to the language I think 
that this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive 
way, we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with three 
vastly different meanings. Two is already bad enough imho (and 
if I had a good idea with what to replace the "in" for AA's I'd 
propose removing that meaning).


Why? Don't you realize that the contexts matters and it's what 
separates the meaning? In truly unambiguous contexts, it 
shouldn't matter. It may require one to decipher the context, 
which takes time, but there is nothing inherently wrong with it 
and we are limited to how many symbols we use(unfortunately we 
are generally stuck with the querty keyboard design, else we 
could use symbols out the ying yang and make things much clearer, 
but even mathematics, which is a near perfect language, 
"overloads" symbols meanings).


You have to do this sort of thing when you limit the number of 
keywords you use. Again, ultimately it doesn't matter. A symbol 
is just a symbol. For me, as long as the context is clear, I 
don't see what kind of harm it can cause. You say it is bad, but 
you don't give the reasons why it is bad. If you like to think of 
`in` has having only one definition then the question is why? You 
are limiting yourself. The natural languages are abound with such 
multi-definitions. Usually in an ambiguous way and it can cause a 
lot of problems, but for computer languages, it can't(else we 
couldn't actually compile the programs). Context sensitive 
grammars are provably more expressive than context free.


https://en.wikipedia.org/wiki/Context-sensitive_grammar

Again, I'm not necessarily arguing for them, just saying that one 
shouldn't avoid them just to avoid them.







For me, and this is just me, I do not find it ambiguous. I 
don't find different meanings ambiguous unless the context 
overlaps. Perceived ambiguity is not ambiguity, it's just 
ignorance... which can be overcome through learning. Hell, D 
has many cases where there are perceived ambiguities... as do 
most things.


It's not about ambiguity for me, it's about readability. The 
more significantly different meanings you overload some keyword 
- or symbol, for that matter - with, the harder it becomes to 
read.


I don't think that is true. Everything is hard to 

Re: Bug in D!!!

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
wrote:
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and 
I hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have 
a finite known set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for 
future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of 
each other; so this feature could be specified to work 
within the same module or new semantics can be written up of 
how the compiler modifies already compiled modules and those 
which reference the compiled modules (the object sizes would 
be changing due to the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


The contexts being independent of each other doesn't change that 
we would still be overloading the same keyword with three vastly 
different meanings. Two is already bad enough imho (and if I had 
a good idea with what to replace the "in" for AA's I'd propose 
removing that meaning).




For me, and this is just me, I do not find it ambiguous. I 
don't find different meanings ambiguous unless the context 
overlaps. Perceived ambiguity is not ambiguity, it's just 
ignorance... which can be overcome through learning. Hell, D 
has many cases where there are perceived ambiguities... as do 
most things.


It's not about ambiguity for me, it's about readability. The more 
significantly different meanings you overload some keyword - or 
symbol, for that matter - with, the harder it becomes to read.




But in any case, I could care less about the exact syntax. It's 
just a suggestion that makes the most logical sense with regard 
to the standard usage of in. If it is truly unambiguous then it 
can be used.


Well, yes, as I wrote, I think it is unambiguous (and can thus be 
used), I just think it shouldn't be used.




Another alternative is

foo(T of Typelist)

which, AFAIK, of is not used in D and even most programming 
languages. Another could be


foo(T -> Typelist)

or even

foo(T from Typelist)


I would much rather see it as a generalization of existing 
template specialization syntax [1], which this is t.b.h. just a 
superset of (current syntax allows limiting to exactly one, you 
propose limiting to 'n'):


---
foo(T: char)  // Existing syntax: Limit T to the single type 
`char`

foo(T: (A, B, C)) // New syntax:  Limit T to one of A, B, or C
---

Strictly speaking, this is exactly what template specialization 
is for, it's just that the current one only supports a single 
type instead of a set of types.
Looking at the grammar rules, upgrading it like this is a fairly 
small change, so the cost there should be minimal.




or whatever. Doesn't really matter. They all mean the same to 
me once the definition has been written in stone. Could use 
`foo(T eifjasldj Typelist)` for all I care.


That's okay, but it does matter to me.

The import thing for me is that such a simple syntax exists 
rather than the "complex syntax's" that have already been 
given(which are ultimately syntax's as 

Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and I 
hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have a 
finite known set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for 
future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of each 
other; so this feature could be specified to work within the 
same module or new semantics can be written up of how the 
compiler modifies already compiled modules and those which 
reference the compiled modules (the object sizes would be 
changing due to the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


For me, and this is just me, I do not find it ambiguous. I don't 
find different meanings ambiguous unless the context overlaps. 
Perceived ambiguity is not ambiguity, it's just ignorance... 
which can be overcome through learning. Hell, D has many cases 
where there are perceived ambiguities... as do most things.


But in any case, I could care less about the exact syntax. It's 
just a suggestion that makes the most logical sense with regard 
to the standard usage of in. If it is truly unambiguous then it 
can be used.


Another alternative is

foo(T of Typelist)

which, AFAIK, of is not used in D and even most programming 
languages. Another could be


foo(T -> Typelist)

or even

foo(T from Typelist)

or whatever. Doesn't really matter. They all mean the same to me 
once the definition has been written in stone. Could use `foo(T 
eifjasldj Typelist)` for all I care. The import thing for me is 
that such a simple syntax exists rather than the "complex 
syntax's" that have already been given(which are ultimately 
syntax's as everything is at the end of the day).



W.r.t. to the idea in general: I think something like that 
could be valuable to have in the language, but since this 
essentially amounts to syntactic sugar (AFAICT), but I'm not 
(yet) convinced that with `static foreach` being included it's 
worth the cost.




Everything is syntactic sugar. So it isn't about if but how much. 
We are all coding in 0's and 1's whether we realize it or not. 
The point if syntax(or syntactic sugar) is to reduce the amount 
of 0's and 1's that we have to *effectively* code by grouping 
common patterns in to symbolic equivalents(by definition).


This is all programming is. We define certain symbols to mean 
certain bit patterns, or generic bit matters(an if keyword/symbol 
is a generic bit pattern, a set of machine instructions(0's and 
1's) and substitution placeholders that are eventually filled 
with 0's and 1's).


No one can judge the usefulness of syntax until it has been 
created because what determines how useful something is is its 
use. But you can't use something if it doesn't exist. I think 
many fail to get that. The initial questions should be: Is there 
a gap in the language? (Yes in this case). Can the gap be filled? 
(this is a theoretical/mathematical question that has to be 
answered. Most people jump the gun here and make assumptions) 
Does the gap need 

Re: Bug in D!!!

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic functions 
in C#. Unfortunately C# doesn't use templates and I hit so 
many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every instantiated 
T, after all, the compiler can't know you have a finite known 
set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for future 
linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and validate 
all derived classes include it. That was easy.


Next up each instantiation of the function needs a new v-table 
entry in all derived classes. Current compiler implementation 
will compile each module independently of each other; so this 
feature could be specified to work within the same module or 
new semantics can be written up of how the compiler modifies 
already compiled modules and those which reference the 
compiled modules (the object sizes would be changing due to 
the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same as 
making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that is 
effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup (return 
pointer to value or null if not present) into an associative 
array [1] and input contracts. It wouldn't be ambiguous AFAICT, 
but having a keyword mean three different things depending on 
context would make the language even more complex (to read).


W.r.t. to the idea in general: I think something like that could 
be valuable to have in the language, but since this essentially 
amounts to syntactic sugar (AFAICT), but I'm not (yet) convinced 
that with `static foreach` being included it's worth the cost.


[1] https://dlang.org/spec/expression.html#InExpression


Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Saturday, 2 September 2017 at 16:20:10 UTC, Jesse Phillips 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
Regardless of the implementation, the idea that we should 
throw the baby out with the bathwater is simply wrong. At 
least there are a few who get that. By looking in to it in a 
serious manner an event better solution might be found. Not 
looking at all results in no solutions and no progress.


Problem is that you didn't define the problem. You showed some 
code the compiler rejected and expressed that the compiler 
needed to figure it out. You did change it to having the 
compiler instantiate specified types, but that isn't defining 
the problem.


I think the problem is clearly defined, it's not my job to be a D 
compiler researcher and spell everything out for everyone else. 
Do I get paid for solving D's problems?


You didn't like the code needed which would generate the 
functions and you hit a Visual D with the new static foreach.


This sentence makes no sense. "hit a Visual D" what? Do you mean 
bug? If that is the case, how is that my fault? Amd I suppose to 
know off the bat that an access violation is caused by Visual D 
and not dmd when there is no info about the violation? Is it my 
fault that someone didn't code one of those tools good enough to 
express enough information for one to figure it out immediately?


All of these are problems you could define, and you could have 
evaluated static foreach as a solution but instead stopped at 
problems with the tooling.


Huh? I think you fail to understand the real problem. The problem 
has nothing to do with tooling and I never said it did. The 
static foreach "solution" came after the fact when SEVERAL 
people(ok, 2) said it was an impossible task to do. That is where 
all this mess started. I then came up with a solution which 
proved that it is possible to do on some level, that is a 
solution to a problem that was defined, else the solution 
wouldn't exist.



You also don't appear to care about the complexity of the 
language. I expressed three required changes some of which may 
not play nicely with least surprise. You went straight to, we 
just need to define a syntax for that instead of expressing 
concern that the compiler will also need to handle errors to 
the use, such that the user understands that a feature they use 
is limited to very specific situations.


Do you not understand that if a library solution exists then 
there is no real complexity added? It is called "lowering" by 
some. The compiler simply "rewrites" whatever new syntax is added 
in a form that the library solution realized. You are pretended, 
why?, that what I am proposed will somehow potentially affect 
every square micron of the D language and compiler, when it won't.


Not all additions to a compiler are add *real* complexity. That 
is a failing of you and many on the D forums who resist change.


Consider if you have a module defined interface, is that 
interface only available for use in that module? If not, how 
does a different model inherent the interface, does it need a 
different syntax.


What does that have to do with this problem? We are not talking 
about interfaces. We are talking about something inside 
interfaces, so the problem about interfaces is irrelevant to this 
discussion because it applies to interfaces in general... 
interfaces that already exist and the problem exists regardless 
of what I


There is a lot more to a feature then having a way to express 
your desires. If your going to stick to a stance that it must 
exist and aren't going to accept there are problems with the 
request why expect others to work through the request.



No, your problem is your ego and your inability to interpret 
things outside of your own mental box. You should always keep in 
mind that you are interpreting someone elses mental wordage in 
your own way and it is not a perfect translation, in fact, we are 
lucky if 50% is interpreted properly. Now, if I do not have a 
right to express my desires, then at least state that, but I do 
have a right not to express any more than that. As far as 
motivating other people, that is isn't my job. I could care less 
actually. D is a hobby for me and I do it because I like the 
power D has, but D is the most frustrating language I have ever 
used. It's the most(hyperbole) buggy, most incomplete(good docs 
system: regardless of what the biased want to claim, tool, etc), 
most uninformative(errors that just toss the whole kitchen sink 
at you), etc.  But I do have hope... which is the only reason I 
use it. Maybe I'm just an idiot and should go with the crowed, it 
would at least save me some frustration. C#, since you are 
familiar with it, you should know there is a huge difference. If 
D was like C# as far as the organizational structure(I do not 
mean MS, I mean the docs, library, etc) you would surely agree 
that D would most likely be the #1 language on this planet? C# 
has 

Re: Bug in D!!!

2017-09-02 Thread Jesse Phillips via Digitalmars-d-learn
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
Regardless of the implementation, the idea that we should throw 
the baby out with the bathwater is simply wrong. At least there 
are a few who get that. By looking in to it in a serious manner 
an event better solution might be found. Not looking at all 
results in no solutions and no progress.


Problem is that you didn't define the problem. You showed some 
code the compiler rejected and expressed that the compiler needed 
to figure it out. You did change it to having the compiler 
instantiate specified types, but that isn't defining the problem.


You didn't like the code needed which would generate the 
functions and you hit a Visual D with the new static foreach.


All of these are problems you could define, and you could have 
evaluated static foreach as a solution but instead stopped at 
problems with the tooling.


You also don't appear to care about the complexity of the 
language. I expressed three required changes some of which may 
not play nicely with least surprise. You went straight to, we 
just need to define a syntax for that instead of expressing 
concern that the compiler will also need to handle errors to the 
use, such that the user understands that a feature they use is 
limited to very specific situations.


Consider if you have a module defined interface, is that 
interface only available for use in that module? If not, how does 
a different model inherent the interface, does it need a 
different syntax.


There is a lot more to a feature then having a way to express 
your desires. If your going to stick to a stance that it must 
exist and aren't going to accept there are problems with the 
request why expect others to work through the request.


Re: Bug in D!!!

2017-09-01 Thread EntangledQuanta via Digitalmars-d-learn

On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips wrote:
I've love being able to inherit and override generic functions 
in C#. Unfortunately C# doesn't use templates and I hit so many 
other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every instantiated 
T, after all, the compiler can't know you have a finite known 
set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for future 
linking.


First the compiler will need to make sure all virtual functions 
can be generated for the derived classes. In this case the 
compiler must note the template function and validate all 
derived classes include it. That was easy.


Next up each instantiation of the function needs a new v-table 
entry in all derived classes. Current compiler implementation 
will compile each module independently of each other; so this 
feature could be specified to work within the same module or 
new semantics can be written up of how the compiler modifies 
already compiled modules and those which reference the compiled 
modules (the object sizes would be changing due to the v-table 
modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same as 
making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that is 
effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, we 
can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor ambiguous, 
I believe.


Regardless of the implementation, the idea that we should throw 
the baby out with the bathwater is simply wrong. At least there 
are a few who get that. By looking in to it in a serious manner 
an event better solution might be found. Not looking at all 
results in no solutions and no progress.





Re: Bug in D!!!

2017-09-01 Thread Jesse Phillips via Digitalmars-d-learn
I've love being able to inherit and override generic functions in 
C#. Unfortunately C# doesn't use templates and I hit so many 
other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every instantiated T, 
after all, the compiler can't know you have a finite known set of 
T unless you tell it.


But lets assume we've told the compiler that it is compiling all 
the source code and it does not need to compile for future 
linking.


First the compiler will need to make sure all virtual functions 
can be generated for the derived classes. In this case the 
compiler must note the template function and validate all derived 
classes include it. That was easy.


Next up each instantiation of the function needs a new v-table 
entry in all derived classes. Current compiler implementation 
will compile each module independently of each other; so this 
feature could be specified to work within the same module or new 
semantics can be written up of how the compiler modifies already 
compiled modules and those which reference the compiled modules 
(the object sizes would be changing due to the v-table 
modifications)


With those three simple changes to the language I think that this 
feature will work for every T.


Re: Bug in D!!!

2017-09-01 Thread EntangledQuanta via Digitalmars-d-learn
This happens when building, not running. This might be a Visual D 
issue as when I use dmd from the command line, it works fine ;/





Re: Bug in D!!!

2017-09-01 Thread EntangledQuanta via Digitalmars-d-learn

On Friday, 1 September 2017 at 19:25:53 UTC, Adam D Ruppe wrote:
On Friday, 1 September 2017 at 18:17:22 UTC, EntangledQuanta 
wrote:

I get an access violation, changed the code to


What is the rest of your code? access violation usually means 
you didn't new the class...


No, that is the code! I added nothing. Try it out and you'll see. 
I just upgraded to released dmd too.



alias I(A...) = A;

interface Foo {
static foreach(T; I!(int, float))
void set(T t); // define virt funcs for a list of 
types

}

class Ass : Foo {
static foreach(T; I!(int, float))
void set(T t) {
// simplement
}
}

void main()
{

}

try it.




Re: Bug in D!!!

2017-09-01 Thread Adam D Ruppe via Digitalmars-d-learn
On Friday, 1 September 2017 at 18:17:22 UTC, EntangledQuanta 
wrote:

I get an access violation, changed the code to


What is the rest of your code? access violation usually means you 
didn't new the class...


Re: Bug in D!!!

2017-09-01 Thread EntangledQuanta via Digitalmars-d-learn

On Friday, 1 September 2017 at 15:24:39 UTC, Adam D. Ruppe wrote:
static foreach is now in the new release! You can now do stuff 
like:


---
alias I(A...) = A;

interface Foo {
static foreach(T; I!(int, float))
void set(T t); // define virt funcs for a list 
of types

}

class Ass : Foo {
static foreach(T; I!(int, float))
void set(T t) {
// simplement
}
}
---


really easily.


I get an access violation, changed the code to

import std.meta;
static foreach(T; AliasSeq!("int", "float"))
mixin("void set("~T~" t);");


and also get an access violation ;/



Re: Bug in D!!!

2017-09-01 Thread Adam D. Ruppe via Digitalmars-d-learn
static foreach is now in the new release! You can now do stuff 
like:


---
alias I(A...) = A;

interface Foo {
static foreach(T; I!(int, float))
void set(T t); // define virt funcs for a list of 
types

}

class Ass : Foo {
static foreach(T; I!(int, float))
void set(T t) {
// simplement
}
}
---


really easily.


Re: Bug in D!!!

2017-09-01 Thread Biotronic via Digitalmars-d-learn
On Thursday, 31 August 2017 at 15:48:12 UTC, EntangledQuanta 
wrote:

On Thursday, 31 August 2017 at 10:34:14 UTC, Kagamin wrote:
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta 
wrote:

I've already implemented a half ass library solution.


It can be improved alot.


Then, by all means, genius!


Enjoy!

mixin template virtualTemplates(alias parent, alias fn, T...) {
import std.meta;
alias name = Alias!(__traits(identifier, fn)[1..$]);
mixin virtualTemplates!(parent, name, fn, T);
}

mixin template virtualTemplates(alias parent, string name, alias 
fn, T...) {

import std.traits;
static if (is(parent == interface)) {
template templateOverloads(string name : name) {
alias templateOverloads = T;
}
alias Types = T;
} else {
alias Types = templateOverloads!name;
}

mixin(virtualTemplatesImpl(name, Types.length, is(parent == 
class)));

}

string virtualTemplatesImpl(string name, int n, bool implement) {
import std.format;
string result;
foreach (i; 0..n) {
auto body = implement ? format(" { return 
fn!(Types[%s])(args); }", i) : ";";
result ~= format("ReturnType!(fn!(Types[%s])) 
%s(Parameters!(fn!(Types[%s])) args)%s\n", i, name, i, body);

}
return result;
}

interface I {
void _Go(T)(T s);
void _Leave(T)(T s);
mixin virtualTemplates!(I, _Go, int, short, float, double);
mixin virtualTemplates!(I, "Abscond", _Leave, int, short, 
float, double);

}

class C : I {
void _Go(T)(T s) { }
void _Leave(T)(T s) { }
mixin virtualTemplates!(C, _Go);
mixin virtualTemplates!(C, "Abscond", _Leave);
}

unittest {
I c = new C();

c.Go(3.2);
c.Abscond(3.4f);
}

Does not support multiple template parameters, or template value 
parameters. Use at own risk for any and all purposes.


Re: Bug in D!!!

2017-08-31 Thread EntangledQuanta via Digitalmars-d-learn

On Thursday, 31 August 2017 at 10:34:14 UTC, Kagamin wrote:
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta 
wrote:

I've already implemented a half ass library solution.


It can be improved alot.


Then, by all means, genius!


Re: Bug in D!!!

2017-08-31 Thread Kagamin via Digitalmars-d-learn
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta 
wrote:

I've already implemented a half ass library solution.


It can be improved alot.


Re: Bug in D!!!

2017-08-30 Thread Ali Çehreli via Digitalmars-d-learn

On 08/30/2017 05:49 PM, EntangledQuanta wrote:

> The compiler can and should do this!

Yes, the compiler can do it for each compilation but there is also the 
feature called /separate compilation/ that D supports. With separate 
compilation, there would potentially be multiple different and 
incompatible definitions of the same interface because compilations 
cannot know the whole set of instantiations of templates.


This relatively popular request is impossible in D as well as other 
languages like C++ that practically settled on vtbl-based polymorphism.


Ali



Re: Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 22:52:41 UTC, Adam D. Ruppe wrote:
On Wednesday, 30 August 2017 at 20:47:12 UTC, EntangledQuanta 
wrote:

This is quite surprising!


In the new version pending release (scheduled for later this 
week), we get a new feature `static foreach` that will let you 
loop through the types you want and declare all the functions 
that way.


When it is released, we'll have to take a second look at this 
problem.


I've already implemented a half ass library solution. It works, 
but is not robust. The compiler can and should do this!





string OverLoadTemplateDefinition(string name, alias func, T...)()
{
import std.string;
string str;
	foreach(t; T) str ~= ((func!t).stringof).replace("function(", 
name~"(")~";\n";

return str;
}

string OverLoadTemplateMethod(string name, alias func, T...)()
{
import std.traits, std.algorithm, std.meta, std.string;

alias RT(S) = ReturnType!(func!S);
alias PN(S) = ParameterIdentifierTuple!(func!S);
alias P(S) = Parameters!(func!S);
alias PD(S) = ParameterDefaults!(func!S);

string str;
foreach(t; T)
{
str ~= (RT!t).stringof~" "~name~"(";
foreach(k,p; P!t)
{
auto d = "";
static if (PD!t[k].stringof != "void")
d = " = "~(PD!t)[k].stringof;
str ~= p.stringof~" "~(PN!t)[k]~d;
if (k < (P!t).length - 1)
str ~= ", ";
}

str ~= ") { _"~name~"(";
foreach(k, n; PN!t)
{
str ~= n;
if (k < (P!t).length - 1)
str ~= ", ";
}
str ~= "); }\n";
}
return str;
}


They are basically the generic version of what Jonathan 
implemented by hand.


In the interface:

private alias _Go(T) = void function();

mixin(OverLoadTemplateDefinition!("Go", _Go, int, short, float, 
double)());


In class:

mixin(OverLoadTemplateMethod!("Go", _Go, int, short, float, 
double)());


protected final void _Go(T)()
{

}


The alias simply defines the function that we are creating. The 
mixin OverLoadTemplateDefinition creates the N templates.


in the class, we have to do something similar but dispatch them 
to the protected _Go... very similar to what Jonathan did by 
hand. But the code to do so is not robust and will break in many 
cases because I left a lot of details out(linkage, attributes, 
etc).


It is a proof of concept, and as you can see, it is not 
difficult. The compiler, and anyone that has a decent 
understanding of the internals of it, should be able to implement 
something quite easily.


Maybe it is also possible to use OpCall to do something similar?

I'd like to reiterate that this is not an insolvable problem or 
an NP problem. It is quite easy. If we require restricting the 
types to a computable set, it is just simple overloading and 
templatizing to reduce the complexity.


Having the compiler to this can reduce the noise and increase the 
robustness and also provide a nice feature that it currently does 
not have, but should.


Using templates with inheritance is a good thing, It should be 
allowed instead of blinding preventing all cases when only one 
case is uncomputable. The logic that some are using is akin to 
"We can't divide by 0 so lets not divide at all", but of course, 
division is very useful and one pathological case doesn't prevent 
all other cases from being useful.




Re: Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 22:08:03 UTC, Jonathan M Davis 
wrote:
On Wednesday, August 30, 2017 21:51:57 EntangledQuanta via 
Digitalmars-d- learn wrote:

[...]


Templates have no idea what arguments you intend to use with 
them. You can pass them any arguments you want, and as long as 
they pass the template constraint, the compiler will attempt to 
instiate the template with those arguments - which may or may 
not compile, but the compiler doesn't care about that until you 
attempt to instantiate the template.


[...]


I'm going to try to implement it as a library solution, something 
that basically does what you have done. This will at least 
simplify each instance to a few lines of code but would be 
required in all derived classes.


Re: Bug in D!!!

2017-08-30 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 20:47:12 UTC, EntangledQuanta 
wrote:

This is quite surprising!


In the new version pending release (scheduled for later this 
week), we get a new feature `static foreach` that will let you 
loop through the types you want and declare all the functions 
that way.


When it is released, we'll have to take a second look at this 
problem.


Re: Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 22:08:03 UTC, Jonathan M Davis 
wrote:
On Wednesday, August 30, 2017 21:51:57 EntangledQuanta via 
Digitalmars-d- learn wrote:
The point you are trying to making, and not doing a great job, 
is that the compiler cannot create an unknown set of virtual 
functions from a single templated virtual function. BUT, when 
you realize that is what the problem is, the unknown set is 
the issue NOT templated virtual functions. Make the set known 
and finite somehow then you have a solution, and it's not that 
difficult. Just requires some elbow grease.


Templates have no idea what arguments you intend to use with 
them. You can pass them any arguments you want, and as long as 
they pass the template constraint, the compiler will attempt to 
instiate the template with those arguments - which may or may 
not compile, but the compiler doesn't care about that until you 
attempt to instantiate the template.


The language does not support a mechanism for creating a 
templated function where you define ahead of time what all of 
the legal arguments are such that the compiler will just 
instantiate them all for you. The compiler only instantiates 
templates when the code instantiates them. Feel free to open up 
an enhancement request for some sort of template which has a 
specified list of arguments to be instantiated with which the 
compiler will then instantiate up front and allow no others, 
but that is not currently a language feature.


and my point is that it is not always the case that T can be 
anything. What if T is meant to only be algebraic?


auto foo(T : Algebraic!(int, float, double))(T t){ }

will the compiler be smart enough to be able to deduce that there 
are only 3 possibilities? No, but it should. (but of course, we 
don't want to use algebraic because that makes thing messy, and 
the whole point of all this is to reduce the mess)


As far as a feature request, my guess is no one will care, I'd 
hope that wouldn't be the case, but seeming how much excitement 
in solving this problem has generated leads me to believe no one 
really cares about solving it.


The normal solution for something like that right now would be 
to explicitly declare each function that you want and then have 
them call a templated function in order to share the 
implementation. e.g.


class C
{
public:

auto foo(int i) { return _foo(i); }
auto foo(float f) { return _foo(f); }
auto foo(string s) { return _foo(s); }

private:

auto _foo(T)(T T) { ...}
}

- Jonathan M Davis


Yes, but this is really just explicit overloading. It doesn't 
solve the problem that templates are suppose to solve. When one 
starts overloading things, it becomes a bigger mess as each class 
needs to deal with the overloading and dispatching. It all could 
be solved with a bit of compiler "magic"(which should be quite 
simple).


I mean, the compiler optimizes all kinds of things, this case 
shouldn't be any different. If it can determine a template 
parameter is reasonably finite then it should convert the 
templates method in to a series of overloaded methods for us... 
which is what you essentially did.






Re: Bug in D!!!

2017-08-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, August 30, 2017 21:51:57 EntangledQuanta via Digitalmars-d-
learn wrote:
> The point you are trying to making, and not doing a great job, is
> that the compiler cannot create an unknown set of virtual
> functions from a single templated virtual function. BUT, when you
> realize that is what the problem is, the unknown set is the issue
> NOT templated virtual functions. Make the set known and finite
> somehow then you have a solution, and it's not that difficult.
> Just requires some elbow grease.

Templates have no idea what arguments you intend to use with them. You can
pass them any arguments you want, and as long as they pass the template
constraint, the compiler will attempt to instiate the template with those
arguments - which may or may not compile, but the compiler doesn't care
about that until you attempt to instantiate the template.

The language does not support a mechanism for creating a templated function
where you define ahead of time what all of the legal arguments are such that
the compiler will just instantiate them all for you. The compiler only
instantiates templates when the code instantiates them. Feel free to open up
an enhancement request for some sort of template which has a specified list
of arguments to be instantiated with which the compiler will then
instantiate up front and allow no others, but that is not currently a
language feature.

The normal solution for something like that right now would be to explicitly
declare each function that you want and then have them call a templated
function in order to share the implementation. e.g.

class C
{
public:

auto foo(int i) { return _foo(i); }
auto foo(float f) { return _foo(f); }
auto foo(string s) { return _foo(s); }

private:

auto _foo(T)(T T) { ...}
}

- Jonathan M Davis



Re: Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 21:33:30 UTC, Jonathan M Davis 
wrote:
On Wednesday, August 30, 2017 20:47:12 EntangledQuanta via 
Digitalmars-d- learn wrote:

This is quite surprising!

public struct S(T)
{
  T s;
}


interface I
{
  void Go(T)(S!T s);

  static final I New()
  {
  return new C();
  }
}

abstract class A : I
{

}


class C : A
{
  void Go(T)(S!T s)
  {

  }
}


void main()
{
  S!int s;
  auto c = I.New();

  c.Go(s);// fails!
  //(cast(C)c).Go(s);  // Works, only difference is we have 
made c

an explicit C.

}

https://dpaste.dzfl.pl/dbc5a0663802

Everything works when Go is not templatized(we explicitly make 
T

an int)


This is a blocker for me! Can someone open a ticket?


It is not possible to have a function be both virtual and 
templated. A function template generates a new function 
definition every time that it's a called with a new set of 
template arguments. So, the actual functions are not known up 
front, and that fundamentally does not work with virtual 
functions, where the functions need to be known up front, and 
you get a different function by a look-up for occurring in the 
virtual function call table for the class. Templates and 
virtual functions simply don't mix. You're going to have to 
come up with a solution that does not try and mix templates and 
virtual functions.


- Jonathan M Davis



I have a finite number of possible values of T, lets say 3. They 
are known at compile time, just because you are or D thinks they 
are not simply means you or D is not trying hard enough. So, 
saying that virtual methods and templates are not compatible is 
wrong. Just because you think they are or D thinks they are means 
you haven't thought about it hard enough.


If I can overload a virtual function to get all my use cases and 
that is all I need then I **should** be able to do it with 
templates. Simple as that, if D can't do that then D needs to be 
enhanced to do so.


e.g.,

class C
{
   Go(Primitive!T)(T t);
}

The compiler can realize that T can only be a primitive, and 
generates all possible combinations of primitives, which is 
finite. This is doable, it is not impossible, regardless of what 
you think. It is equivalent to


class C
{
   Go(Primitive1 t);
   Go(Primitive2 t);
   ...
   Go(PrimitiveN t);
}


In fact, we can use string mixins to generate such code, but it 
doens't save us trouble, which is what templates are suppose to 
do in the first place. Just become someone hasn't implemented 
special cases does not mean it is theoretically impossible to do.


A different syntax would be better

interface I
{
  Go(T in [float, double, int])(T t);
}

class C : I
{
  Go(T in [float, double, int])(T t) { }
}

which the compiler "unrolls" to

interface I
{
  Go(float t);
  Go(double t);
  Go(int t);
}


class C
{
  Go(float t) { }
  Go(double t) { }
  Go(int t) { }
}

Which, is standard D code. There is nothing wrong with 
specializing the most common cases.


The point you are trying to making, and not doing a great job, is 
that the compiler cannot create an unknown set of virtual 
functions from a single templated virtual function. BUT, when you 
realize that is what the problem is, the unknown set is the issue 
NOT templated virtual functions. Make the set known and finite 
somehow then you have a solution, and it's not that difficult. 
Just requires some elbow grease.


Primitives are obviously known at compile time so that is a 
doable special case. Although there will probably be quite a bit 
of wasted space since each primitive will have a function 
generated for it for each templated function, that really isn't 
an issue.


By adding a new syntax in D, we could allow for any arbitrary(but 
known and finite) set to be used


Go(T in [A,B,C])(T t)

Where A,B,C are known types at compile time. This generates 3 
functions and is doable. (should be simple for any D compiler 
genius to add for testing)
















Re: Bug in D!!!

2017-08-30 Thread lobo via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 20:47:12 UTC, EntangledQuanta 
wrote:

This is quite surprising!

public struct S(T)
{
T s;
}


interface I
{   
void Go(T)(S!T s);

static final I New()
{
return new C();
}
}

abstract class A : I
{

}


class C : A
{
void Go(T)(S!T s)
{

}
}


void main()
{
S!int s;
auto c = I.New();

c.Go(s);// fails!
	//(cast(C)c).Go(s);  // Works, only difference is we have made 
c an explicit C.


}

https://dpaste.dzfl.pl/dbc5a0663802

Everything works when Go is not templatized(we explicitly make 
T an int)



This is a blocker for me! Can someone open a ticket?


Knock yourself out:

https://issues.dlang.org/

Anyone can open tickets for bugs or enhancement requsts.

bye,
lobo


Re: Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 21:13:19 UTC, Kagamin wrote:

It can't work this way. You can try std.variant.


Sure it can! What are you talking about! std.variant has nothing 
to do with it! It works if T is hard coded, so it should work 
generically. What's the point of templates variables if they 
can't be used across inheritance?


I could overload Go for each type and hence it should work. There 
is absolutely no reason why it can't work. Replace T with short, 
it works, replace T with anything and it works, hence it should 
work with T.


If you are claiming that the compiler has to make a virtual 
function for each T, that is nonsense, I only need it for 
primitives, and there are a finite number of them. I could create 
overloads for short, int, double, float, etc but why? The whole 
point of templates is to solve that problem.


Variants do not help.

Openmethods can solve this problem too, but D should be more 
intelligent than simply writing off all normal use cases because 
someone thinks something can't be done. How many people thought 
it was impossible to go to the moon, yet it happened. Anyone 
can't deny anything, it's such a simple thing to do...









Re: Bug in D!!!

2017-08-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, August 30, 2017 20:47:12 EntangledQuanta via Digitalmars-d-
learn wrote:
> This is quite surprising!
>
> public struct S(T)
> {
>   T s;
> }
>
>
> interface I
> {
>   void Go(T)(S!T s);
>
>   static final I New()
>   {
>   return new C();
>   }
> }
>
> abstract class A : I
> {
>
> }
>
>
> class C : A
> {
>   void Go(T)(S!T s)
>   {
>
>   }
> }
>
>
> void main()
> {
>   S!int s;
>   auto c = I.New();
>
>   c.Go(s);// fails!
>   //(cast(C)c).Go(s);  // Works, only difference is we have made c
> an explicit C.
>
> }
>
> https://dpaste.dzfl.pl/dbc5a0663802
>
> Everything works when Go is not templatized(we explicitly make T
> an int)
>
>
> This is a blocker for me! Can someone open a ticket?

It is not possible to have a function be both virtual and templated. A
function template generates a new function definition every time that it's a
called with a new set of template arguments. So, the actual functions are
not known up front, and that fundamentally does not work with virtual
functions, where the functions need to be known up front, and you get a
different function by a look-up for occurring in the virtual function call
table for the class. Templates and virtual functions simply don't mix.
You're going to have to come up with a solution that does not try and mix
templates and virtual functions.

- Jonathan M Davis



Re: Bug in D!!!

2017-08-30 Thread Kagamin via Digitalmars-d-learn

It can't work this way. You can try std.variant.


Bug in D!!!

2017-08-30 Thread EntangledQuanta via Digitalmars-d-learn

This is quite surprising!

public struct S(T)
{
T s;
}


interface I
{   
void Go(T)(S!T s);

static final I New()
{
return new C();
}
}

abstract class A : I
{

}


class C : A
{
void Go(T)(S!T s)
{

}
}


void main()
{
S!int s;
auto c = I.New();

c.Go(s);// fails!
	//(cast(C)c).Go(s);  // Works, only difference is we have made c 
an explicit C.


}

https://dpaste.dzfl.pl/dbc5a0663802

Everything works when Go is not templatized(we explicitly make T 
an int)



This is a blocker for me! Can someone open a ticket?





Re: C callbacks getting a value of 0! Bug in D?

2017-08-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/28/17 9:34 PM, Johnson Jones wrote:


produces 4 on both x86 and x64. So, I'm not sure how you are getting 8.


Yes, this is exactly why you should use c_long and c_ulong, because just 
using int makes it not portable to other systems.


-Steve


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Moritz Maxeiner via Digitalmars-d-learn

On Tuesday, 29 August 2017 at 02:47:34 UTC, Johnson Jones wrote:

[...]

Seems only long and ulong are issues.


With respect to the currently major platforms you can reasonable 
expect software to run on, yes.
Just don't try to use D on something with e.g. 32 bit C shorts 
unless you bind to it via c_short.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Johnson Jones via Digitalmars-d-learn

On Tuesday, 29 August 2017 at 01:56:43 UTC, Moritz Maxeiner wrote:

On Tuesday, 29 August 2017 at 01:34:40 UTC, Johnson Jones wrote:

[...]


produces 4 on both x86 and x64. So, I'm not sure how you are 
getting 8.


There are different 64bit data models [1] and it seems your 
platform uses LLP64, which uses 32bit longs. Am I correct in 
assuming you're on Windows (as they are the only major modern 
platform that I'm aware of that made this choice)?


[1] 
https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models


Yes.

I found this, which gives a map for all the types: 
https://dlang.org/spec/interfaceToC.html


Seems only long and ulong are issues.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 29 August 2017 at 01:34:40 UTC, Johnson Jones wrote:


import core.stdc.config;
pragma(msg, c_long.sizeof);

prints 4UL

both on x64 and x86

and and C:

void foo()
{
int dummy;
switch (dummy) {
case sizeof(long) :
case sizeof(long) :
break;
}
}


produces 4 on both x86 and x64. So, I'm not sure how you are 
getting 8.


It's because you're on Windows. There, long/ulong are 4 bytes in 
both 32- and 64-bit. On Linux/Mac/*BSD, they're 4 in 32-bit and 8 
in 64-bit. This is why we have c_long and c_ulong, to hide those 
differences.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Moritz Maxeiner via Digitalmars-d-learn

On Tuesday, 29 August 2017 at 01:34:40 UTC, Johnson Jones wrote:

[...]


produces 4 on both x86 and x64. So, I'm not sure how you are 
getting 8.


There are different 64bit data models [1] and it seems your 
platform uses LLP64, which uses 32bit longs. Am I correct in 
assuming you're on Windows (as they are the only major modern 
platform that I'm aware of that made this choice)?


[1] 
https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Johnson Jones via Digitalmars-d-learn
On Tuesday, 29 August 2017 at 00:42:45 UTC, Steven Schveighoffer 
wrote:

On 8/28/17 7:47 PM, Johnson Jones wrote:

[...]


Then I think possibly the port audio bindings are not correct. 
It's also possible that long is not 64-bit even on the platform 
you are using. Finally, it's also possible that the D compiler 
is not generating the call correctly.


When I test on my mac, c_long is 8-bytes. I'm not sure what it 
is in your case, try this code and see what happens:


import core.stdc.config;

pragma(msg, c_long.sizeof); // prints 8 on my box.

And in c:

#include 

int main()
{
   printf("%lu\n", sizeof(long)); // also prints 8 on my box
   return 0;
}

They should match. If they don't, that's a D bug (in either 
core.stdc.config or the compiler, I'm not sure which). If they 
do, then one of the other two possibilities is happening, and I 
would lean towards the bindings being incorrect.


-Steve


import core.stdc.config;
pragma(msg, c_long.sizeof);

prints 4UL

both on x64 and x86

and and C:

void foo()
{
int dummy;
switch (dummy) {
case sizeof(long) :
case sizeof(long) :
break;
}
}


produces 4 on both x86 and x64. So, I'm not sure how you are 
getting 8.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/28/17 7:47 PM, Johnson Jones wrote:

On Monday, 28 August 2017 at 21:35:27 UTC, Steven Schveighoffer wrote:

On 8/27/17 10:17 PM, Johnson Jones wrote:

Looking at the assembly shows something like this:

0041ea98  push 0x0
0041ea9a  push 0x0
0041ea9c  push 0x0
0041ea9e  push dword 0x100
0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc (0x80d4cc)]
0041eaa9  mov eax, [fs:0x2c]
0041eaaf  mov edx, [eax+ecx*4]
0041eab2  push dword [edx+0x1c]
0041eab8  push dword [edx+0x18]
0041eabe  push dword [ebp-0x54]
0041eac1  push dword [ebp-0x5c]
0041eac4  mov ebx, PA.stream (0x823f30)
0041eac9  push ebx
0041eaca  call dword near [Pa_OpenStream (0x823f18)]

I noticed that those 0's were the values being fed in to the function.

I remember converting c_ulong's to ulong's and that they were 
probably uint's in D. Converting those fixed the problem and the 
callback is now called! I converted all the ulongs to uint's but 
there were a few longs and I don't know if they are c_longs or 
d_longs...


Anyways, At least I'm on the right track.



For C/C++ interaction, always use c_... types if they are available. 
The idea is both that they will be correctly defined for the width, 
and also it will mangle correctly for C++ compilers (yes, long and int 
are mangled differently even when they are the same thing).




In portaudio, this doesn't seem to be the case. I changed all the longs 
to ints and ran my code in x64 and it worked fine.


It may just be that the stuff that uses long is not used in my code. In 
port audio I see it using unsigned long and so this should be 64-bits in 
x64. Surprised it worked. Maybe conversion is taking place or the high 
bits of the long are 0'ed and so there is not much difference.


Then I think possibly the port audio bindings are not correct. It's also 
possible that long is not 64-bit even on the platform you are using. 
Finally, it's also possible that the D compiler is not generating the 
call correctly.


When I test on my mac, c_long is 8-bytes. I'm not sure what it is in 
your case, try this code and see what happens:


import core.stdc.config;

pragma(msg, c_long.sizeof); // prints 8 on my box.

And in c:

#include 

int main()
{
   printf("%lu\n", sizeof(long)); // also prints 8 on my box
   return 0;
}

They should match. If they don't, that's a D bug (in either 
core.stdc.config or the compiler, I'm not sure which). If they do, then 
one of the other two possibilities is happening, and I would lean 
towards the bindings being incorrect.


-Steve


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Johnson Jones via Digitalmars-d-learn
On Monday, 28 August 2017 at 21:35:27 UTC, Steven Schveighoffer 
wrote:

On 8/27/17 10:17 PM, Johnson Jones wrote:

Looking at the assembly shows something like this:

0041ea98  push 0x0
0041ea9a  push 0x0
0041ea9c  push 0x0
0041ea9e  push dword 0x100
0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc 
(0x80d4cc)]

0041eaa9  mov eax, [fs:0x2c]
0041eaaf  mov edx, [eax+ecx*4]
0041eab2  push dword [edx+0x1c]
0041eab8  push dword [edx+0x18]
0041eabe  push dword [ebp-0x54]
0041eac1  push dword [ebp-0x5c]
0041eac4  mov ebx, PA.stream (0x823f30)
0041eac9  push ebx
0041eaca  call dword near [Pa_OpenStream (0x823f18)]

I noticed that those 0's were the values being fed in to the 
function.


I remember converting c_ulong's to ulong's and that they were 
probably uint's in D. Converting those fixed the problem and 
the callback is now called! I converted all the ulongs to 
uint's but there were a few longs and I don't know if they are 
c_longs or d_longs...


Anyways, At least I'm on the right track.



For C/C++ interaction, always use c_... types if they are 
available. The idea is both that they will be correctly defined 
for the width, and also it will mangle correctly for C++ 
compilers (yes, long and int are mangled differently even when 
they are the same thing).


-Steve


In portaudio, this doesn't seem to be the case. I changed all the 
longs to ints and ran my code in x64 and it worked fine.


It may just be that the stuff that uses long is not used in my 
code. In port audio I see it using unsigned long and so this 
should be 64-bits in x64. Surprised it worked. Maybe conversion 
is taking place or the high bits of the long are 0'ed and so 
there is not much difference.


Anyways, I guess I'll deal with any of those bugs when I run in 
to them, if they exist.




Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Johnson Jones via Digitalmars-d-learn

On Monday, 28 August 2017 at 22:41:56 UTC, Moritz Maxeiner wrote:

On Monday, 28 August 2017 at 22:21:18 UTC, Johnson Jones wrote:
On Monday, 28 August 2017 at 21:35:27 UTC, Steven 
Schveighoffer wrote:

[...]


and where are these c_ types defined? The reason I replaced 
them was precisely because D was not finding them.


core.stdc.config

, which unfortunately doesn't appear in the online 
documentation AFAICT (something that ought to be fixed).
A common workaround is to use pattern searching tools like grep 
if you know the phrase to look for:

$ grep -Er c_long /path/to/imports
, or in this case, since these things are usually done with 
aliases:

$ grep -Er 'alias\s+\w*\s+c_long' /path/to/imports


Thanks. I copied over stuff from the bindings and from the 
original header and I guess I missed the import.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Moritz Maxeiner via Digitalmars-d-learn

On Monday, 28 August 2017 at 22:21:18 UTC, Johnson Jones wrote:
On Monday, 28 August 2017 at 21:35:27 UTC, Steven Schveighoffer 
wrote:

On 8/27/17 10:17 PM, Johnson Jones wrote:

[...]


For C/C++ interaction, always use c_... types if they are 
available. The idea is both that they will be correctly 
defined for the width, and also it will mangle correctly for 
C++ compilers (yes, long and int are mangled differently even 
when they are the same thing).


-Steve


and where are these c_ types defined? The reason I replaced 
them was precisely because D was not finding them.


core.stdc.config

, which unfortunately doesn't appear in the online documentation 
AFAICT (something that ought to be fixed).
A common workaround is to use pattern searching tools like grep 
if you know the phrase to look for:

$ grep -Er c_long /path/to/imports
, or in this case, since these things are usually done with 
aliases:

$ grep -Er 'alias\s+\w*\s+c_long' /path/to/imports


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Johnson Jones via Digitalmars-d-learn
On Monday, 28 August 2017 at 21:35:27 UTC, Steven Schveighoffer 
wrote:

On 8/27/17 10:17 PM, Johnson Jones wrote:

[...]


For C/C++ interaction, always use c_... types if they are 
available. The idea is both that they will be correctly defined 
for the width, and also it will mangle correctly for C++ 
compilers (yes, long and int are mangled differently even when 
they are the same thing).


-Steve


and where are these c_ types defined? The reason I replaced them 
was precisely because D was not finding them.


Re: C callbacks getting a value of 0! Bug in D?

2017-08-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/27/17 10:17 PM, Johnson Jones wrote:

Looking at the assembly shows something like this:

0041ea98  push 0x0
0041ea9a  push 0x0
0041ea9c  push 0x0
0041ea9e  push dword 0x100
0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc (0x80d4cc)]
0041eaa9  mov eax, [fs:0x2c]
0041eaaf  mov edx, [eax+ecx*4]
0041eab2  push dword [edx+0x1c]
0041eab8  push dword [edx+0x18]
0041eabe  push dword [ebp-0x54]
0041eac1  push dword [ebp-0x5c]
0041eac4  mov ebx, PA.stream (0x823f30)
0041eac9  push ebx
0041eaca  call dword near [Pa_OpenStream (0x823f18)]

I noticed that those 0's were the values being fed in to the function.

I remember converting c_ulong's to ulong's and that they were probably 
uint's in D. Converting those fixed the problem and the callback is now 
called! I converted all the ulongs to uint's but there were a few longs 
and I don't know if they are c_longs or d_longs...


Anyways, At least I'm on the right track.



For C/C++ interaction, always use c_... types if they are available. The 
idea is both that they will be correctly defined for the width, and also 
it will mangle correctly for C++ compilers (yes, long and int are 
mangled differently even when they are the same thing).


-Steve


Re: C callbacks getting a value of 0! Bug in D?

2017-08-27 Thread Johnson Jones via Digitalmars-d-learn

Looking at the assembly shows something like this:

0041ea98  push 0x0
0041ea9a  push 0x0
0041ea9c  push 0x0
0041ea9e  push dword 0x100
0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc (0x80d4cc)]
0041eaa9  mov eax, [fs:0x2c]
0041eaaf  mov edx, [eax+ecx*4]
0041eab2  push dword [edx+0x1c]
0041eab8  push dword [edx+0x18]
0041eabe  push dword [ebp-0x54]
0041eac1  push dword [ebp-0x5c]
0041eac4  mov ebx, PA.stream (0x823f30)
0041eac9  push ebx
0041eaca  call dword near [Pa_OpenStream (0x823f18)]

I noticed that those 0's were the values being fed in to the 
function.


I remember converting c_ulong's to ulong's and that they were 
probably uint's in D. Converting those fixed the problem and the 
callback is now called! I converted all the ulongs to uint's but 
there were a few longs and I don't know if they are c_longs or 
d_longs...


Anyways, At least I'm on the right track.



C callbacks getting a value of 0! Bug in D?

2017-08-27 Thread Johnson Jones via Digitalmars-d-learn
Trying to set a callback for portaudio and it's seeing zero for 
the value passed.


Pa_OpenStream(, input, output, sampleRate, cast(ulong)0, 
cast(PaStreamFlags)(PaStreamFlags.NoFlag + 
0*PaStreamFlags.PrimeOutputBuffersUsingStreamCallback),

 
cast(PaStreamCallback)(a,b,c,d,e,f){
callbackCalled = true;

 return 0;
 }, 
null);

I am using a debug build of portaudio that prints out all the 
parameters before anything else, so it's not an issue with 
portaudio.


I've tried passing a normal function:

__gshared int sawtooth(const(void)* inputBuffer, void* 
outputBuffer, ulong framesPerBuffer, 
const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags 
statusFlags, void *userData)

{ return 0; }

and passing it as 

with the same issue.

I've tried changing the calling convention and using __gshared 
but the value is always 0. It seems other values are 0 too and 
can't seem to get any value in to the callback(Even a random one).



The output essentially always looks like this:


Opening Stream!
Pa_OpenStream called:
PaStream** stream: 0x00823EA0
PaStreamParameters *inputParameters: NULL
PaStreamParameters *outputParameters: 0x02C6C1C0
PaDeviceIndex outputParameters->device: 3
int outputParameters->channelCount: 4
PaSampleFormat outputParameters->sampleFormat: 1
PaTime outputParameters->suggestedLatency: 0.135000
void *outputParameters->hostApiSpecificStreamInfo: 
0x

double sampleRate: 44100
unsigned long framesPerBuffer: 256
PaStreamFlags streamFlags: 0x0
PaStreamCallback *streamCallback: 0x
void *userData: 0x
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 1
Pa_GetSampleSize returned:
int: 4
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_OpenStream returned:
*(PaStream** stream): 0x03BEAD50
PaError: 0 ( Success )


everything seems correct except:

PaStreamCallback *streamCallback: 0x
void *userData: 0x

You can find the full code at

https://forum.dlang.org/thread/lkbswgpsgxynhfyzw...@forum.dlang.org 



This is either a bug in D, an issue with calling conventions, or 
how one passes the data.



The original portaudio open stream function, so you can see that 
it simply prints it's arguments:


PaError Pa_OpenStream( PaStream** stream,
   const PaStreamParameters *inputParameters,
   const PaStreamParameters *outputParameters,
   double sampleRate,
   unsigned long framesPerBuffer,
   PaStreamFlags streamFlags,
   PaStreamCallback *streamCallback,
   void *userData )
{
PaError result;
PaUtilHostApiRepresentation *hostApi = 0;
PaDeviceIndex hostApiInputDevice = paNoDevice, 
hostApiOutputDevice = paNoDevice;
PaStreamParameters hostApiInputParameters, 
hostApiOutputParameters;
PaStreamParameters *hostApiInputParametersPtr, 
*hostApiOutputParametersPtr;



#ifdef PA_LOG_API_CALLS
PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" );
PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));

if( inputParameters == NULL ){
PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
NULL\n" ));

}else{
PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
0x%p\n", inputParameters ));
PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: 
%d\n", inputParameters->device ));
PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", 
inputParameters->channelCount ));
PA_LOGAPI(("\tPaSampleFormat 
inputParameters->sampleFormat: %d\n", 
inputParameters->sampleFormat ));
PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: 
%f\n", inputParameters->suggestedLatency ));
PA_LOGAPI(("\tvoid 
*inputParameters->hostApiSpecificStreamInfo: 0x%p\n", 
inputParameters->hostApiSpecificStreamInfo ));

}

if( outputParameters == NULL ){
PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
NULL\n" ));

}else{
PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
0x%p\n", outputParameters ));
PA_LOGAPI(("\tPaDeviceIndex

Re: Bug in D?!

2017-08-11 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Aug 11, 2017 at 11:34:04PM +, Adam D. Ruppe via Digitalmars-d-learn 
wrote:
> On Friday, 11 August 2017 at 22:43:02 UTC, Mr. Pib wrote:
> > int and I should be able to append an int without having to worry
> > about the value of the int.
> 
> Appending an int to a string really ought to just be a type mismatch error.
> 
> We might be able to convince the leadership to do that too, since that
> still fits with the C compatibility guidelines.

I support this.  Changing the behaviour silently is definitely a no-go,
but I'm all for breaking code with wrong or questionable behaviour.
Unfortunately, I'm not sure how likely it is to convince W & A about
this one... they have previously shown resistance to changing char to
int promotion rules, even though it has caused grief elsewhere.


T

-- 
One Word to write them all, One Access to find them, One Excel to count them 
all, And thus to Windows bind them. -- Mike Champion


Re: Bug in D?!

2017-08-11 Thread Mr. Pib via Digitalmars-d-learn

On Friday, 11 August 2017 at 23:34:04 UTC, Adam D. Ruppe wrote:

On Friday, 11 August 2017 at 22:43:02 UTC, Mr. Pib wrote:
int and I should be able to append an int without having to 
worry about the value of the int.


Appending an int to a string really ought to just be a type 
mismatch error.


We might be able to convince the leadership to do that too, 
since that still fits with the C compatibility guidelines.


I'd prefer that since at least it wouldn't silently work and 
produce potentially catastrophic errors. But then that too is 
still breaking backwards compatibility(which I think is the 
plague of the 21st century).




Re: Bug in D?!

2017-08-11 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 11 August 2017 at 22:43:02 UTC, Mr. Pib wrote:
int and I should be able to append an int without having to 
worry about the value of the int.


Appending an int to a string really ought to just be a type 
mismatch error.


We might be able to convince the leadership to do that too, since 
that still fits with the C compatibility guidelines.


Re: Bug in D?!

2017-08-11 Thread Mr. Pib via Digitalmars-d-learn

On Friday, 11 August 2017 at 22:50:53 UTC, ketmar wrote:

Mr. Pib wrote:

Wow, that is pretty screwed up! I thought D was against 
implicit conversions that might cause problems?  I'm passing 
an int and I should be able to append an int without having to 
worry about the value of the int. Instead D chose to do 
something very strange, awkward, and error prone.


this is legacy we got from trying to be C-compatible (along 
with int/uint autoconversion, and some other things). i believe 
that initially it was done to allow something like `char c = 
32;`, and now it is too late to change it, 'cause such change 
will break existing code (and we're trying to not break the 
code without a *very* strong reason, even if keeping old code 
working means keeping some old quirks).


The problem is that that mentality perpetuates the problem. It 
keeps things from ever getting fixed and corrected by it's very 
nature... all to supposedly save time but how much time does 
it waste too? It would be better to break things cleanly and let 
those that get errors fix them... cause hell, after some years 
the old code will not be used more anyways or be rewritten so 
maybe it is trying to solve a problem that doesn't actually exist?


Re: Bug in D?!

2017-08-11 Thread ketmar via Digitalmars-d-learn

Mr. Pib wrote:

Wow, that is pretty screwed up! I thought D was against implicit 
conversions that might cause problems?  I'm passing an int and I should 
be able to append an int without having to worry about the value of the 
int. Instead D chose to do something very strange, awkward, and error 
prone.


this is legacy we got from trying to be C-compatible (along with int/uint 
autoconversion, and some other things). i believe that initially it was 
done to allow something like `char c = 32;`, and now it is too late to 
change it, 'cause such change will break existing code (and we're trying to 
not break the code without a *very* strong reason, even if keeping old code 
working means keeping some old quirks).


Re: Bug in D?!

2017-08-11 Thread Mr. Pib via Digitalmars-d-learn

On Friday, 11 August 2017 at 04:17:32 UTC, ketmar wrote:

Mr. Pib wrote:


string Q(alias T, alias D)()
{
pragma(msg, T);
pragma(msg, D);
enum x = T~" = "~D~";";
pragma(msg, x);
}


mixin(Q!(`x`, 100)());

outputs, at compile time,

x
100
x = d;

there is no lowercase d. I did initially define Q as

string Q(alias T, D)(D d)

and one might think it is remnants left over from I cleaned 
the project so it shouldn't be happening. Seems like a bug.


(I realized that I'd probably only ever pass compile time 
values)


Of course, using D.stringof gives the value.

The problem is the case of D.


nope. the problem is the *value* of D. `char(100)` == 'd'.

string s = "<"~100~">";

yes, this works. weither this bug or not is questionable, but 
this is how D works regerding to implicit type conversions: 
small ints (in the range of [0..char.max]) will be implicitly 
converted to `char` if necessary.



Wow, that is pretty screwed up! I thought D was against implicit 
conversions that might cause problems?  I'm passing an int and I 
should be able to append an int without having to worry about the 
value of the int. Instead D chose to do something very strange, 
awkward, and error prone.




Re: Bug in D?!

2017-08-10 Thread ketmar via Digitalmars-d-learn

Mr. Pib wrote:


string Q(alias T, alias D)()
{
pragma(msg, T);
pragma(msg, D);
enum x = T~" = "~D~";";
pragma(msg, x);
}


mixin(Q!(`x`, 100)());

outputs, at compile time,

x
100
x = d;

there is no lowercase d. I did initially define Q as

string Q(alias T, D)(D d)

and one might think it is remnants left over from I cleaned the project 
so it shouldn't be happening. Seems like a bug.


(I realized that I'd probably only ever pass compile time values)

Of course, using D.stringof gives the value.

The problem is the case of D.


nope. the problem is the *value* of D. `char(100)` == 'd'.

string s = "<"~100~">";

yes, this works. weither this bug or not is questionable, but this is how D 
works regerding to implicit type conversions: small ints (in the range of 
[0..char.max]) will be implicitly converted to `char` if necessary.


Bug in D?!

2017-08-10 Thread Mr. Pib via Digitalmars-d-learn

string Q(alias T, alias D)()
{
pragma(msg, T);
pragma(msg, D);
enum x = T~" = "~D~";";
pragma(msg, x);
}


mixin(Q!(`x`, 100)());

outputs, at compile time,

x
100
x = d;

there is no lowercase d. I did initially define Q as

string Q(alias T, D)(D d)

and one might think it is remnants left over from I cleaned the 
project so it shouldn't be happening. Seems like a bug.


(I realized that I'd probably only ever pass compile time values)

Of course, using D.stringof gives the value.

The problem is the case of D.