Re: Does dmd not always compile all of the source code?

2017-12-07 Thread user1234 via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 19:19:09 UTC, A Guy With a 
Question wrote:
On Wednesday, 6 December 2017 at 18:09:45 UTC, Steven 
Schveighoffer wrote:

On 12/6/17 12:17 PM, Steven Schveighoffer wrote:

So why wouldn't the compiler fail? Because it has no idea yet 
what you mean by Nullable. It doesn't even know if Nullable 
will be available or not. You could even import Nullable, but 
Nullable!T may be an error.


To give an example of why the compiler waits until 
instantiation:


class C(T) : T
{
   void foo() { doesthisexist(); }
}

class D { void doesthisexist(); }

auto x = new C!D; // OK
auto y = new C!Object: // fail

-Steve


It also doesn't parse or do semantic checks on unit tests 
unless you add the flag...apparently.


This compiles...

unittest
{
WHY DOESNT THE COMPILER FIND A PROBLEM HERE!?
}

It seems D's fast compile times are achieved by skipping 
semantic checking and even parsing when it doesn't feel it's 
needed. I strongly disagree with this decision. This could 
leave complex dormant time bombs that break builds unexpectedly 
and even accidentally.


That's why measuring the level of coverage obtained by the 
unittests is important.
It's not just about the templates, standard if conditions that 
are never tested can also be time bombs, standard functions that 
are never tested can also be time bombs. Even more pernicious in 
a way.


Re: Does dmd not always compile all of the source code?

2017-12-07 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:07:41 UTC, A Guy With a 
Question wrote:

Does dmd not compile all source code?


It doesn't. I like to build with a few different options to 
explicitly test (e.g. build for Windows and Linux and -m32 and 
-m64 to ensure those all  exercised) and for templates, do a 
-unittest that actually runs it - e.g. instantiate Array!int - to 
make sure that works and compile with -unittest every so often 
too. Might also do a `__traits(compiles` or static assert on it 
too.


Others have explained why this is, but this is a simple way to 
ensure it compiles at least in some cases to catch typos like 
this.


Another worry btw: the opDispatch feature will just say `no such 
property` if it fails to compile its innards. A test might also 
want to call it explicitly to force error messages.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/6/17 2:19 PM, A Guy With a Question wrote:

On Wednesday, 6 December 2017 at 18:09:45 UTC, Steven Schveighoffer wrote:

On 12/6/17 12:17 PM, Steven Schveighoffer wrote:

So why wouldn't the compiler fail? Because it has no idea yet what 
you mean by Nullable. It doesn't even know if Nullable will be 
available or not. You could even import Nullable, but Nullable!T may 
be an error.


To give an example of why the compiler waits until instantiation:

class C(T) : T
{
   void foo() { doesthisexist(); }
}

class D { void doesthisexist(); }

auto x = new C!D; // OK
auto y = new C!Object: // fail

-Steve


It also doesn't parse or do semantic checks on unit tests unless you add 
the flag...apparently.


This compiles...

unittest
{
     WHY DOESNT THE COMPILER FIND A PROBLEM HERE!?
}

It seems D's fast compile times are achieved by skipping semantic 
checking and even parsing when it doesn't feel it's needed.


This is a red herring. The compile times are fast even with unittests 
enabled. They are just faster (and use less memory) when unittests 
aren't compiled in.


If a unit test is instantiating tons of templates that I'm not using in 
my main code, I don't want that being compiled and then thrown away when 
I don't care about it!


I strongly 
disagree with this decision. This could leave complex dormant time bombs 
that break builds unexpectedly and even accidentally. 


This decision was made by reality. How do you compile incomplete code? 
that is essentially what a template is.


In terms of unit tests that don't compile, I can't ever imagine someone 
writing a unittest and then not compiling with -unittest, and being 
upset their code "passed".


Note, this was done pretty recently, and simply to make the compiler 
consume less memory (and run a bit faster).


It's 
understandable in certain situations where there is enough information, 
but the first step to testing code, is first making sure it compiles...I 
don't want the compiler making decisions on what is worthy to compile.


The first step to testing code is writing tests. And the idea that the 
compiler is making these decisions arbitrarily is incorrect. You are 
telling the compiler how to compile.


If I pass a d source file into it, I want to know if it's valid. This is 
unfortunate. This might be a deal breaker for me.


There is literally only one exception to the rule, unittests. Everything 
else must be valid syntax-wise.


Even version statements must have valid syntax inside them.

Hardly a deal-breaker, since you aren't going to write unittests and 
then not run them.


-Steve


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Atila Neves via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 19:40:49 UTC, A Guy With a 
Question wrote:
On Wednesday, 6 December 2017 at 19:19:09 UTC, A Guy With a 
Question wrote:
It seems D's fast compile times are achieved by skipping 
semantic checking and even parsing when it doesn't feel it's 
needed. I strongly disagree with this decision. This could 
leave complex dormant time bombs that break builds 
unexpectedly and even accidentally. It's understandable in 
certain situations where there is enough information, but the 
first step to testing code, is first making sure it 
compiles...I don't want the compiler making decisions on what 
is worthy to compile. If I pass a d source file into it, I 
want to know if it's valid. This is unfortunate. This might be 
a deal breaker for me.


