Re: Unique!struct bug - Re: unique_ptr | Unique for autoclose handle

2022-12-16 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 15 December 2022 at 20:12:12 UTC, Ali Çehreli wrote:
I think this is a bug because the documentation clearly talks 
about destroying the object:


OK: https://github.com/dlang/phobos/pull/8651


>  do we need to do some kind of deprecation?

The behavior is so different from the intention that I don't 
think anybody is using Unique anyway. :o)


Yes, at least for structs.


Re: Unique!struct bug - Re: unique_ptr | Unique for autoclose handle

2022-12-15 Thread Ali Çehreli via Digitalmars-d-learn

On 12/15/22 11:31, Nick Treleaven wrote:
> On Wednesday, 14 December 2022 at 17:41:07 UTC, Ali Çehreli wrote:
>> I've never used Unique but I think it has a bug (or a design issue?):
>> Its destructor is the following:
>>
>> ~this()
>> {
>> if (_p !is null)
>> {
>> destroy(_p);
>> _p = null;
>> }
>> }
>>
>> Because _p is a pointer, destroy(_p) will not dereference and destroy
>> what it points to. I think this is a bug with Unique. I think it
>> should do
>>
>>   destroy(*_p);
>
> Now filed:
> https://issues.dlang.org/show_bug.cgi?id=23561

Thanks. I was hoping others more experienced with Phobos implementation 
chime in. But to me, the intention is to destroy the object. One never 
wants to destroy a pointer as there is no operation there.


As a minor proud moment, I do cover this issue:

  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

> Do you think it's OK to just fix this or

I think this is a bug because the documentation clearly talks about 
destroying the object:


  https://dlang.org/library/std/typecons/unique.html

"When a Unique!T goes out of scope it will call destroy on the
resource T that it manages, unless it is transferred. One
important consequence of destroy is that it will call the
destructor of the resource T."

>  do we need to do some kind of deprecation?

The behavior is so different from the intention that I don't think 
anybody is using Unique anyway. :o)


Ali



Re: mixin template bug with opBinary?

2022-07-22 Thread Paul Backus via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:

I get:
```
foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B 
b) pure nothrow @nogc @safe => a])` does not match template 
declaration `opBi(A, A function(A, A)[string] f0)`

```

Is this a bug or am I doing something wrong?


Looks like this bug:

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


Re: mixin template bug with opBinary?

2022-07-22 Thread Anthony Quizon via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:56:44 UTC, Adam D Ruppe wrote:

```
mixin template opBi(
alias f0
) {
static foreach (k, f; f0) { typeof(this) opBinary(string op:
k)(typeof(this) r) { return f(this, r); } }
}
```


Thanks, this seems to do the trick.


Re: mixin template bug with opBinary?

2022-07-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/22/22 8:33 AM, Anthony Quizon wrote:

Hello,

I'm trying to create a mixin for quick binary operator overloads by 
passing in types with a corresponding associative array of strings to 
functions. However,

the code I currently have:

```
module foo;

mixin template opBi(
     A, A function(A, A)[string] f0,
) {
     static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return 
f(this, r); } }

}

struct A {
     mixin opBi!(
     A, [ "+": (A a, A b) => a],
     );
}

struct B {
     mixin opBi!(
     B, [ "+": (B a, B b) => a],
     );
}


```

Will not let me override operators on both struct A and B.

I get:
```
foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure 
nothrow @nogc @safe => a])` does not match template declaration `opBi(A, 
A function(A, A)[string] f0)`

```

Is this a bug or am I doing something wrong?


It's typing the AA differently, and therefore it doesn't fit. The type 
of the AA you are passing in is `T1[string]`, where it's expecting 
`T2[string]`, where:


`T1` is `B function(B, B) pure nothrow @nogc @safe`
`T2` is `B function(B, B)`

I don't know if there's a better way to do this, other than use a 
further template parameter to match the function type passed in.


-Steve


Re: mixin template bug with opBinary?

2022-07-22 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:

Is this a bug or am I doing something wrong?


I think this is a bug. The compiler must not take well to this 
pattern, maybe the assoc array template argument, but idk. It 
looks like the first type used gets cached and reused even if it 
is supposed to change.


I vaguely recall seeing this before but yeah smells buggy 
anyway.



An alternative you might consider is dropping some of the type 
and using typeof(this):


```
module foo;

mixin template opBi(
alias f0
) {
static foreach (k, f; f0) { typeof(this) opBinary(string op:
k)(typeof(this) r) { return f(this, r); } }
}

struct A {
mixin opBi!(
[ "+": (A a, A b) => a],
);
}

struct B {
mixin opBi!(
[ "+": (B a, B b) => a],
);
}
```

That sidesteps the bug though it just trusts you pass the right 
type to `f0`.


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-18 Thread Denis Feklushkin via Digitalmars-d-learn

On Saturday, 18 December 2021 at 12:50:17 UTC, Tejas wrote:


As Ali said, this is an implementation issue.

So I guess the answer to your question is that this is a bug.

Please file a report at [issues.dlang.org](issues.dlang.org)


Looks like this is same case:
https://issues.dlang.org/show_bug.cgi?id=13628



Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-18 Thread Tejas via Digitalmars-d-learn
On Saturday, 18 December 2021 at 11:01:53 UTC, Denis Feklushkin 
wrote:

On Friday, 17 December 2021 at 19:03:05 UTC, Tejas wrote:


Well, I got completely mislead by my experiment 

```d
struct S
{
~this() immutable {}
}
```


Interesting what discussed behaviour isn't affects method what 
implements same functionality as dtor and called explictly at 
each appropriate place.


So for dirty fix I just created

```d
void __custom_dtor() const
{ ... }
```

And then called this __custom_dtor at each dtor what uses this 
struct.


As Ali said, this is an implementation issue.

So I guess the answer to your question is that this is a bug.

Please file a report at [issues.dlang.org](issues.dlang.org)


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-18 Thread Denis Feklushkin via Digitalmars-d-learn

On Friday, 17 December 2021 at 19:03:05 UTC, Tejas wrote:


Well, I got completely mislead by my experiment 

```d
struct S
{
~this() immutable {}
}
```


Interesting what discussed behaviour isn't affects method what 
implements same functionality as dtor and called explictly at 
each appropriate place.


So for dirty fix I just created

```d
void __custom_dtor() const
{ ... }
```

And then called this __custom_dtor at each dtor what uses this 
struct.


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Tejas via Digitalmars-d-learn

On Friday, 17 December 2021 at 18:51:56 UTC, Ali Çehreli wrote:

On 12/17/21 10:01 AM, Tejas wrote:

> [...]
Storage,

There is no such requirement nor guarantee.

[...]


Well, I got completely mislead by my experiment 

```d
struct S
{
~this() immutable {}
}

void main()
{
immutable S s = S();
}
```
This failed, so I just came up with reasons to justify this 
behaviour


Thanks for correcting me 


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Ali Çehreli via Digitalmars-d-learn

On 12/17/21 10:01 AM, Tejas wrote:

> I think since `immutable` objects are kept in Read Only Storage,

There is no such requirement nor guarantee.

> you
> can't call destructors on them

Destructor is nothing but a piece of code that is executed when an 
object's life ends. A destructor need not touch any member of the object:


struct S {
  ~this() {
import std.stdio;
writeln("done");
  }
}

void main() {
  immutable a = S();
  auto b = immutable(S)();
}

Both objects are immutable there yet their destructor is executed.

> since the objects don't get erased when
> `~this` is called, but rather they get assigned their `.init` value,

That's true only for destroy(), which gets called only if the programmer 
asks for it. Otherwise, destroyed objects don't get assigned any special 
value.


> which tells the GC that they can be collected.

That's not true. The GC collects objects when there are no references to 
them. The values of the object's members have nothing to do with it.


> `immutable class` has nothing to do with it, even the following fails to
> compile:
> ```d
>
>
>
> struct S
> {
>  ~this() immutable {}

That immutable qualifier means "this destructor is for immutable objects 
of this type." However, it seems impossible to define two destructors:


  ~this() {
writeln(__FUNCTION__);
  }

  ~this() immutable {
writeln(__FUNCTION__);
  }

Error: destructor `deneme.S.~this` conflicts with destructor 
`deneme.S.~this` at deneme.d(79)


I think this is an unexplored corner of the language. Part of the 
complication may be due to implementations by an earlier compiler 
contributor, who I heard was responsible for qualifiers on constructors. 
Note two different constructors here:


import std.stdio;

struct S {
  this(int) {
writeln(__PRETTY_FUNCTION__);
  }

  this(int) immutable {
writeln(__PRETTY_FUNCTION__);
  }
}

void main() {
  auto a = immutable(S)(0);
  auto b = S(1);
}

I bet the problem here is that the implementation in the compiler is 
half-baked on these qualifiers.


Ali



Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Tejas via Digitalmars-d-learn
On Friday, 17 December 2021 at 18:32:43 UTC, Denis Feklushkin 
wrote:

On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote:

I improved your sample:

```d
immutable struct S
{
~this() {}
}

immutable struct S2
{
S sss;
~this() {}
}

void main()
{
S2 s = S2();
}
```

```
Error: `immutable` method `serializer_bug.S.~this` is not 
callable using a mutable object
Error: mutable method `serializer_bug.S2.~this` is not callable 
using a `immutable` object
serializer_bug.d(17,5):Consider adding `const` or 
`inout` here

```

immutable dtor can't be called at all?


Nope, seems to go against the very promise it's making

Labelling `~this()` as const or immutable means it won't affect 
the state of the object, but it will, by it's very nature.


That's why I said it's not too much of a stretch to imagine why 
they're disallowed entirely.


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Denis Feklushkin via Digitalmars-d-learn

On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote:

I improved your sample:

```d
immutable struct S
{
~this() {}
}

immutable struct S2
{
S sss;
~this() {}
}

void main()
{
S2 s = S2();
}
```

```
Error: `immutable` method `serializer_bug.S.~this` is not 
callable using a mutable object
Error: mutable method `serializer_bug.S2.~this` is not callable 
using a `immutable` object
serializer_bug.d(17,5):Consider adding `const` or `inout` 
here

```

immutable dtor can't be called at all?



Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Tejas via Digitalmars-d-learn
On Friday, 17 December 2021 at 18:19:34 UTC, Denis Feklushkin 
wrote:

On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:


I think since `immutable` objects are kept in Read Only Storage


Some of them can be stored in ROM in some cases, but actually 
"immutable" keyword means "not mutable for whole its lifetime"


Well, it would be really weird if destructors successfully 
executed for some class of `immutable` qualified objects but 
didn't for others.


Not too much of a stretch to imagine that destruction for 
immutable objects was outright disallowed.


Someone who can explain this behaviour more thoroughly would be 
much appreciated 


Maybe we should allow finalizers to mutate their instance?


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Denis Feklushkin via Digitalmars-d-learn

On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:


I think since `immutable` objects are kept in Read Only Storage


Some of them can be stored in ROM in some cases, but actually 
"immutable" keyword means "not mutable for whole its lifetime"


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Tejas via Digitalmars-d-learn

On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:
On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin 
wrote:
On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin 
wrote:



[...]


("serializer_bug" is just name of my local .d file)


I think since `immutable` objects are kept in Read Only 
Storage, you can't call destructors on them since the objects 
don't get erased when `~this` is called, but rather they get 
assigned their `.init` value, which tells the GC that they can 
be collected.


`immutable class` has nothing to do with it, even the following 
fails to compile:

```d



struct S
{
~this() immutable {}
}

void main()
{
S s = S();
}

Error: `immutable` method `onlineapp.S.~this` is not callable 
using a mutable object

```


Correction:
`immutable S s = S();` inside the `void main()`


Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Tejas via Digitalmars-d-learn
On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin 
wrote:
On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin 
wrote:


~this() {} // Comment out this to fix this compilation  
error:

// Error: `immutable` method `serializer_bug.Imm.~this` is


("serializer_bug" is just name of my local .d file)


I think since `immutable` objects are kept in Read Only Storage, 
you can't call destructors on them since the objects don't get 
erased when `~this` is called, but rather they get assigned their 
`.init` value, which tells the GC that they can be collected.


`immutable class` has nothing to do with it, even the following 
fails to compile:

```d



struct S
{
~this() immutable {}
}

void main()
{
S s = S();
}

Error: `immutable` method `onlineapp.S.~this` is not callable 
using a mutable object