I'm very concerned of working with a language that, at minimum, 
doesn't let me know if a file I passed in even contains valid 
code.


It does let you know if it contains valid code - if you're 
actually building it.


If you write unit tests but never compile them in, whether or not 
they make any sense is IMHO irrelevant. If you write a template 
and never instantiate it, does it make a sound?*


Imagine this:

version(Windows) int i = 0;
else foobarbaz;

Should it fail to compile on Linux? How is this any different 
from:


#ifdef _WIN32
int i = 0;
#else
ohnoes
#endif

As noted by others, C++ templates work similarly. And for good 
reason!


Atila

* https://en.wikipedia.org/wiki/If_a_tree_falls_in_a_forest


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 19:19:09 UTC, A Guy With a 
Question wrote:
It seems D's fast compile times are achieved by skipping 
semantic checking and even parsing when it doesn't feel it's 
needed. I strongly disagree with this decision. This could 
leave complex dormant time bombs that break builds unexpectedly 
and even accidentally. It's understandable in certain 
situations where there is enough information, but the first 
step to testing code, is first making sure it compiles...I 
don't want the compiler making decisions on what is worthy to 
compile. If I pass a d source file into it, I want to know if 
it's valid. This is unfortunate. This might be a deal breaker 
for me.


I'm very concerned of working with a language that, at minimum, 
doesn't let me know if a file I passed in even contains valid 
code.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 18:09:45 UTC, Steven 
Schveighoffer wrote:

On 12/6/17 12:17 PM, Steven Schveighoffer wrote:

So why wouldn't the compiler fail? Because it has no idea yet 
what you mean by Nullable. It doesn't even know if Nullable 
will be available or not. You could even import Nullable, but 
Nullable!T may be an error.


To give an example of why the compiler waits until 
instantiation:


class C(T) : T
{
   void foo() { doesthisexist(); }
}

class D { void doesthisexist(); }

auto x = new C!D; // OK
auto y = new C!Object: // fail

-Steve


It also doesn't parse or do semantic checks on unit tests unless 
you add the flag...apparently.


This compiles...

unittest
{
WHY DOESNT THE COMPILER FIND A PROBLEM HERE!?
}

It seems D's fast compile times are achieved by skipping semantic 
checking and even parsing when it doesn't feel it's needed. I 
strongly disagree with this decision. This could leave complex 
dormant time bombs that break builds unexpectedly and even 
accidentally. It's understandable in certain situations where 
there is enough information, but the first step to testing code, 
is first making sure it compiles...I don't want the compiler 
making decisions on what is worthy to compile. If I pass a d 
source file into it, I want to know if it's valid. This is 
unfortunate. This might be a deal breaker for me.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/6/17 12:17 PM, Steven Schveighoffer wrote:

So why wouldn't the compiler fail? Because it has no idea yet what you 
mean by Nullable. It doesn't even know if Nullable will be available or 
not. You could even import Nullable, but Nullable!T may be an error.


To give an example of why the compiler waits until instantiation:

class C(T) : T
{
   void foo() { doesthisexist(); }
}

class D { void doesthisexist(); }

auto x = new C!D; // OK
auto y = new C!Object: // fail

-Steve


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Gary Willoughby via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:47:17 UTC, A Guy With a 
Question wrote:

abstract class Test(T)
{
private:
T thing;

public:
this(T theThing)
{
thing = theThing;
thisdoesnotexist(); // expect compiler error right here
}
}

...but this compiles just fine.


It's because it's not being used in your program. How can the 
compiler compile it without knowing what T would be?


When you do this:


class Test2
   : Test!int
{
this(int thing)
{
super(thing);
}
}


You are suppling T and now it is compiled and an error raised.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/6/17 12:04 PM, A Guy With a Question wrote:

I really do think, regardless of if this is considered a template 
expansion, that dmd should be catching these obvious errors. When one 
writes interfaces and abstract classes they are generally not ready to 
implement the end class yet. And getting a ton of errors at once when 
that occurs is really hard to deal with. I really don't understand why 
the compiler would have issues with this.


So, it is important to note that a template must successfully *parse*, 
but it cannot be semantically analyzed until it is instantiated.


It is no different from C++ templates.

So why wouldn't the compiler fail? Because it has no idea yet what you 
mean by Nullable. It doesn't even know if Nullable will be available or 
not. You could even import Nullable, but Nullable!T may be an error.


This is definitely different from Generics (which I think you are 
familiar with), where there is some semblance of structure implied in 
the wildcard types. With templates, the type can be anything.


It might be possible to do some deduction of whether something will EVER 
compile, but it's probably not worth the extra work.


Did you waste your time? No. It seems like all your errors are simple 
import problems, just fix the bugs, and you should be good!


For the future, the correct way to write templates like this is to 
instantiate them in tests. Use unittesting, and you shouldn't have 
problems like this.


-Steve


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Nick Treleaven via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 17:04:06 UTC, A Guy With a 
Question wrote:

abstract class Test(T)


Here you have a class template.


It does produce there error when I do this:

class Test2
   : Test!int


You instantiated the template, so the compiler can now type check 
the instantiated class.



class Test
   : ITest!int


Same thing here but with an interface template.

I really do think, regardless of if this is considered a 
template expansion, that dmd should be catching these obvious 
errors. When one writes interfaces and abstract classes they 
are generally not ready to implement the end class yet. And 
getting a ton of errors at once when that occurs is really hard 
to deal with. I really don't understand why the compiler would 
have issues with this.


I sympathize, something like Rust's traits or concept-enhanced 
C++ could probably do what you want, but D doesn't have this 
feature.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:49:51 UTC, A Guy With a 
Question wrote:

module grrr.grr;

abstract class Test(T)
{
private:
T thing;

public:
this(T theThing)
{
thing = theThing;
thisdoesnotexist(); // expect compiler error right here
}
}

...but this compiles just fine.


It does produce there error when I do this:

class Test2
   : Test!int
{
this(int thing)
{
super(thing);
}
}


Another example:

interface ITest(T)
{
   @property
   Nullable!T value();  // have not imported Nullable. Should fail.
}

compiles...

Fails when this happens:

class Test
   : ITest!int
{
   @property
   Nullable!int value() { return nullable(0); }
}


I really do think, regardless of if this is considered a template 
expansion, that dmd should be catching these obvious errors. When 
one writes interfaces and abstract classes they are generally not 
ready to implement the end class yet. And getting a ton of errors 
at once when that occurs is really hard to deal with. I really 
don't understand why the compiler would have issues with this.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:32:05 UTC, A Guy With a 
Question wrote:
I have to be honest, I'm a little worried about all of this 
code I just translated and how much of it is actually valid...I 
hope I didn't waste my time.


Ok, so I verified this much. I would expect an error from the 
following, but it does not actually produce an error...


module grrr.grr;

abstract class Test(T)
{
private:
T thing;

public:
this(T theThing)
{
thing = theThing;
thisdoesnotexist(); // expect compiler error right here
}
}

...but this compiles just fine.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:47:17 UTC, A Guy With a 
Question wrote:
On Wednesday, 6 December 2017 at 16:32:05 UTC, A Guy With a 
Question wrote:
I have to be honest, I'm a little worried about all of this 
code I just translated and how much of it is actually 
valid...I hope I didn't waste my time.


Ok, so I verified this much. I would expect an error from the 
following, but it does not actually produce an error...


module grrr.grr;

abstract class Test(T)
{
private:
T thing;

public:
this(T theThing)
{
thing = theThing;
thisdoesnotexist(); // expect compiler error right here
}
}

...but this compiles just fine.


It does produce there error when I do this:

class Test2
   : Test!int
{
this(int thing)
{
super(thing);
}
}


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
I have to be honest, I'm a little worried about all of this code 
I just translated and how much of it is actually valid...I hope I 
didn't waste my time.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn

On Wednesday, 6 December 2017 at 16:10:34 UTC, Atila Neves wrote:
On Wednesday, 6 December 2017 at 16:07:41 UTC, A Guy With a 
Question wrote:
Noticed several typos that dmd seems to have not picked up 
initially. Does dmd not compile all source code? I obviously 
wouldn't expect it to recompile something unnecessarily, but 
in a few cases I've just seen it not throw errors where it 
should have.


It depends on how you're invoking it.

In all likelihood, you had typos in uninstantiated templates.

Atila


I'm not sure how it works underneath the covers, but I'm not 
currently working with a ton of templates explicitly. I am 
utilizing interfaces and some generic container types, which I 
guess might mean templates underneath. However, if an abstract 
class with a generic parameter translates itself to a template 
underneath the covers, I still would expect it to throw an error 
if I have a clear syntax problem. If it's not, that's pretty 
unacceptable actually for it not to.


Re: Does dmd not always compile all of the source code?

2017-12-06 Thread Atila Neves via Digitalmars-d-learn
On Wednesday, 6 December 2017 at 16:07:41 UTC, A Guy With a 
Question wrote:
Noticed several typos that dmd seems to have not picked up 
initially. Does dmd not compile all source code? I obviously 
wouldn't expect it to recompile something unnecessarily, but in 
a few cases I've just seen it not throw errors where it should 
have.


It depends on how you're invoking it.

In all likelihood, you had typos in uninstantiated templates.

Atila


Does dmd not always compile all of the source code?

2017-12-06 Thread A Guy With a Question via Digitalmars-d-learn
Noticed several typos that dmd seems to have not picked up 
initially. Does dmd not compile all source code? I obviously 
wouldn't expect it to recompile something unnecessarily, but in a 
few cases I've just seen it not throw errors where it should have.