```



Re: This is bug or not? (immutable class containing struct with dtor)

2021-12-17 Thread Denis Feklushkin via Digitalmars-d-learn
On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin 
wrote:


~this() {} // Comment out this to fix this compilation  
error:

// Error: `immutable` method `serializer_bug.Imm.~this` is


("serializer_bug" is just name of my local .d file)



Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Brian Callahan via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:38:44 UTC, jfondren wrote:


With nothing to the contrary, I'd take "must be terminated by a 
null pointer" as "can't itself be a null pointer".




The execve(2) is more explicit:
"The argument argv is a pointer to a null-terminated array of 
character pointers to NUL-terminated character strings. These 
strings construct the argument list to be made available to the 
new process. At least one non-null argument must be present in 
the array; by custom, the first element should be the name of the 
executed program (for example, the last component of path)."


Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Basile B. via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:38:44 UTC, jfondren wrote:

[...]

With nothing to the contrary, I'd take "must be terminated by a 
null pointer" as "can't itself be a null pointer".




ah yeah, and thanks, of course ... how would the count of arg be 
known without the sentinel...


Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread jfondren via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:21:52 UTC, Basile B. wrote:

What do you think ?


I'm very surprised that this is even allowed. Apparently it's 
Linux userspace that normally complains about it: 
https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/progname.c#n54


The manpages just say

```
   v - execv(), execvp(), execvpe()
   The char *const argv[] argument is an array of pointers to 
null-terminated strings  that  represent
   the argument list available to the new program.  The first 
argument, by convention, should point to
   the filename associated with the file being executed.  The 
array of pointers must be terminated  by

   a null pointer.
```

With nothing to the contrary, I'd take "must be terminated by a 
null pointer" as "can't itself be a null pointer".


On OpenBSD this fails outright:

```
RET   execve -1 errno 14 Bad address
```

You can get `execv` from `core.sys.posix.unistd`


Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Basile B. via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:21:52 UTC, Basile B. wrote:

The following code, on linux
[...]
What do you think ?


Forgot to say that this change

```diff
- execv("a", null);
+ execv("a", ["whatever".ptr].ptr);
```

makes the problem goes away, so it would be caused by how `null` 
args are handled, presumably.


Re: Is this bug ? format %(%)

2021-04-07 Thread Meta via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 17:31:09 UTC, Paul Backus wrote:

On Wednesday, 7 April 2021 at 17:04:56 UTC, novice2 wrote:

On Wednesday, 7 April 2021 at 13:43:18 UTC, Paul Backus wrote:

So, you should change your code to

writefln("%-(%s, %)", s);


sorry i dont read docs so carefully
thanks


It's not your fault--this is a pretty obscure feature, and it's 
not documented very well. Even after you've found the correct 
page in the documentation (the page for `formattedWrite` [1]), 
you have to scroll down past multiple examples to find the text 
that explains it.


[1] https://dlang.org/phobos/std_format.html#formattedWrite


I have created a pull request that will hopefully make this more 
prominent on the doc page:

https://github.com/dlang/phobos/pull/7944


Re: Is this bug ? format %(%)

2021-04-07 Thread Berni44 via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 17:31:09 UTC, Paul Backus wrote:
It's not your fault--this is a pretty obscure feature, and it's 
not documented very well. Even after you've found the correct 
page in the documentation (the page for `formattedWrite` [1]), 
you have to scroll down past multiple examples to find the text 
that explains it.


[1] https://dlang.org/phobos/std_format.html#formattedWrite


The docs of `std.format` are currently under strong revision, 
about 90% is already done, but that "feature" is among the other 
10%. I hope to get that ready till the end of the month, so the 
next stable release will have better docs.


Unfortunately it's much more difficult to change that strange 
behavior without breaking code. Currently I hope for Phobos 2.0 
coming soon and meanwhile try to prepare `std.format` for that 
change.


Re: Is this bug ? format %(%)

2021-04-07 Thread Ali Çehreli via Digitalmars-d-learn

On 4/7/21 10:04 AM, novice2 wrote:

On Wednesday, 7 April 2021 at 13:43:18 UTC, Paul Backus wrote:

So, you should change your code to

    writefln("%-(%s, %)", s);


sorry i dont read docs so carefully
thanks


For the sake of completeness, I mention this feature in a couple of 
other places:


  http://ddili.org/ders/d.en/formatted_output.html#ix_formatted_output.%-(

  https://www.youtube.com/watch?v=dRORNQIB2wA=1146s

Ali



Re: Is this bug ? format %(%)

2021-04-07 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 17:04:56 UTC, novice2 wrote:

On Wednesday, 7 April 2021 at 13:43:18 UTC, Paul Backus wrote:

So, you should change your code to

writefln("%-(%s, %)", s);


sorry i dont read docs so carefully
thanks


It's not your fault--this is a pretty obscure feature, and it's 
not documented very well. Even after you've found the correct 
page in the documentation (the page for `formattedWrite` [1]), 
you have to scroll down past multiple examples to find the text 
that explains it.


[1] https://dlang.org/phobos/std_format.html#formattedWrite


Re: Is this bug ? format %(%)

2021-04-07 Thread novice2 via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 13:43:18 UTC, Paul Backus wrote:

So, you should change your code to

writefln("%-(%s, %)", s);


sorry i dont read docs so carefully
thanks


Re: Is this bug ? format %(%)

2021-04-07 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 7 April 2021 at 13:31:59 UTC, novice3 wrote:

there is extra quotes, wich not present in firmat specifier.
is this bug, or i should change something in my code?


This is actually an intentional feature (albeit kind of a stupid 
one). From the documentation:


Inside a compound format specifier, strings and characters are 
escaped automatically. To avoid this behavior, add '-' flag to 
"%(".


So, you should change your code to

writefln("%-(%s, %)", s);


Re: The New Bug Bounty System

2019-08-19 Thread RazvanN via Digitalmars-d-announce

On Saturday, 17 August 2019 at 12:04:46 UTC, Mike Parker wrote:
Thanks to BOS Platform Korea, the new Bug Bounty system is 
live. Anyone willing to seed new bounties or increase the 
existing ones is free to do so. We hope to see the number of 
bounties grow and a few folks make some money from it. The 
details are in the blog post:


https://dlang.org/blog/2019/08/17/bug-bounties-have-arrived/

Reddit:
https://www.reddit.com/r/d_language/comments/crla4a/bug_bounties_have_arrived/

And for those who want to skip the blog post for now and get 
straight to work (read it later, though!):


https://www.flipcause.com/secure/cause_pdetails/NjI2Njg=

I'll see about getting this into the Community menu sometime 
soonish.


Awesome! Now we can fix bugs AND get rich at the same time!


Re: Scope exit bug?

2019-06-14 Thread Les De Ridder via Digitalmars-d-learn

On Friday, 14 June 2019 at 05:35:05 UTC, Amex wrote:
I used it to avoid having to write bar twice or use a flag but 
it's not working... I see no reason why it should not work. 
scope(exit) is suppose to execute the block at the end of the 
function call, right?


No, a scope guard executes at the end of the scope. The spec[1] 
has a

few examples (with output).

[1] https://dlang.org/spec/statement.html#scope-guard-statement


Re: D interface bug?

2019-03-29 Thread Alex via Digitalmars-d-learn

On Saturday, 30 March 2019 at 00:44:31 UTC, Alex wrote:

On Saturday, 30 March 2019 at 00:06:23 UTC, H. S. Teoh wrote:
On Fri, Mar 29, 2019 at 11:44:35PM +, Alex via 
Digitalmars-d-learn wrote:

interface iBase
{
iBase fooBase(iBase);
}


class cBase : iBase
{
cBase fooBase(cBase c) { return c; }

}

cBase.fooBase should be a valid override of iBase.fooBase 
because they are the same type! cBase is a super type so it 
contains everything iBase contains and maybe more.


No, that's wrong. Consider this:

class cBase : iBase
{
int x;
cBase fooBase(cBase c) { return (x==1) ? c : null; }
}

class dBase : iBase
{
string y;
dBase fooBase(dBase c) { return (y=="a") ? c : null; }
}

iBase intf = new cBase;
dBase dobj = new dBase;
dobj.fooBase(intf); // oops: intf.y doesn't exist!

I.e., it's invalid for dBase.fooBase to override the interface 
method.


The parameter type of fooBase must be the interface type or a 
super-interface thereof.  For a class C to inherit from an 
interface X means that C contains a subset of all possible 
objects that X might refer to.  Therefore, if a method takes a 
parameter of type C, it *cannot* be passed an argument of type 
X, since the actual object might be outside the subset that C 
includes. IOW, such a method cannot be covariant with a method 
that takes X as a parameter.



There should be no reason why the compiler can't figure this 
out. It's a very simple rule.


Any time the user calls iBase.fooBase it can be replaced with 
cBase.fooBase so it should not compromise any code to go 
ahead and accept it as a proper override.

[...]

Nope.  The user can call iBase.fooBase, passing it an instance 
of a different class that also implements iBase but does not 
inherit from cBase.  Then cBase.fooBase would receive an 
argument of incompatible type.



T



Ok. In my use case, which is what I was thinking of, there will 
never be a dBase. There will never be any other class that 
inherits from the interface. I have to use an interface ONLY 
because D does not allow for multiple inheritance.


class X;
class C;

class Q : X, C;


Which can't be done, so I want to do

interface iC;
class C : iC;

class Q : X, iC;


which now works. The problem now is that I have to then still 
follow these rules which are very restrictive. It's true that 
someone could come along and create an new class D : iC and 
cause problems, but that should never happen in my case. 
Ideally, if they did, they would use the same pattern as above:


interface iD;
class D : C, iD;

and this then also alleviates the problem.

In your case it is
   iC
  /  \
 /\
C  D

but in my case it should never happen, or if it would, it is 
better to do



   iC
  /
 /
C iD
 \   /
  \ /
   D


I'm only using interfaces because I have to, not because I want 
to. But then that forces me to do strange things in D and it 
causes many problems. Since one can't have fields in an 
interface it requires using properties and all that code bloat 
that comes with them, along with the casting issues, and 
overloading, etc.


Maybe, CRTP is something you can use?
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

The fact, that your interfaces are bounded to the classes in a 
1:1 manner would be a hint for this...


Re: D interface bug?

2019-03-29 Thread Alex via Digitalmars-d-learn

On Saturday, 30 March 2019 at 00:06:23 UTC, H. S. Teoh wrote:
On Fri, Mar 29, 2019 at 11:44:35PM +, Alex via 
Digitalmars-d-learn wrote:

interface iBase
{
iBase fooBase(iBase);
}


class cBase : iBase
{
cBase fooBase(cBase c) { return c; }

}

cBase.fooBase should be a valid override of iBase.fooBase 
because they are the same type! cBase is a super type so it 
contains everything iBase contains and maybe more.


No, that's wrong. Consider this:

class cBase : iBase
{
int x;
cBase fooBase(cBase c) { return (x==1) ? c : null; }
}

class dBase : iBase
{
string y;
dBase fooBase(dBase c) { return (y=="a") ? c : null; }
}

iBase intf = new cBase;
dBase dobj = new dBase;
dobj.fooBase(intf); // oops: intf.y doesn't exist!

I.e., it's invalid for dBase.fooBase to override the interface 
method.


The parameter type of fooBase must be the interface type or a 
super-interface thereof.  For a class C to inherit from an 
interface X means that C contains a subset of all possible 
objects that X might refer to.  Therefore, if a method takes a 
parameter of type C, it *cannot* be passed an argument of type 
X, since the actual object might be outside the subset that C 
includes. IOW, such a method cannot be covariant with a method 
that takes X as a parameter.



There should be no reason why the compiler can't figure this 
out. It's a very simple rule.


Any time the user calls iBase.fooBase it can be replaced with 
cBase.fooBase so it should not compromise any code to go ahead 
and accept it as a proper override.

[...]

Nope.  The user can call iBase.fooBase, passing it an instance 
of a different class that also implements iBase but does not 
inherit from cBase.  Then cBase.fooBase would receive an 
argument of incompatible type.



T



Ok. In my use case, which is what I was thinking of, there will 
never be a dBase. There will never be any other class that 
inherits from the interface. I have to use an interface ONLY 
because D does not allow for multiple inheritance.


class X;
class C;

class Q : X, C;


Which can't be done, so I want to do

interface iC;
class C : iC;

class Q : X, iC;


which now works. The problem now is that I have to then still 
follow these rules which are very restrictive. It's true that 
someone could come along and create an new class D : iC and cause 
problems, but that should never happen in my case. Ideally, if 
they did, they would use the same pattern as above:


interface iD;
class D : C, iD;

and this then also alleviates the problem.

In your case it is
   iC
  /  \
 /\
C  D

but in my case it should never happen, or if it would, it is 
better to do



   iC
  /
 /
C iD
 \   /
  \ /
   D


I'm only using interfaces because I have to, not because I want 
to. But then that forces me to do strange things in D and it 
causes many problems. Since one can't have fields in an interface 
it requires using properties and all that code bloat that comes 
with them, along with the casting issues, and overloading, etc.













Re: D interface bug?

2019-03-29 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Mar 29, 2019 at 11:44:35PM +, Alex via Digitalmars-d-learn wrote:
> interface iBase
> {
>   iBase fooBase(iBase);
> }
> 
> 
> class cBase : iBase
> {
>   cBase fooBase(cBase c) { return c; }
> 
> }
> 
> cBase.fooBase should be a valid override of iBase.fooBase because they
> are the same type! cBase is a super type so it contains everything
> iBase contains and maybe more.

No, that's wrong. Consider this:

class cBase : iBase
{
int x;
cBase fooBase(cBase c) { return (x==1) ? c : null; }
}

class dBase : iBase
{
string y;
dBase fooBase(dBase c) { return (y=="a") ? c : null; }
}

iBase intf = new cBase;
dBase dobj = new dBase;
dobj.fooBase(intf); // oops: intf.y doesn't exist!

I.e., it's invalid for dBase.fooBase to override the interface method.

The parameter type of fooBase must be the interface type or a
super-interface thereof.  For a class C to inherit from an interface X
means that C contains a subset of all possible objects that X might
refer to.  Therefore, if a method takes a parameter of type C, it
*cannot* be passed an argument of type X, since the actual object might
be outside the subset that C includes. IOW, such a method cannot be
covariant with a method that takes X as a parameter.


> There should be no reason why the compiler can't figure this out. It's
> a very simple rule.
> 
> Any time the user calls iBase.fooBase it can be replaced with
> cBase.fooBase so it should not compromise any code to go ahead and
> accept it as a proper override.
[...]

Nope.  The user can call iBase.fooBase, passing it an instance of a
different class that also implements iBase but does not inherit from
cBase.  Then cBase.fooBase would receive an argument of incompatible
type.


T

-- 
"A man's wife has more power over him than the state has." -- Ralph Emerson


Re: D interface bug?

2019-03-29 Thread Adam D. Ruppe via Digitalmars-d-learn
On Friday, 29 March 2019 at 23:44:35 UTC, Alex wrote:
> interface iBase
> {
>   iBase fooBase(iBase);
> }
>
>
> class cBase : iBase
> {
>   cBase fooBase(cBase c) { return c; }
>
> }
>
> cBase.fooBase should be a valid override of iBase.fooBase 
> because
>  they are the same type!

The return value there is allowed, but the parameter is not. Consider this case:

class AnotherChild : iBase { /* snip */ }

iBase i = new cBase(); // allowed, cBase implements iBase
i.fooBase(new AnotherChild);


That second line should be allowed: the interface says it accepts any 
implementation of the iBase interface.

But the cBase implementation doen't allow *any* implementation of iBase - it 
only accepts cBase and down. That function wouldn't be able to handle my 
AnotherChild instance.

Thus, cBase.fooBase does NOT implement the iBase's interface, and it fails to 
compile.



Re: isSame/TemplateOf bug?

2019-02-19 Thread Ali Çehreli via Digitalmars-d-learn

On 02/19/2019 03:21 PM, SrMordred wrote:
> On Tuesday, 19 February 2019 at 23:03:37 UTC, Paul Backus wrote:

>> Inside a templated struct, the name of the template, by itself,
>> actually refers to the current instantiation. So when you write `Test`
>> in your __traits(isSame) test, the compiler interprets it as `Test!T`.
>
> True!
> writeln(Test.stringof) inside the struct give me Test!int.
>
> Thanks!
>
> Little unexpected D dark corner :P

For reference, it is the same in C++.

Ali



Re: isSame/TemplateOf bug?

2019-02-19 Thread SrMordred via Digitalmars-d-learn

On Tuesday, 19 February 2019 at 23:03:37 UTC, Paul Backus wrote:

On Tuesday, 19 February 2019 at 22:43:25 UTC, SrMordred wrote:

import std.traits;
import std.stdio;

struct Test(T)
{
this(T)( auto ref T value )
{
writeln( TemplateOf!(typeof(value)).stringof);
		writeln(  __traits(isSame, TemplateOf!(typeof(value)), Test) 
);

}
}

void main(){
auto value = Test!int(Test!int());

writeln( TemplateOf!(typeof(value)).stringof);
writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) );
}

//output:

Test(T)
false
Test(T)
true


Inside a templated struct, the name of the template, by itself, 
actually refers to the current instantiation. So when you write 
`Test` in your __traits(isSame) test, the compiler interprets 
it as `Test!T`.


True!
writeln(Test.stringof) inside the struct give me Test!int.

Thanks!

Little unexpected D dark corner :P


Re: isSame/TemplateOf bug?

2019-02-19 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 19 February 2019 at 22:43:25 UTC, SrMordred wrote:

import std.traits;
import std.stdio;

struct Test(T)
{
this(T)( auto ref T value )
{
writeln( TemplateOf!(typeof(value)).stringof);
		writeln(  __traits(isSame, TemplateOf!(typeof(value)), Test) 
);

}
}

void main(){
auto value = Test!int(Test!int());

writeln( TemplateOf!(typeof(value)).stringof);
writeln( __traits(isSame, TemplateOf!(typeof(value)), Test) );
}

//output:

Test(T)
false
Test(T)
true


Inside a templated struct, the name of the template, by itself, 
actually refers to the current instantiation. So when you write 
`Test` in your __traits(isSame) test, the compiler interprets it 
as `Test!T`.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 08, 2019 at 11:36:03PM +, JN via Digitalmars-d-learn wrote:
> On Friday, 8 February 2019 at 23:30:44 UTC, H. S. Teoh wrote:
[...]
> > Pity we couldn't get rid of std.stdio.
[...]
> I can replace it with core.stdc.stdio if it's any better. Looks like
> any attempt to do a check for "x is null" hides the bug. I tried
> assert(), also tried if (x is null) throw new Exception(...)

Aha!  That's an important insight.  It's almost certain that it's caused
by a backend bug now.  So testing the value perturbs the codegen code
path enough to mask the bug / avoid the bug.  I think from this point
somebody who's familiar with the dmd backend ought to be able to track
it down reasonably easily.  (Unfortunately I'm completely unfamiliar
with that part of the dmd code.)


T

-- 
In order to understand recursion you must first understand recursion.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread JN via Digitalmars-d-learn

On Friday, 8 February 2019 at 23:30:44 UTC, H. S. Teoh wrote:
On Fri, Feb 08, 2019 at 10:45:39PM +, JN via 
Digitalmars-d-learn wrote: [...]
Anyway, I reduced the code further manually. It's very hard to 
reduce it any further. For example, removing the assignments 
in fromEulerAngles static method hides the bug.  Likewise, 
replacing writeln with assert makes it work properly too.


Pity we couldn't get rid of std.stdio.  It's a pretty big piece 
of code, and there are plenty of places where it may go wrong 
inside, even though we generally expect that the bug lies 
elsewhere.  Oh well.  Hopefully somebody else can dig into this 
and figure out what's going on.


Hmm. I just glanced over the std.stdio code... it appears that 
somebody has added @trusted all over the place, probably just 
to get it to compile with @safe.  That's kinda scary... 
somebody needs to vet this code carefully to make sure nothing 
fishy's going on in there!



T


I can replace it with core.stdc.stdio if it's any better. Looks 
like any attempt to do a check for "x is null" hides the bug. I 
tried assert(), also tried if (x is null) throw new Exception(...)


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 08, 2019 at 10:45:39PM +, JN via Digitalmars-d-learn wrote:
[...]
> Anyway, I reduced the code further manually. It's very hard to reduce
> it any further. For example, removing the assignments in
> fromEulerAngles static method hides the bug.  Likewise, replacing
> writeln with assert makes it work properly too.

Pity we couldn't get rid of std.stdio.  It's a pretty big piece of code,
and there are plenty of places where it may go wrong inside, even though
we generally expect that the bug lies elsewhere.  Oh well.  Hopefully
somebody else can dig into this and figure out what's going on.

Hmm. I just glanced over the std.stdio code... it appears that somebody
has added @trusted all over the place, probably just to get it to
compile with @safe.  That's kinda scary... somebody needs to vet this
code carefully to make sure nothing fishy's going on in there!


T

-- 
For every argument for something, there is always an equal and opposite 
argument against it. Debates don't give answers, only wounded or inflated egos.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread JN via Digitalmars-d-learn

On Friday, 8 February 2019 at 22:11:31 UTC, H. S. Teoh wrote:
Pity I still can't reproduce the problem locally. Otherwise I 
would reduce it even more -- e.g., eliminate std.stdio 
dependency and have the program fail on assert(obj != null), 
and a bunch of other things to make it easier for compiler devs 
to analyze -- and perhaps look at the generated assembly to see 
what went wrong.  If you have the time (and patience) to do 
that, it would greatly increase the chances of this being fixed 
in a timely way, since it would narrow down the bug even more 
so that it's easier to find in the dmd source code.



T


It seems to be a Windows 64-bit only thing. Anyway, I reduced the 
code further manually. It's very hard to reduce it any further. 
For example, removing the assignments in fromEulerAngles static 
method hides the bug. Likewise, replacing writeln with assert 
makes it work properly too.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 08, 2019 at 09:42:11PM +, JN via Digitalmars-d-learn wrote:
> On Friday, 8 February 2019 at 21:35:34 UTC, H. S. Teoh wrote:
> > On Fri, Feb 08, 2019 at 09:23:40PM +, JN via Digitalmars-d-learn
> > wrote: [...]
> > > I managed to greatly reduce the source code. I have filed a bug
> > > with the reduced testcase
> > > https://issues.dlang.org/show_bug.cgi?id=19662 .
> > 
> > Haha, you were right!  It's a compiler bug, another one of those
> > nasty -O -inline bugs.  Probably a backend codegen bug.  Ran into
> > one of those before; was pretty nasty.  Fortunately it got fixed
> > soon(ish) after I made noise about it in the forum. :-P
[...]
> Luckily it's not a blocker for me, because it doesn't trigger on debug
> builds, and for release builds I can always use LDC, but still it's
> bugging me (pun intended).

Pity I still can't reproduce the problem locally. Otherwise I would
reduce it even more -- e.g., eliminate std.stdio dependency and have the
program fail on assert(obj != null), and a bunch of other things to make
it easier for compiler devs to analyze -- and perhaps look at the
generated assembly to see what went wrong.  If you have the time (and
patience) to do that, it would greatly increase the chances of this
being fixed in a timely way, since it would narrow down the bug even
more so that it's easier to find in the dmd source code.


T

-- 
I see that you JS got Bach.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread JN via Digitalmars-d-learn

On Friday, 8 February 2019 at 21:35:34 UTC, H. S. Teoh wrote:
On Fri, Feb 08, 2019 at 09:23:40PM +, JN via 
Digitalmars-d-learn wrote: [...]
I managed to greatly reduce the source code. I have filed a 
bug with the reduced testcase 
https://issues.dlang.org/show_bug.cgi?id=19662 .


Haha, you were right!  It's a compiler bug, another one of 
those nasty -O -inline bugs.  Probably a backend codegen bug.  
Ran into one of those before; was pretty nasty.  Fortunately it 
got fixed soon(ish) after I made noise about it in the forum. 
:-P



T


Luckily it's not a blocker for me, because it doesn't trigger on 
debug builds, and for release builds I can always use LDC, but 
still it's bugging me (pun intended).


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 08, 2019 at 09:23:40PM +, JN via Digitalmars-d-learn wrote:
[...]
> I managed to greatly reduce the source code. I have filed a bug with
> the reduced testcase https://issues.dlang.org/show_bug.cgi?id=19662 .

Haha, you were right!  It's a compiler bug, another one of those nasty
-O -inline bugs.  Probably a backend codegen bug.  Ran into one of those
before; was pretty nasty.  Fortunately it got fixed soon(ish) after I
made noise about it in the forum. :-P


T

-- 
Don't drink and derive. Alcohol and algebra don't mix.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread JN via Digitalmars-d-learn
On Friday, 8 February 2019 at 09:30:12 UTC, Vladimir Panteleev 
wrote:

On Friday, 8 February 2019 at 09:28:48 UTC, JN wrote:
I will try. However, one last thing - in the example test 
scripts, it runs first with one compiler setting (or D 
version) and the second time with the other compiler setting 
(or D version). But it looks like the exit code of the first 
run is ignored anyway, so why run it?


With "set -e", the shell interpreter will exit the script with 
any command that fails (returns with non-zero status), unless 
it's in an "if" condition or such. I'll update the article to 
clarify it.


I see. Dustmite helped. I had to convert it to windows batch, so 
my testscript ended up to be:


dmd -O -inline -release -boundscheck=on -i app.d -m64
@IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1)
@app | FINDSTR /C:"Object"
@IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1)
dmd -O -inline -release -boundscheck=off -i app.d -m64
@IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1)
@app | FINDSTR /C:"null"
@IF %ERRORLEVEL% EQU 0 (EXIT /B 0) ELSE (EXIT /B 1)

I managed to greatly reduce the source code. I have filed a bug 
with the reduced testcase 
https://issues.dlang.org/show_bug.cgi?id=19662 .


Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread Vladimir Panteleev via Digitalmars-d-learn

On Friday, 8 February 2019 at 09:28:48 UTC, JN wrote:
I will try. However, one last thing - in the example test 
scripts, it runs first with one compiler setting (or D version) 
and the second time with the other compiler setting (or D 
version). But it looks like the exit code of the first run is 
ignored anyway, so why run it?


With "set -e", the shell interpreter will exit the script with 
any command that fails (returns with non-zero status), unless 
it's in an "if" condition or such. I'll update the article to 
clarify it.




Re: Tricky DMD bug, but I have no idea how to report

2019-02-08 Thread JN via Digitalmars-d-learn
On Friday, 8 February 2019 at 07:30:41 UTC, Vladimir Panteleev 
wrote:

On Thursday, 7 February 2019 at 22:16:19 UTC, JN wrote:

Does it also work for dub projects?


It will work if you can put all the relevant D code in one 
directory, which is harder for Dub, as it likes to pull 
dependencies from all over the place. When "dub dustmite" is 
insufficient (as in this case), the safest way to proceed would 
be to build with dub in verbose mode, take note of the compiler 
command lines it's using, then put them in a shell script and 
all mentioned D files in one directory, then pass that to 
Dustmite.


I will try. However, one last thing - in the example test 
scripts, it runs first with one compiler setting (or D version) 
and the second time with the other compiler setting (or D 
version). But it looks like the exit code of the first run is 
ignored anyway, so why run it?


Re: Tricky DMD bug, but I have no idea how to report

2019-02-07 Thread Vladimir Panteleev via Digitalmars-d-learn

On Thursday, 7 February 2019 at 22:16:19 UTC, JN wrote:

Does it also work for dub projects?


It will work if you can put all the relevant D code in one 
directory, which is harder for Dub, as it likes to pull 
dependencies from all over the place. When "dub dustmite" is 
insufficient (as in this case), the safest way to proceed would 
be to build with dub in verbose mode, take note of the compiler 
command lines it's using, then put them in a shell script and all 
mentioned D files in one directory, then pass that to Dustmite.




Re: Tricky DMD bug, but I have no idea how to report

2019-02-07 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Feb 07, 2019 at 10:16:19PM +, JN via Digitalmars-d-learn wrote:
[...]
> Anyway, I managed to reduce the source code greatly manually:
> 
> https://github.com/helikopterodaktyl/repro_d_release/
> 
> unfortunately I can't get rid of the dlib dependency. When built with
> debug, test outputs [0: Object], with release it outputs [0: null].
> 
> commenting this line out:
> f.rotation = Quaternionf.fromEulerAngles(Vector3f(0.0f, 0.0f, 0.0f));
> or changing it to:
> f.rotation = Quaternionf.identity();
> 
> is enough to make release output [0: Object] as well. I guess dlib is
> doing something dodgy with memory layout, but I can't see anything
> suspicious :(

Hmm. I can't seem to reproduce this in my environment (Linux/x86_64).
Tried it with various combinations of `dub -b release|debug|etc.`,
manually compiling with `dmd -I~/.dub/packages/dlib-0.15.0/dlib` with
various combinations of -release, -debug, etc..

I wonder if you somehow have an ABI mismatch caused by stale cached
objects in dub?  Perhaps try `dub --force` to force a rebuild of
everything?  Or, if you're daring, delete the entire dub cache and
rebuild, just to be sure there are no stray stale files lying around
somewhere.


Barring that, one way to narrow this down further is to copy the
relevant dlib sources into your own source tree, remove the dub
dependency, and then reduce the dlib sources as well.  I did a quick and
crude test, and discovered that you only need the following files:

dlib/math/matrix.d
dlib/math/linsolve.d
dlib/math/quaternion.d
dlib/math/decomposition.d
dlib/math/package.d
dlib/math/vector.d
dlib/math/utils.d
dlib/core/package.d
dlib/core/tuple.d

Replace dlib/core/package.d with an empty file, and edit
dlib/math/package.d to import only dlib.math.quaternion and
dlib.math.vector.

Since you're only using a very small number of functions, you can
probably quickly eliminate most of the above files too. Just edit the
files directly (since they're your own copy) and delete everything that
isn't directly needed by your code.  Of course, at the same time check
also that deleting doesn't change the bug behaviour. If it does, then
whatever you just deleted may possibly be (part of) the cause of the
problem.

Sorry I can't help you with reproducing the problem, as the bug doesn't
seem to show up in my environment.  (I suspect it's still there, just
that subtle differences in my environment may be masking it somehow.)


T

-- 
Political correctness: socially-sanctioned hypocrisy.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-07 Thread JN via Digitalmars-d-learn
On Thursday, 7 February 2019 at 03:50:32 UTC, Vladimir Panteleev 
wrote:

On Monday, 17 December 2018 at 21:59:59 UTC, JN wrote:
while working on my game engine project, I encountered a DMD 
codegen bug. It occurs only when compiling in release mode, 
debug works.


Old thread, but FWIW, such bugs can be easily and precisely 
reduced with DustMite. In your test script, just compile with 
and without the compiler option which causes the bug to 
manifest, and check that one works and the other doesn't.


I put together a short article on the DustMite wiki describing 
how to do this:

https://github.com/CyberShadow/DustMite/wiki/Reducing-a-bug-with-a-specific-compiler-option


Does it also work for dub projects?

Anyway, I managed to reduce the source code greatly manually:

https://github.com/helikopterodaktyl/repro_d_release/

unfortunately I can't get rid of the dlib dependency. When built 
with debug, test outputs [0: Object], with release it outputs [0: 
null].


commenting this line out:
f.rotation = Quaternionf.fromEulerAngles(Vector3f(0.0f, 0.0f, 
0.0f));

or changing it to:
f.rotation = Quaternionf.identity();

is enough to make release output [0: Object] as well. I guess 
dlib is doing something dodgy with memory layout, but I can't see 
anything suspicious :(


Re: Tricky DMD bug, but I have no idea how to report

2019-02-06 Thread Vladimir Panteleev via Digitalmars-d-learn

On Monday, 17 December 2018 at 21:59:59 UTC, JN wrote:
while working on my game engine project, I encountered a DMD 
codegen bug. It occurs only when compiling in release mode, 
debug works.


Old thread, but FWIW, such bugs can be easily and precisely 
reduced with DustMite. In your test script, just compile with and 
without the compiler option which causes the bug to manifest, and 
check that one works and the other doesn't.


I put together a short article on the DustMite wiki describing 
how to do this:

https://github.com/CyberShadow/DustMite/wiki/Reducing-a-bug-with-a-specific-compiler-option



Re: Tricky DMD bug, but I have no idea how to report

2019-02-06 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Feb 06, 2019 at 10:37:27PM +, JN via Digitalmars-d-learn wrote:
[...]
> I am not sure if it's a pointer bug. What worries me is that it breaks
> at the start of the program, but uncommenting code at the end of the
> program influences it. Unless there's some crazy reordering going on,
> this shouldn't normally have an effect.

As I've said before, this kind of "spooky" action-at-a-distance symptom
is exactly the kind of behaviour you'd expect from a pointer bug.  Of
course, it doesn't mean that it *must* be a pointer bug, but it does
look awfully similar to one.


> I still believe the bug is on the compiler side, but it's a bit of
> code in my case, and if I try to minimize the case, the issue
> disappears. Oh well.

That's another typical symptom of a pointer bug.  It seems less likely
to be a codegen bug, because I'd expect a codegen bug to exhibit more
consistent symptoms: if a particular code is triggering a compiler
codegen bug, then it shouldn't matter what other code is being compiled,
the bug should show up in all cases.  This kind of sensitivity to
minute, unrelated changes is closer to how pointer bugs tend to behave.

Of course, it's possible that there's a pointer bug in the *compiler*,
so there's that.  It's hard to tell either way at this point.  Though
given how much the compiler is used by so many people on a daily basis,
it's also less likely though not impossible. Unless your code just
happens to contain a particularly rare combination of language features
that causes the compiler to go down a rarely-tested code path that
contains the bug.

Anyway, given what you said about how moving (or minimizing)
seemingly-unrelated code around seems to affect the symptoms, we could
do a little educated guesswork to try to narrow it down a little more.
You said commenting out code at the end of the program affects whether
it crashes at the beginning.  Is this in the same function (presumably
main()), or is it in different functions?

If it's in the same function, one possibility is that you have some
local variables that are being overrun by a buffer overflow or some bad
pointer.  Commenting out code at the end of the function changes the
layout of variables on the stack, so it would change what gets
overwritten.  Possibly, the bug gets hidden by the bad pointer being
redirected to some innocuous variable whose value is no longer used, or
some such, so the presence of the bug is masked.

If the commented-out code is in a different function from the location
of the crash, and you're sure that the commented out code is not being
run before the crash, then it would appear to be something related to
the layout of global variables.  Perhaps there's some module static ctor
that's being triggered / not triggered, that changes the global state in
some way that affects the code at the beginning of the program?  If
there's a bad pointer that points to some heap location, the action of
module ctors running vs. not running could alter the heap state enough
to mask the bug in some cases.

Another possibility is if you're interfacing with C code and have a non
null-terminated D string that's being cast to char*, and the presence of
more code in the executable may perturb the data/code segment layout
just enough to push the string somewhere that happens to contain a null
shortly afterwards.

Just some guesses based on my experience with pointer bugs.


T

-- 
Written on the window of a clothing store: No shirt, no shoes, no service.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-06 Thread JN via Digitalmars-d-learn

On Wednesday, 6 February 2019 at 22:22:26 UTC, H. S. Teoh wrote:
Of course, I've no clue whether this is the cause of your 
problems -- it's just one of many possibilities.  Pointer bugs 
are nasty things to debug, regardless of whether or not they've 
been abstracted away in nicer clothing.  I still remember 
pointer bugs that took literally months just to get a clue on, 
because it was nigh impossible to track down where they 
happened -- the symptoms are too far removed from the cause.  
You pretty much have to take a wild guess and get lucky.


They are just as bad as race condition bugs. (Once, a race 
condition bug took me almost half a year to fix, because it 
only showed up in the customer's live environment and we could 
never reproduce it locally. We knew there was a race somewhere, 
but it was impossible to locate it. Eventually, by pure 
accident, an unrelated code change subtly altered the timings 
of certain things that made the bug more likely to manifest 
under certain conditions -- and only then were we finally able 
to reliably reproduce the problem and track down its root 
cause.)



T


I am not sure if it's a pointer bug. What worries me is that it 
breaks at the start of the program, but uncommenting code at the 
end of the program influences it. Unless there's some crazy 
reordering going on, this shouldn't normally have an effect. I 
still believe the bug is on the compiler side, but it's a bit of 
code in my case, and if I try to minimize the case, the issue 
disappears. Oh well.


Re: Tricky DMD bug, but I have no idea how to report

2019-02-06 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Feb 06, 2019 at 09:50:44PM +, JN via Digitalmars-d-learn wrote:
> On Tuesday, 18 December 2018 at 22:56:19 UTC, H. S. Teoh wrote:
> > Since no explicit slicing was done, there was no compiler error /
> > warning of any sort, and it wasn't obvious from the code what had
> > happened. By the time doSomething() was called, it was already long
> > past the source of the problem in buggyCode(), and it was almost
> > impossible to trace the problem back to its source.
> > 
> > Theoretically, -dip25 and -dip1000 are supposed to prevent this sort
> > of problem, but I don't know how fully-implemented they are, whether
> > they would catch the specific instance in your code, or whether your
> > code even compiles with these options.
[...]
> No luck. Actually, I avoid in my code pointers in general, I write my
> code very "Java-like" with objects everywhere etc.
[...]

The nasty thing about the implicit static array -> slice conversion is
that your code can have no bare pointers in sight, yet you still end up
with an invalid reference to an out-of-scope local variable.

Some of us have argued that this conversion ought to be be prohibited.
But we haven't actually tried going in that direction yet, because it
*will* break existing code (though IMO such code is suspect to begin
with, and besides, all you have to do is to explicitly slice the static
array to get around the newly-introduced compile error).

Of course, I've no clue whether this is the cause of your problems --
it's just one of many possibilities.  Pointer bugs are nasty things to
debug, regardless of whether or not they've been abstracted away in
nicer clothing.  I still remember pointer bugs that took literally
months just to get a clue on, because it was nigh impossible to track
down where they happened -- the symptoms are too far removed from the
cause.  You pretty much have to take a wild guess and get lucky.

They are just as bad as race condition bugs. (Once, a race condition bug
took me almost half a year to fix, because it only showed up in the
customer's live environment and we could never reproduce it locally. We
knew there was a race somewhere, but it was impossible to locate it.
Eventually, by pure accident, an unrelated code change subtly altered
the timings of certain things that made the bug more likely to manifest
under certain conditions -- and only then were we finally able to
reliably reproduce the problem and track down its root cause.)


T

-- 
"I suspect the best way to deal with procrastination is to put off the
procrastination itself until later. I've been meaning to try this, but
haven't gotten around to it yet. " -- swr


Re: Tricky DMD bug, but I have no idea how to report

2019-02-06 Thread JN via Digitalmars-d-learn

On Tuesday, 18 December 2018 at 22:56:19 UTC, H. S. Teoh wrote:
Since no explicit slicing was done, there was no compiler error 
/ warning of any sort, and it wasn't obvious from the code what 
had happened. By the time doSomething() was called, it was 
already long past the source of the problem in buggyCode(), and 
it was almost impossible to trace the problem back to its 
source.


Theoretically, -dip25 and -dip1000 are supposed to prevent this 
sort of problem, but I don't know how fully-implemented they 
are, whether they would catch the specific instance in your 
code, or whether your code even compiles with these options.



T


No luck. Actually, I avoid in my code pointers in general, I 
write my code very "Java-like" with objects everywhere etc. I 
gave up on the issue actually, perhaps I am encountering this bug 
https://issues.dlang.org/show_bug.cgi?id=16511 in my own code. 
Anyway, 32-bit and 64-bit debug work, so does LDC. That's good 
enough for me.


Re: Tricky DMD bug, but I have no idea how to report

2018-12-18 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Dec 18, 2018 at 10:29:07PM +, JN via Digitalmars-d-learn wrote:
> On Monday, 17 December 2018 at 22:22:05 UTC, H. S. Teoh wrote:
> > A less likely possibility might be an optimizer bug -- do you get
> > different results if you add / remove '-O' (and/or '-inline') from
> > your dmd command-line?  If some combination of -O and -inline (or
> > their removal thereof) "fixes" the problem, it could be an optimizer
> > bug. But those are rare, and usually only show up when you use an
> > obscure D feature combined with another obscure corner case, in a
> > way that people haven't thought of.  My bet is still on a pointer
> > bug somewhere in your code.
> > 
> 
> I played around with dmd commandline. It works with -O. Works with -O
> -inline. As soon as I add -boundscheck=off it breaks.
> 
> As I understand it, out of bounds access is UB. Which would fit my
> problems because they look like UB. But if I run without
> boundscheck=off, shouldn't I get a RangeError somewhere?

In theory, yes.  But I wonder if there's some corner case where some
combination of -O or -inline may cause a bounds check to be elided, but
still hit UB. Perhaps the optimizer skipped a bounds check even though
it shouldn't have.  What about compiling with -boundscheck=off but
without -O -inline?  Does that make a difference?

Barring that, it might be one of those really evil pointer bugs where
the problem has already happened far away from the site where the
symptoms first appear, usually an undetected memory corruption that only
shows up as invalid data long after the actual corruption happened. Very
hard to trace.

Are you sure you didn't accidentally do something like escape a pointer
to a local variable, or a slice of a local static array that has since
gone out of scope?  Because that's what your symptoms most closely
resemble.  The last time I ran into this in my own D code, it was caused
by D's really evil implicit conversion of static arrays to slices, where
passing a local static array implicitly passes a slice instead, e.g.:

SomeObject persistentStorage;

auto someFunc(int[] data)
{
... // stuff
persistentStorage.insert(data); // retains reference to data
...
}

void buggyCode()
{
int[16] arr = ...;
...
someFunc(arr);  // <--- implicit conversion happens here
...
// uh oh, arr is going out of scope, but
// persistentStorage holds a reference to it
}

void main()
{
...
buggyCode(); // escaped reference to local variable
...

// Crash when it tries to access the slice to
// out-of-scope data:
doSomething(persistentStorage);
...
}

Since no explicit slicing was done, there was no compiler error /
warning of any sort, and it wasn't obvious from the code what had
happened. By the time doSomething() was called, it was already long past
the source of the problem in buggyCode(), and it was almost impossible
to trace the problem back to its source.

Theoretically, -dip25 and -dip1000 are supposed to prevent this sort of
problem, but I don't know how fully-implemented they are, whether they
would catch the specific instance in your code, or whether your code
even compiles with these options.


T

-- 
There's light at the end of the tunnel. It's the oncoming train.


Re: Tricky DMD bug, but I have no idea how to report

2018-12-18 Thread JN via Digitalmars-d-learn

On Monday, 17 December 2018 at 22:22:05 UTC, H. S. Teoh wrote:
A less likely possibility might be an optimizer bug -- do you 
get different results if you add / remove '-O' (and/or 
'-inline') from your dmd command-line?  If some combination of 
-O and -inline (or their removal thereof) "fixes" the problem, 
it could be an optimizer bug. But those are rare, and usually 
only show up when you use an obscure D feature combined with 
another obscure corner case, in a way that people haven't 
thought of.  My bet is still on a pointer bug somewhere in your 
code.




I played around with dmd commandline. It works with -O. Works 
with -O -inline. As soon as I add -boundscheck=off it breaks.


As I understand it, out of bounds access is UB. Which would fit 
my problems because they look like UB. But if I run without 
boundscheck=off, shouldn't I get a RangeError somewhere?


Re: Tricky DMD bug, but I have no idea how to report

2018-12-17 Thread Aliak via Digitalmars-d-learn

On Monday, 17 December 2018 at 21:59:59 UTC, JN wrote:

Hey guys,

while working on my game engine project, I encountered a DMD 
codegen bug. It occurs only when compiling in release mode, 
debug works. Unfortunately I am unable to minimize the code, 
since it's quite a bit of code, and changing the code changes 
the bug occurrence. Basically my faulty piece of code looks 
like this


[...]


I remember a couple of months ago someone complaining about 
similar issues when switching to a newer dmd. I tried looking for 
the thread but can’t find it. Think it was on the general list.


Have you tried previous compiler versions yet?


Re: Tricky DMD bug, but I have no idea how to report

2018-12-17 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Dec 17, 2018 at 09:59:59PM +, JN via Digitalmars-d-learn wrote:
[...]
> class Texture2D {}
> 
> auto a = new Texture2D();
> auto b = new Texture2D();
> auto c = new Texture2D();
> Texture2D[int] TextureBindings;
> writeln(a, b, c);
> textureBindings[0] = a;
> textureBindings[1] = b;
> textureBindings[2] = c;
> writeln(textureBindings);
> 
> and the output is:
> 
> Texture2DTexture2DTexture2D
> [0:null, 2:null, 1:null]
> 
> I'd expect it to output:
> 
> Texture2DTexture2DTexture2D
> [0:Texture2D, 2:Texture2D, 1:Texture2D]
> 
> depending on what I change around this code, for example changing it to
> 
> writeln(a, " ", b, " ", c);
> 
> results in output of:
> 
> Texture2D Texture2D Texture2D
> [0:Texture2D, 2:null, 1:null]

Ah, a pointer bug.  Lovely. :-/

My first guess is that you have a bunch of references to local variables
that have gone out of scope.


> It feels completely random. Removing, adding calls completely
> unrelated to these changes the result.

Typical symptoms of a pointer bug of some kind.  Could be an
uninitialized pointer, if you have used `T* p = void;` anywhere.


> My guess is that the compiler somehow reorders the calls incorrectly,
> changing the semantics.

Possible, but unlikely.  My bet is that you have dangling pointers, most
likely to local variables that have gone out of scope.  Perhaps
somewhere in the code you ran into the evil implicit conversion of
static arrays into slices, which results in dangling pointers if said
slice persists beyond the lifetime of the static array.

Another likely candidate is that if you're calling C/C++ libraries
somewhere in your code, you may have passed in a wrong size, perhaps a
byte count where an array length ought to be used, or vice versa, and as
a result you got a buffer overrun.  I ran into similar bugs when writing
OpenGL code.


> Trick is, LDC works correctly and produces the expected result, both
> when compiling in debug and release mode.
[...]

I bet the bug is still there, just latent because of the slightly
different memory layout when compiling with LDC.  You probably want to
be absolutely sure it's a compiler bug before moving on, as it could
very well be a bug in your code.

A less likely possibility might be an optimizer bug -- do you get
different results if you add / remove '-O' (and/or '-inline') from your
dmd command-line?  If some combination of -O and -inline (or their
removal thereof) "fixes" the problem, it could be an optimizer bug. But
those are rare, and usually only show up when you use an obscure D
feature combined with another obscure corner case, in a way that people
haven't thought of.  My bet is still on a pointer bug somewhere in your
code.


T

-- 
If the comments and the code disagree, it's likely that *both* are wrong. -- 
Christopher


Re: D Logic bug

2018-10-15 Thread Nick Treleaven via Digitalmars-d
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler 
wrote:
For example, the "Conditional operator" in D actually has a 
higher priority than an assignment, but in C++ it's the same 
and is evaluated right-to-left.  So this expression would be 
different in C++ and D:


a ? b : c = d

In D it would be:

(a ? b : c ) = d

And in C++ would be:

a ? b : (c = d)


This is now deprecated:

 int b = 1, c = 1;
 1 ? b : c = 0;

Deprecation: `1 ? b : c` must be surrounded by parentheses when 
next to operator `=`


https://dlang.org/changelog/2.082.0.html#cond_assign


Re: D Logic bug

2018-10-12 Thread Patrick Schluter via Digitalmars-d
On Friday, 12 October 2018 at 13:15:22 UTC, Steven Schveighoffer 
wrote:

On 10/12/18 6:06 AM, Kagamin wrote:
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler 
wrote:

[...]


That's https://issues.dlang.org/show_bug.cgi?id=14186


Wow, interesting that C precedence is different from C++ here.



It's C++ which the anormal one.



Re: D Logic bug

2018-10-12 Thread Patrick Schluter via Digitalmars-d
On Thursday, 11 October 2018 at 23:17:57 UTC, Jonathan M Davis 
wrote:
On Thursday, October 11, 2018 8:35:34 AM MDT James Japherson 
via Digitalmars-d wrote:


Certainly, major languages like C, C++, Java, and C# all do it 
the way that D does, and they all have the same kind of 
precedence for the ternary operator that D does.


No, the off man out is C++. it's the only one with the priority 
of the ternary equal to assignments. All other languages do it 
like C, i.e. with a higher priority for ?:


C++ is the annoying one (as always) here.


Re: D Logic bug

2018-10-12 Thread Patrick Schluter via Digitalmars-d
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler 
wrote:
On Thursday, 11 October 2018 at 21:57:00 UTC, Jonathan M Davis 
wrote:
On Thursday, October 11, 2018 1:09:14 PM MDT Jonathan Marler 
via Digitalmars-d wrote:

On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson

wrote:
> [...]

In c++ the ternary operator is the second most lowest 
precedence operator, just above the comma.  You can see a 
table of each operator and their precendence here, I refer to 
it every so often: 
https://en.cppreference.com/w/cpp/language/operator_precedence


Learning that the ternary operator has such a low precedence 
is one of those things that all programmers eventually run 
into...welcome to the club :)


It looks like D has a similar table here 
(https://wiki.dlang.org/Operator_precedence).  However, it 
doesn't appear to have the ternary operator in there. On that 
note, D would take it's precedence order from C/C++ unless 
there's a VERY good reason to change it.


The operator precedence matches in D. Because in principle, C 
code should either be valid D code with the same semantics as 
it had in C, or it shouldn't compile as D code, changing 
operator precedence isn't something that D is going to do 
(though clearly, the ternary operator needs to be added to the 
table). It would be a disaster for porting code if we did.


- Jonathan M Davis


I had a look at the table again, looks like the ternary 
operator is on there, just called the "conditional operator".  
And to clarify, D's operator precedence is close to C/C++ but 
doesn't match exactly.


Please do not conflate C and C++. It is specifically on order of 
precedence of the ternary that the 2 languages differ. It is C++ 
and only C++ which has the unconventionnal order of precedence 
where the ternary has the same priority as the assign operators. 
ALL other C derived languages have a higher priority for the 
ternary than the assignments.


Re: D Logic bug

2018-10-12 Thread Steven Schveighoffer via Digitalmars-d

On 10/12/18 6:06 AM, Kagamin wrote:

On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler wrote:
I had a look at the table again, looks like the ternary operator is on 
there, just called the "conditional operator". And to clarify, D's 
operator precedence is close to C/C++ but doesn't match exactly.  This 
is likely a result of the grammar differences rather than an intention 
one.  For example, the "Conditional operator" in D actually has a 
higher priority than an assignment, but in C++ it's the same and is 
evaluated right-to-left.  So this expression would be different in C++ 
and D:


a ? b : c = d

In D it would be:

(a ? b : c ) = d

And in C++ would be:

a ? b : (c = d)


That's https://issues.dlang.org/show_bug.cgi?id=14186


Wow, interesting that C precedence is different from C++ here.

-Steve


Re: D Logic bug

2018-10-12 Thread Kagamin via Digitalmars-d
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler 
wrote:
I had a look at the table again, looks like the ternary 
operator is on there, just called the "conditional operator".  
And to clarify, D's operator precedence is close to C/C++ but 
doesn't match exactly.  This is likely a result of the grammar 
differences rather than an intention one.  For example, the 
"Conditional operator" in D actually has a higher priority than 
an assignment, but in C++ it's the same and is evaluated 
right-to-left.  So this expression would be different in C++ 
and D:


a ? b : c = d

In D it would be:

(a ? b : c ) = d

And in C++ would be:

a ? b : (c = d)


That's https://issues.dlang.org/show_bug.cgi?id=14186


Re: D Logic bug

2018-10-11 Thread Steven Schveighoffer via Digitalmars-d

On 10/11/18 9:16 PM, Jonathan Marler wrote:

On Thursday, 11 October 2018 at 23:29:05 UTC, Steven Schveighoffer wrote:

On 10/11/18 7:17 PM, Jonathan Marler wrote:

I had a look at the table again, looks like the ternary operator is 
on there, just called the "conditional operator". And to clarify, D's 
operator precedence is close to C/C++ but doesn't match exactly.  
This is likely a result of the grammar differences rather than an 
intention one.  For example, the "Conditional operator" in D actually 
has a higher priority than an assignment, but in C++ it's the same 
and is evaluated right-to-left.  So this expression would be 
different in C++ and D:




Not in my C/D code. It would have copious parentheses everywhere :)



Good :)


Yep. General rule of thumb for me after having been burned many many 
times -- Always use parentheses to define order of operations when 
dealing with bitwise operations (and, or, xor) and for the ternary operator.


I think I do make an exception when it's a simple assignment. i.e.:

a = cond ? 1 : 2;



That case is actually very strange, I don't know if it's something 
that's really common.




Yes, that explains why myself, Jonathan Davis and certainly others 
didn't know there were actually differences between C++ and D Operator 
precedence :)  I wasn't sure myself but having a quick look at each's 
operator precedence table made it easy to find an expression that 
behaves differently in both.




I actually was curious whether DMC followed the rules (hey, maybe Walter 
just copied his existing code!), but it does follow C's rules.


-Steve


Re: D Logic bug

2018-10-11 Thread Jonathan Marler via Digitalmars-d
On Thursday, 11 October 2018 at 23:29:05 UTC, Steven 
Schveighoffer wrote:

On 10/11/18 7:17 PM, Jonathan Marler wrote:

I had a look at the table again, looks like the ternary 
operator is on there, just called the "conditional operator".  
And to clarify, D's operator precedence is close to C/C++ but 
doesn't match exactly.  This is likely a result of the grammar 
differences rather than an intention one.  For example, the 
"Conditional operator" in D actually has a higher priority 
than an assignment, but in C++ it's the same and is evaluated 
right-to-left.  So this expression would be different in C++ 
and D:




Not in my C/D code. It would have copious parentheses 
everywhere :)




Good :)

That case is actually very strange, I don't know if it's 
something that's really common.




Yes, that explains why myself, Jonathan Davis and certainly 
others didn't know there were actually differences between C++ 
and D Operator precedence :)  I wasn't sure myself but having a 
quick look at each's operator precedence table made it easy to 
find an expression that behaves differently in both.




Re: D Logic bug

2018-10-11 Thread Trass3r via Digitalmars-d
On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson 
wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


That's why shouldn't compose it like that.
It's been a constant source of bugs in C/C++ code:
https://www.viva64.com/en/b/0583/#ID0E1CAC


Re: D Logic bug

2018-10-11 Thread Steven Schveighoffer via Digitalmars-d

On 10/11/18 7:17 PM, Jonathan Marler wrote:

I had a look at the table again, looks like the ternary operator is on 
there, just called the "conditional operator".  And to clarify, D's 
operator precedence is close to C/C++ but doesn't match exactly.  This 
is likely a result of the grammar differences rather than an intention 
one.  For example, the "Conditional operator" in D actually has a higher 
priority than an assignment, but in C++ it's the same and is evaluated 
right-to-left.  So this expression would be different in C++ and D:




Not in my C/D code. It would have copious parentheses everywhere :)

That case is actually very strange, I don't know if it's something 
that's really common.


-Steve


Re: D Logic bug

2018-10-11 Thread Jonathan Marler via Digitalmars-d
On Thursday, 11 October 2018 at 21:57:00 UTC, Jonathan M Davis 
wrote:
On Thursday, October 11, 2018 1:09:14 PM MDT Jonathan Marler 
via Digitalmars-d wrote:

On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson

wrote:
> Took me about an hour to track this one down!
>
> A + (B == 0) ? 0 : C;
>
> D is evaluating it as
>
> (A + (B == 0)) ? 0 : C;
>
>
> The whole point of the parenthesis was to associate.
>
> I usually explicitly associate precisely because of this!
>
> A + ((B == 0) ? 0 : C);
>
> In the ternary operator it should treat parenthesis directly 
> to the left as the argument.

>
> Of course, I doubt this will get fixed but it should be 
> noted so other don't step in the same poo.


In c++ the ternary operator is the second most lowest 
precedence operator, just above the comma.  You can see a 
table of each operator and their precendence here, I refer to 
it every so often: 
https://en.cppreference.com/w/cpp/language/operator_precedence


Learning that the ternary operator has such a low precedence 
is one of those things that all programmers eventually run 
into...welcome to the club :)


It looks like D has a similar table here 
(https://wiki.dlang.org/Operator_precedence).  However, it 
doesn't appear to have the ternary operator in there. On that 
note, D would take it's precedence order from C/C++ unless 
there's a VERY good reason to change it.


The operator precedence matches in D. Because in principle, C 
code should either be valid D code with the same semantics as 
it had in C, or it shouldn't compile as D code, changing 
operator precedence isn't something that D is going to do 
(though clearly, the ternary operator needs to be added to the 
table). It would be a disaster for porting code if we did.


- Jonathan M Davis


I had a look at the table again, looks like the ternary operator 
is on there, just called the "conditional operator".  And to 
clarify, D's operator precedence is close to C/C++ but doesn't 
match exactly.  This is likely a result of the grammar 
differences rather than an intention one.  For example, the 
"Conditional operator" in D actually has a higher priority than 
an assignment, but in C++ it's the same and is evaluated 
right-to-left.  So this expression would be different in C++ and 
D:


a ? b : c = d

In D it would be:

(a ? b : c ) = d

And in C++ would be:

a ? b : (c = d)

Check it out:

---
import core.stdc.stdio;
void main()
{
int a = 2, b = 3;
printf("expr = %d\n", 1 ? a : b = 4);
}
---
prints "expr = 4"

it evaluates the conditional (1 ? a : b) into the expression a, 
which is actually an rvalue! and then assigns it to 4 because of 
the "= 4" and then returns the value 4 to printf.


Here's the C++ version:

#include 

int main(int argc, char *argv[])
{
int a = 2, b = 3;
printf("expr = %d\n", 1 ? a : b = 4);
}

This one prints "expr = 2"

It simply returns the value of `a` because the "b = 4" at the end 
is all part of the "else" contition in the ternary operator.




Re: D Logic bug

2018-10-11 Thread Jonathan M Davis via Digitalmars-d
On Thursday, October 11, 2018 8:35:34 AM MDT James Japherson via 
Digitalmars-d wrote:
> Took me about an hour to track this one down!
>
> A + (B == 0) ? 0 : C;
>
> D is evaluating it as
>
> (A + (B == 0)) ? 0 : C;
>
>
> The whole point of the parenthesis was to associate.
>
> I usually explicitly associate precisely because of this!
>
> A + ((B == 0) ? 0 : C);
>
> In the ternary operator it should treat parenthesis directly to
> the left as the argument.
>
> Of course, I doubt this will get fixed but it should be noted so
> other don't step in the same poo.

When parens are used to affect operator precedence, it's _always_ by
enclosing the expression. There may be a language out there that does it a
different way, but if so, I've never heard of it. Certainly, major languages
like C, C++, Java, and C# all do it the way that D does, and they all have
the same kind of precedence for the ternary operator that D does. I honestly
have no clue how you could ever have gotten the idea that putting parens in
front of something could affect operator precedence, since I don't think
that I've ever seen anything work that way in any language ever.

By putting the parens around (B == 0), you've told the compiler to treat
that as a single expression regardless of what operator precendence would
otherwise do. You haven't told it to do anything to any other operators. So,

A + B == 0

has gone from being equivalent to

(A + B) == 0

to

A + (B == 0)

but that has no effect whatsoever on the ternary operator or any other
operator that has lower precedence. So, really, it seems to me that your
misunderstanding of operator precedence and parens goes well beyond the
ternary operator. Normally, if someone were going to be confused by the
operator precedence of the ternary operator, I'd expect them to be confused
about the precendence of stuff that happens to the right of the ternary
operator when it's in a more complicated expression, not about what happens
with parens used in the condition. That stuff is the same as you'd get in
any if statement or while loop condition.

- Jonathan M Davis





Re: D Logic bug

2018-10-11 Thread Jonathan M Davis via Digitalmars-d
On Thursday, October 11, 2018 1:09:14 PM MDT Jonathan Marler via 
Digitalmars-d wrote:
> On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson
>
> wrote:
> > Took me about an hour to track this one down!
> >
> > A + (B == 0) ? 0 : C;
> >
> > D is evaluating it as
> >
> > (A + (B == 0)) ? 0 : C;
> >
> >
> > The whole point of the parenthesis was to associate.
> >
> > I usually explicitly associate precisely because of this!
> >
> > A + ((B == 0) ? 0 : C);
> >
> > In the ternary operator it should treat parenthesis directly to
> > the left as the argument.
> >
> > Of course, I doubt this will get fixed but it should be noted
> > so other don't step in the same poo.
>
> In c++ the ternary operator is the second most lowest precedence
> operator, just above the comma.  You can see a table of each
> operator and their precendence here, I refer to it every so
> often:
> https://en.cppreference.com/w/cpp/language/operator_precedence
>
> Learning that the ternary operator has such a low precedence is
> one of those things that all programmers eventually run
> into...welcome to the club :)
>
> It looks like D has a similar table here
> (https://wiki.dlang.org/Operator_precedence).  However, it
> doesn't appear to have the ternary operator in there. On that
> note, D would take it's precedence order from C/C++ unless
> there's a VERY good reason to change it.

The operator precedence matches in D. Because in principle, C code should
either be valid D code with the same semantics as it had in C, or it
shouldn't compile as D code, changing operator precedence isn't something
that D is going to do (though clearly, the ternary operator needs to be
added to the table). It would be a disaster for porting code if we did.

- Jonathan M Davis





Re: D Logic bug

2018-10-11 Thread Neia Neutuladh via Digitalmars-d

On 10/11/2018 07:35 AM, James Japherson wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


Friends don't let friends use the ternary operator except in trivial cases.

This would be a good thing for a linter to check.


The whole point of the parenthesis was to associate.


Yes. The expression would otherwise have been parsed as:

((A + B) == 0) ? 0 : C

It might be a good idea to deprecate arithmetic with booleans, which 
would have caught this specific error.


Re: D Logic bug

2018-10-11 Thread Jonathan Marler via Digitalmars-d
On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson 
wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


The whole point of the parenthesis was to associate.

I usually explicitly associate precisely because of this!

A + ((B == 0) ? 0 : C);

In the ternary operator it should treat parenthesis directly to 
the left as the argument.


Of course, I doubt this will get fixed but it should be noted 
so other don't step in the same poo.


In c++ the ternary operator is the second most lowest precedence 
operator, just above the comma.  You can see a table of each 
operator and their precendence here, I refer to it every so 
often: 
https://en.cppreference.com/w/cpp/language/operator_precedence


Learning that the ternary operator has such a low precedence is 
one of those things that all programmers eventually run 
into...welcome to the club :)


It looks like D has a similar table here 
(https://wiki.dlang.org/Operator_precedence).  However, it 
doesn't appear to have the ternary operator in there. On that 
note, D would take it's precedence order from C/C++ unless 
there's a VERY good reason to change it.


Re: D Logic bug

2018-10-11 Thread Shachar Shemesh via Digitalmars-d

On 11/10/18 20:16, Kagamin wrote:

On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson wrote:
In the ternary operator it should treat parenthesis directly to the 
left as the argument.


I don't think parentheses are ever treated like that. They are 
self-contained and don't affect operators outside them.


Almost.

const(int) *


Re: D Logic bug

2018-10-11 Thread Patrick Schluter via Digitalmars-d
On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson 
wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


As it should.




The whole point of the parenthesis was to associate.

I usually explicitly associate precisely because of this!

A + ((B == 0) ? 0 : C);

In the ternary operator it should treat parenthesis directly to 
the left as the argument.


Of course, I doubt this will get fixed but it should be noted 
so other don't step in the same poo.


No. Except for assignement and assignment operators, ternary 
operator has the lowest precedence of any operator in D (and C, 
C++, java, PHP, C# etc.).





Re: D Logic bug

2018-10-11 Thread Kagamin via Digitalmars-d
On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson 
wrote:
In the ternary operator it should treat parenthesis directly to 
the left as the argument.


I don't think parentheses are ever treated like that. They are 
self-contained and don't affect operators outside them.


Re: D Logic bug

2018-10-11 Thread krzaq via Digitalmars-d
On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson 
wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


The whole point of the parenthesis was to associate.

I usually explicitly associate precisely because of this!

A + ((B == 0) ? 0 : C);

In the ternary operator it should treat parenthesis directly to 
the left as the argument.


Of course, I doubt this will get fixed but it should be noted 
so other don't step in the same poo.


Are any languages evaluating it differently? For example, is this 
different from C, C++, Java, C#, Ruby, Javascript?


Re: D Logic bug

2018-10-11 Thread rikki cattermole via Digitalmars-d

On 12/10/2018 3:35 AM, James Japherson wrote:

Took me about an hour to track this one down!

A + (B == 0) ? 0 : C;

D is evaluating it as

(A + (B == 0)) ? 0 : C;


The whole point of the parenthesis was to associate.

I usually explicitly associate precisely because of this!

A + ((B == 0) ? 0 : C);

In the ternary operator it should treat parenthesis directly to the left 
as the argument.


Of course, I doubt this will get fixed but it should be noted so other 
don't step in the same poo.


The specification makes this clear (even if another example is needed).

The conditional expression takes an OrOrExpression not an expression as 
the condition. In other words, it requires a boolean operation on the 
left, with Expression's for the branches (deprecated behavior related to 
assignment for else branch but won't go into that).


So not a bug and is working in a reasonable way.

https://dlang.org/spec/expression.html#conditional_expressions


Re: Static foreach bug?

2018-09-07 Thread Dechcaudron via Digitalmars-d
On Thursday, 6 September 2018 at 15:56:50 UTC, Jonathan M Davis 
wrote:
However, since attributes are applied to functions, and 
__gshared is for variables, it really wouldn't make sense to 
have @gshared, and by that same token, it wouldn't make sense 
to have @ctlocal.


I don't see any reason why @gshared/@ctlocal (with or without 
'@')could not be restricted to variables, just like @nogc is 
restricted to functions.


Regards,
Dechcaudron




Re: Static foreach bug?

2018-09-06 Thread Jonathan M Davis via Digitalmars-d
On Thursday, September 6, 2018 3:11:14 AM MDT Dechcaudron via Digitalmars-d 
wrote:
> On Wednesday, 5 September 2018 at 11:39:31 UTC, Jonathan M Davis
>
> wrote:
> > Conceptually, what Timon is talking about doing here is to add
> > an attribute to symbols declared within a static foreach where
> > that attribute indicates that the symbol is temporary (or at
> > least scoped to a particular iteration of the loop). So, saying
> > that it's "local" as __local would makes perfect sense. It's
> > local to that iteration of the loop.
> >
> > And there may very well be other syntaxes which would be
> > better, but trying to overload the meaning of static even
> > further by using it in this context would risk code breakage
> > and would be _very_ confusing for most people.
>
> You are right, using "static" would be confusing I guess. I'm
> just against starting to use __keywords reserved to the compiler
> that maybe shouldn't be. I know we already have __gshared,
> though. Just what is the criteria to prepend the double
> underscore to a keyword? Why now just use an @attribute instead?
> @gshared and @ctlocal would fit better in the D style, IMO.

__ can be used for any identifier that is reserved by the compiler. There
have been identifiers which start with __ since the language began, whereas
attributes are a later edition to the language. And regardless of whether
@gshared would make sense, __gshared predates attributes, so there's no way
that it would be @gshared. However, since attributes are applied to
functions, and __gshared is for variables, it really wouldn't make sense to
have @gshared, and by that same token, it wouldn't make sense to have
@ctlocal.

- Jonathan M Davis





Re: Static foreach bug?

2018-09-06 Thread Dechcaudron via Digitalmars-d
On Wednesday, 5 September 2018 at 11:39:31 UTC, Jonathan M Davis 
wrote:
Conceptually, what Timon is talking about doing here is to add 
an attribute to symbols declared within a static foreach where 
that attribute indicates that the symbol is temporary (or at 
least scoped to a particular iteration of the loop). So, saying 
that it's "local" as __local would makes perfect sense. It's 
local to that iteration of the loop.


And there may very well be other syntaxes which would be 
better, but trying to overload the meaning of static even 
further by using it in this context would risk code breakage 
and would be _very_ confusing for most people.


You are right, using "static" would be confusing I guess. I'm 
just against starting to use __keywords reserved to the compiler 
that maybe shouldn't be. I know we already have __gshared, 
though. Just what is the criteria to prepend the double 
underscore to a keyword? Why now just use an @attribute instead? 
@gshared and @ctlocal would fit better in the D style, IMO.


Rgds,
Dechcaudron


Re: Static foreach bug?

2018-09-05 Thread Timon Gehr via Digitalmars-d

On 05.09.2018 12:29, Dechcaudron wrote:

On Tuesday, 4 September 2018 at 19:50:27 UTC, Timon Gehr wrote:

The only blocker is finding a good syntax.


How does "static enum" sound?


It can't be anything that is legal code today (__local works for all 
declarations, not just enums).


Re: Static foreach bug?

2018-09-05 Thread Timon Gehr via Digitalmars-d

On 05.09.2018 14:41, Andre Pany wrote:

On Wednesday, 5 September 2018 at 12:05:59 UTC, rikki cattermole wrote:


Indeed. scope enum would make much more sense.


scope enum sounds a lot better for me than static enum or even __local. 
The __ words looks a little bit like compiler magic as the __ words are 
reserved for the compiler.


Kind regards
Andre


I agree, but it is not an option as scope already has a different 
meaning, and so this would redefine the semantics of existing code.


Re: Static foreach bug?

2018-09-05 Thread rikki cattermole via Digitalmars-d

On 06/09/2018 12:52 AM, JN wrote:

On Wednesday, 5 September 2018 at 12:41:05 UTC, Andre Pany wrote:

On Wednesday, 5 September 2018 at 12:05:59 UTC, rikki cattermole wrote:


Indeed. scope enum would make much more sense.


scope enum sounds a lot better for me than static enum or even 
__local. The __ words looks a little bit like compiler magic as the __ 
words are reserved for the compiler.


Kind regards
Andre


To be honest, using enum as "compile-time variable" is magic enough. 
Enum should be reserved for enumerations. But I guess it's one of those 
things that is too late to change.


An enum is some sort of constant. As long as something like scope enum 
remains a constant and not an actual variable that can be modified, then 
I think that it is ok naming-wise.


Of course the manifest enum's that you're referring to is a remnant of 
#define in C. So it sort of makes sense and a little not at the same 
time. Tis' weird.


Re: Static foreach bug?

2018-09-05 Thread JN via Digitalmars-d

On Wednesday, 5 September 2018 at 12:41:05 UTC, Andre Pany wrote:
On Wednesday, 5 September 2018 at 12:05:59 UTC, rikki 
cattermole wrote:



Indeed. scope enum would make much more sense.


scope enum sounds a lot better for me than static enum or even 
__local. The __ words looks a little bit like compiler magic as 
the __ words are reserved for the compiler.


Kind regards
Andre


To be honest, using enum as "compile-time variable" is magic 
enough. Enum should be reserved for enumerations. But I guess 
it's one of those things that is too late to change.


Re: Static foreach bug?

2018-09-05 Thread Andre Pany via Digitalmars-d
On Wednesday, 5 September 2018 at 12:05:59 UTC, rikki cattermole 
wrote:



Indeed. scope enum would make much more sense.


scope enum sounds a lot better for me than static enum or even 
__local. The __ words looks a little bit like compiler magic as 
the __ words are reserved for the compiler.


Kind regards
Andre


Re: Static foreach bug?

2018-09-05 Thread rikki cattermole via Digitalmars-d

On 05/09/2018 11:39 PM, Jonathan M Davis wrote:

On Wednesday, September 5, 2018 5:19:04 AM MDT Dechcaudron via Digitalmars-d
wrote:

On Wednesday, 5 September 2018 at 10:45:20 UTC, Jonathan M Davis

wrote:

Too many people already think that the point of static is to
just make something be done at compile time (which is actually
a pretty terrible reason to use static) without adding that
sort of thing into the confusion.


Well, "static" in English means something that does not change
(so do constant and immutable, but that's another story). One
could argue that using static for function-scope variables with
extended lifespan and for variables shared between instances of a
class is more misleading. But since virtually every language out
there uses them for that purpose, I understand we want to go with
it. But then again, "static if" and "static foreach" make sense
to me. And since all enums are compile time constants by
definition, "static enum" may be a good way to tell them apart,
although I do agree that it is far from ideal.

I understand that the syntax for CT if and foreach blocks is not
going to be changed for good reasons now, but was something like
"CTif" considered at the time? I know it doesn't "look" good as
is, but maybe some small variation could have done the trick.


The thing is that static already has a meaning when it's used on a variable
declaration.

 static foo = 42;

and

 enum foo = 42;

already have distinct meanings, and _everything_ having to do with enums is
already a compile-time thing. So, something like

 static enum foo = 42;

really stands no chance of being anything other than highly confusing. Not
to mention, you then get into the fun question of what happens when someone
does something like

 static
 {
 enum foo = 42;
 }

or

 static:
 enum foo = 42;

And actually, right now,

 static enum foo = 42;

has exactly the same meaning. In all three cases, the static is ignored,
because it's meaningless to apply it to an enum. So, making

 static enum foo = 42;

change its meaning could actually break code (albeit code that's badly
written), and if

 static enum foo = 42;

had a special meaning, then it would be inconsistent if the

 static { enum foo = 42; }

or

 static: enum foo = 42;

versions acted differently. And those actually are much more likely to break
otherwise valid code.

Conceptually, what Timon is talking about doing here is to add an attribute
to symbols declared within a static foreach where that attribute indicates
that the symbol is temporary (or at least scoped to a particular iteration
of the loop). So, saying that it's "local" as __local would makes perfect
sense. It's local to that iteration of the loop.

And there may very well be other syntaxes which would be better, but trying
to overload the meaning of static even further by using it in this context
would risk code breakage and would be _very_ confusing for most people.

- Jonathan M Davis


Indeed. scope enum would make much more sense.



Re: Static foreach bug?

2018-09-05 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 5, 2018 5:19:04 AM MDT Dechcaudron via Digitalmars-d 
wrote:
> On Wednesday, 5 September 2018 at 10:45:20 UTC, Jonathan M Davis
>
> wrote:
> > Too many people already think that the point of static is to
> > just make something be done at compile time (which is actually
> > a pretty terrible reason to use static) without adding that
> > sort of thing into the confusion.
>
> Well, "static" in English means something that does not change
> (so do constant and immutable, but that's another story). One
> could argue that using static for function-scope variables with
> extended lifespan and for variables shared between instances of a
> class is more misleading. But since virtually every language out
> there uses them for that purpose, I understand we want to go with
> it. But then again, "static if" and "static foreach" make sense
> to me. And since all enums are compile time constants by
> definition, "static enum" may be a good way to tell them apart,
> although I do agree that it is far from ideal.
>
> I understand that the syntax for CT if and foreach blocks is not
> going to be changed for good reasons now, but was something like
> "CTif" considered at the time? I know it doesn't "look" good as
> is, but maybe some small variation could have done the trick.

The thing is that static already has a meaning when it's used on a variable
declaration.

static foo = 42;

and

enum foo = 42;

already have distinct meanings, and _everything_ having to do with enums is
already a compile-time thing. So, something like

static enum foo = 42;

really stands no chance of being anything other than highly confusing. Not
to mention, you then get into the fun question of what happens when someone
does something like

static
{
enum foo = 42;
}

or

static:
enum foo = 42;

And actually, right now,

static enum foo = 42;

has exactly the same meaning. In all three cases, the static is ignored,
because it's meaningless to apply it to an enum. So, making

static enum foo = 42;

change its meaning could actually break code (albeit code that's badly
written), and if

static enum foo = 42;

had a special meaning, then it would be inconsistent if the

static { enum foo = 42; }

or

static: enum foo = 42;

versions acted differently. And those actually are much more likely to break
otherwise valid code.

Conceptually, what Timon is talking about doing here is to add an attribute
to symbols declared within a static foreach where that attribute indicates
that the symbol is temporary (or at least scoped to a particular iteration
of the loop). So, saying that it's "local" as __local would makes perfect
sense. It's local to that iteration of the loop.

And there may very well be other syntaxes which would be better, but trying
to overload the meaning of static even further by using it in this context
would risk code breakage and would be _very_ confusing for most people.

- Jonathan M Davis





Re: Static foreach bug?

2018-09-05 Thread Dechcaudron via Digitalmars-d
On Wednesday, 5 September 2018 at 10:45:20 UTC, Jonathan M Davis 
wrote:
Too many people already think that the point of static is to 
just make something be done at compile time (which is actually 
a pretty terrible reason to use static) without adding that 
sort of thing into the confusion.


Well, "static" in English means something that does not change 
(so do constant and immutable, but that's another story). One 
could argue that using static for function-scope variables with 
extended lifespan and for variables shared between instances of a 
class is more misleading. But since virtually every language out 
there uses them for that purpose, I understand we want to go with 
it. But then again, "static if" and "static foreach" make sense 
to me. And since all enums are compile time constants by 
definition, "static enum" may be a good way to tell them apart, 
although I do agree that it is far from ideal.


I understand that the syntax for CT if and foreach blocks is not 
going to be changed for good reasons now, but was something like 
"CTif" considered at the time? I know it doesn't "look" good as 
is, but maybe some small variation could have done the trick.


Rgds,
Dechcaudron


Re: Static foreach bug?

2018-09-05 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, September 5, 2018 4:29:32 AM MDT Dechcaudron via Digitalmars-d 
wrote:
> On Tuesday, 4 September 2018 at 19:50:27 UTC, Timon Gehr wrote:
> > The only blocker is finding a good syntax.
>
> How does "static enum" sound?

Like it would be really, really confusing. Too many people already think
that the point of static is to just make something be done at compile time
(which is actually a pretty terrible reason to use static) without adding
that sort of thing into the confusion. Timon's suggested __local is
infinitely better IMHO.

- Jonathan M Davis





Re: Static foreach bug?

2018-09-05 Thread Dechcaudron via Digitalmars-d

On Tuesday, 4 September 2018 at 19:50:27 UTC, Timon Gehr wrote:

The only blocker is finding a good syntax.


How does "static enum" sound?


Re: Static foreach bug?

2018-09-04 Thread Timon Gehr via Digitalmars-d

On 02.09.2018 15:45, bauss wrote:
On Sunday, 2 September 2018 at 13:26:55 UTC, Petar Kirov [ZombineDev] 
wrote:
It's intended, but with the possibility to add special syntax for 
local declarations in the future left open, as per:
https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1010.md#local-declarations 



Is there any plans to implement it soon


It has been implemented for a long time (which you will find is actually 
clearly stated if you follow the link above). The only blocker is 
finding a good syntax. Currently, it would be:


static foreach(i;0..2){
__local enum x = 2;
}


or is this going to be another half done feature?
The feature is complete. There are just some further features that might 
go well with it.


Re: Static foreach bug?

2018-09-03 Thread Meta via Digitalmars-d

On Monday, 3 September 2018 at 18:03:18 UTC, Soma wrote:
Sorry to disrupt your threat, but as a lurking in this forum 
using D for small projects, and after looking such snippet my 
first impression is how D is getting polluted and becoming more 
like Java and C++.


"final class", "public final this", "super"...


I agree with you that D has more than a few function attributes 
and it gets confusing, but I'd like to point out that "final", 
"public", "super", etc. have been in D since the first version of 
D1, if I'm not mistaken.




Re: Static foreach bug?

2018-09-03 Thread Soma via Digitalmars-d

On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:

unmaintainable piece of code:

```
final class ClassName : SoapBinding, Interface
{
  public:
  final:
  this()
  {
super();
  }
   import __stdtraits = std.traits;
   static foreach (member; __traits(derivedMembers, Interface))
  {
mixin
(
  mixin("(__stdtraits.ReturnType!" ~ member ~ ").stringof") 
~

  " " ~
  member ~
  "(" ~
mixin("parameters!" ~ member) ~
  ") { /* Do stuff ... */ }"
);
  }
}
```


Sorry to disrupt your threat, but as a lurking in this forum 
using D for small projects, and after looking such snippet my 
first impression is how D is getting polluted and becoming more 
like Java and C++.


"final class", "public final this", "super"...

And of course this is just the beginning, other attributes:

"inout", "@disable", "@system".

And keeps funny when names are somewhat 'synonymous': "shared", 
"__gshared"


or like these 3: "@safe", "@trusted", "pure"

or like these 2: "const", "immutable".

And the list goes on and on...

For beginners (Or even average programmers) it would be "very 
nice" to not confuse them.


Soma.


Re: Static foreach bug?

2018-09-03 Thread Jonathan M Davis via Digitalmars-d
n Monday, September 3, 2018 12:39:17 AM MDT Neia Neutuladh via Digitalmars-d 
wrote:
> On Monday, 3 September 2018 at 04:43:30 UTC, bauss wrote:
> > On Sunday, 2 September 2018 at 20:01:08 UTC, Neia Neutuladh
> >
> > wrote:
> >> On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:
> >>> Woud be so much more maintainable if I could have each
> >>> statement into a variable that could be maintained properly.
> >>
> >> You could extract the body of the static foreach into a
> >> [template] function.
> >
> > I'm aware of that, but it's an unnecessary work around for
> > something as trivial as the alternative would have been.
>
> You would need to mark symbols as scoped to the static foreach
> body, or else as exported from a scope to an outer scope. So it's
> not exactly trivial.

Yeah. Having scoping wouldn't work. You would either need a way to name each
of the enums individually (which you can totally do - it's just a bit of a
pain), or you'd need a way to indicate that a particular enum was somehow
scoped to that particular iteration of the loop while the symbol you really
wanted was not restricted to that iteration.

Really, what this comes down to is that static foreach doesn't do anything
special beyond extend what foreach already did when iterating over a
compile-time construct like an AliasSeq. It makes it so that you can iterate
over stuff like arrays at compile-time (instead of just stuff that only
exists at compile-time), and it makes it so that you can use it outside of
functions in order to add declarations, but it works fundamentally the same
way. The only major difference in its semantics is that it does not
introduce a new scope (unlike a foreach over an AliasSeq), because that
doesn't work with declarations, but otherwise, it works basically the same
as a foreach of an AliasSeq. You would need a fundamentally new construct in
order to have something that's somehow tied to a particular iteration of the
loop while still having having declarations that aren't tied to a particular
iteration of the loop. While such a construct would be useful for some uses
of static foreach, it wasn't part of the core concept, and it's far less
obvious what such a construct should look like. Maybe, we'll get such an
improvement at some point, but it's not necessariy for static foreach to do
its core job.

As things stand, if you want to create a symbol specific to a particular
iteration of the loop, you're going to have to use a string mixin to give it
a name unique to that iteration (presumably embedding either the index or
the key into the name).

- Jonathan M Davis





Re: Static foreach bug?

2018-09-03 Thread bauss via Digitalmars-d

On Monday, 3 September 2018 at 06:39:17 UTC, Neia Neutuladh wrote:

On Monday, 3 September 2018 at 04:43:30 UTC, bauss wrote:
On Sunday, 2 September 2018 at 20:01:08 UTC, Neia Neutuladh 
wrote:

On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:
Woud be so much more maintainable if I could have each 
statement into a variable that could be maintained properly.


You could extract the body of the static foreach into a 
[template] function.


I'm aware of that, but it's an unnecessary work around for 
something as trivial as the alternative would have been.


You would need to mark symbols as scoped to the static foreach 
body, or else as exported from a scope to an outer scope. So 
it's not exactly trivial.


It's more trivial than having them in another part of the code.

I changed my implementation though to move away from static 
foreach for now and just generate a huge mixin from the 
definitions of the generated interface.


Re: Static foreach bug?

2018-09-03 Thread Neia Neutuladh via Digitalmars-d

On Monday, 3 September 2018 at 04:43:30 UTC, bauss wrote:
On Sunday, 2 September 2018 at 20:01:08 UTC, Neia Neutuladh 
wrote:

On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:
Woud be so much more maintainable if I could have each 
statement into a variable that could be maintained properly.


You could extract the body of the static foreach into a 
[template] function.


I'm aware of that, but it's an unnecessary work around for 
something as trivial as the alternative would have been.


You would need to mark symbols as scoped to the static foreach 
body, or else as exported from a scope to an outer scope. So it's 
not exactly trivial.


Re: Static foreach bug?

2018-09-02 Thread bauss via Digitalmars-d

On Sunday, 2 September 2018 at 20:01:08 UTC, Neia Neutuladh wrote:

On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:
Woud be so much more maintainable if I could have each 
statement into a variable that could be maintained properly.


You could extract the body of the static foreach into a 
[template] function.


I'm aware of that, but it's an unnecessary work around for 
something as trivial as the alternative would have been.


Re: Static foreach bug?

2018-09-02 Thread Neia Neutuladh via Digitalmars-d

On Sunday, 2 September 2018 at 19:42:20 UTC, bauss wrote:
Woud be so much more maintainable if I could have each 
statement into a variable that could be maintained properly.


You could extract the body of the static foreach into a 
[template] function.


  1   2   3   4   5   6   >