Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Neia Neutuladh via Digitalmars-d-learn

On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote:
Is there a reason scope(success) needs to set up for exception 
handling?

Or is this a bug / potential enhancement ?


If you had no exception handling in place, you'd need to 
duplicate code in the output. For instance:


void foo()
{
  scope(success) writeln("success!");
  if (a) return;
  if (b) return;
  throw new Exception;
}

This would have to be lowered to:

void foo()
{
  if (a) { writeln("success!"); return; }
  if (b) { writeln("success!"); return; }
  throw new Exception;
  writeln("success!");  // maybe omitted with flow analysis
}

Now imagine there were 20 places you return from the function 
early. Now imagine this is in a loop body, where you can leave it 
via goto, break, continue, return, or end-of-block. And wrapped 
in several if statements.


You generate smaller code with the exception handling system. The 
compiler only has to pay attention to scope guards in the code 
that handles it directly, instead of at every flow control 
statement. Add to that the fact that -betterC is pretty recent 
and scope guards are more than ten years old, and you get this 
hole in the compiler.


Re: How to list all the manifest constants in a class or struct

2018-06-17 Thread Heromyth via Digitalmars-d-learn

On Sunday, 17 June 2018 at 20:03:09 UTC, aliak wrote:

On Sunday, 17 June 2018 at 02:44:38 UTC, Heromyth wrote:

[...]


I think this bolts.isManifestAssignable [1] will get you 
partially there. The place where it'll fail though is a static 
immutable (since they are assignable to manifest constants) but 
you can filter those by seeing if you can take the address, 
something like:


foreach (m; __traits(allMembers, T)) {
  if (isManifestAssignable!(T, m) && 
!is(typeof(mixin(""~m))) {

// it's a manifest constant ... (?)
  }
}

There of course might be edge cases I can't think of/don't know 
about though.


Cheers,
- Ali

http://bolts.dpldocs.info/bolts.traits.isManifestAssignable.html


Thant's it. Thanks for your great lib: 
https://github.com/aliak00/bolts


Re: typeof on protected field

2018-06-17 Thread DigitalDesigns via Digitalmars-d-learn

On Sunday, 17 June 2018 at 02:29:12 UTC, Adam D. Ruppe wrote:

On Saturday, 16 June 2018 at 08:32:38 UTC, DigitalDesigns wrote:
I need to get the protected and private members for 
serialization.


This breaks encapsulation.

A better design would be to have a class know how to serialize 
itself via a serializable interface.


Yeah, but that is a lot of extra work when it is generally 
unnecessary and breaks encapsulation far more than a CT 
reflection based scheme. CT reflection should not have these same 
restrictions and encapsulation does not technically apply.


Encapsulation cannot reflect in a generic way. Reflection can be 
generic and hence handle any case.  OOP and Reflection are two 
different things and encapsulation is mainly for OOP. After all, 
encapsulation is optional and one can code so things are highly 
dependent... so why should reflection break in one case but not 
the other? One can easily deal with encapsulation in reflection 
if they desire but it shouldn't be forced as it take away many 
useful possibilities.



With proper CT reflection one does not have to touch any code and 
it can just work. With oop one has to modify the classes to 
support serialization. That's a huge difference.






Re: How to list all the manifest constants in a class or struct

2018-06-17 Thread aliak via Digitalmars-d-learn

On Sunday, 17 June 2018 at 02:44:38 UTC, Heromyth wrote:

Here is a struct named S:

struct S
{
enum X = 10;
enum Y
{
  i = 10
}
enum Z = "str";
struct S {}
class C {}

static int sx = 0;
__gshared int gx = 0;

shared void g();
}

I want list all then the manifest constants in it.

I searched the std.traits and this forums, but get nothing.
Maybe, my real question is how to get the storage class for a 
member in a class or struct.


Thanks.


I think this bolts.isManifestAssignable [1] will get you 
partially there. The place where it'll fail though is a static 
immutable (since they are assignable to manifest constants) but 
you can filter those by seeing if you can take the address, 
something like:


foreach (m; __traits(allMembers, T)) {
  if (isManifestAssignable!(T, m) && !is(typeof(mixin(""~m))) {
// it's a manifest constant ... (?)
  }
}

There of course might be edge cases I can't think of/don't know 
about though.


Cheers,
- Ali

http://bolts.dpldocs.info/bolts.traits.isManifestAssignable.html




Re: range.put() to Empty Array Causes Error?

2018-06-17 Thread Seb via Digitalmars-d-learn
On Sunday, 17 June 2018 at 12:23:55 UTC, Steven Schveighoffer 
wrote:

On 6/17/18 7:07 AM, Vijay Nayar wrote:

This code breaks with the following error:
void main()
{
 import std.range;
   int[] vals = [];
 vals.put(3);
}
/src/phobos/std/range/primitives.d(2328): Attempting to fetch 
the front of an empty array of int


The following code has no error:
void main()
{
 import std.range;
   int[] vals = [1];
 vals.put(3);
}

Why is range.put() not allowed for empty arrays?




range.put fills an existing array like a buffer, it does not 
append (as I'm guessing you are expecting). Use 
std.array.Appender to get append behavior.


Or simply ~= if you want to use built-in arrays (works with 
Appender too FWIW).




Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Mike Franklin via Digitalmars-d-learn

On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote:


---

// main.d
void main() {
scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---


You can see what the compiler is doing at 
https://run.dlang.io/is/5BZOQV and clicking on the "AST" button.  
It produces the following:


import object;
void main()
{
bool __os2 = false;
try
{
}
catch(Throwable __o3)
{
__os2 = true;
throw __o3;
}
if (!__os2)
{
}
return 0;
}

The compiler could probably lower that to something more 
intelligent so it could be used in -betterC.  I rule it a bug.


Mike




Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/17/18 8:24 AM, Timoses wrote:

On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote:

Hello,
I'm not sure whether I'm missing something obvious here, but is there 
a reason for scope(success) being lowered to a try-catch statement?
I would have expected only scope(exit) and scope(failure) to actually 
interact with exception handling, while scope(success) simply places 
code on the path of normal control flow.


Example (windows x32):

---

// main.d
void main() {
scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---

Regardless of whether -betterC is used, you can see in the disassembly 
that having a scope(success) anywhere in the function causes the SEH 
prologue to be emitted in the code.


Is there a reason scope(success) needs to set up for exception handling?
Or is this a bug / potential enhancement ?


In Andrei's book 'The D Programming Language' the following is written:

{
     
     scope(success) 
     
}
is lowered to
{
     
     bool __succeeded = true;
     try {
     
     } catch(Exception e) {
     __succeeded = false;
     throw e;
     } finally {
     if (__succeeded)  // vice-versa for scope(failure): 
`if (!__succeeded) ...`

     }
}

If it weren't and it would simply be integrated one would have to write

     potentiallyThrowingFunc();
     scope(success) {...};

I suppose? And this seems like breaking how scope works with failure and 
exit?

I think the request isn't to integrate the code immediately, but to do:

{




}

and be just fine. I think the reason the scope(failure) is done that way 
is likely for proper exception chaining in case one of the scope 
statements throws.


-Steve


Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Cauterite via Digitalmars-d-learn

On Sunday, 17 June 2018 at 12:10:33 UTC, Nicholas Wilson wrote:
I suspect scope(success) is lowered because scope(exit) and 
scope(failure)
are, and that would result in a simpler (compiler) 
implementation of it.


does adding nothrow to main fix it? For dcompute I specifically 
allow scope(exit|success) because there will never be any 
exceptions _at all_.


If not, please do submit an issue. Also a better error message 
should be given.


nothrow unfortunately doesn't help; i guess I'll file an issue.
thanks for your input


Re: range.put() to Empty Array Causes Error?

2018-06-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/17/18 7:07 AM, Vijay Nayar wrote:

This code breaks with the following error:
void main()
{
 import std.range;
   int[] vals = [];
 vals.put(3);
}
/src/phobos/std/range/primitives.d(2328): Attempting to fetch the front 
of an empty array of int


The following code has no error:
void main()
{
 import std.range;
   int[] vals = [1];
 vals.put(3);
}

Why is range.put() not allowed for empty arrays?




range.put fills an existing array like a buffer, it does not append (as 
I'm guessing you are expecting). Use std.array.Appender to get append 
behavior.


BTW, use put(vals, 3) instead of vals.put(3), as you may bypass the 
features of put.


-Steve


Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/17/18 6:58 AM, Cauterite wrote:

Hello,
I'm not sure whether I'm missing something obvious here, but is there a 
reason for scope(success) being lowered to a try-catch statement?
I would have expected only scope(exit) and scope(failure) to actually 
interact with exception handling, while scope(success) simply places 
code on the path of normal control flow.


Example (windows x32):

---

// main.d
void main() {
 scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---

Regardless of whether -betterC is used, you can see in the disassembly 
that having a scope(success) anywhere in the function causes the SEH 
prologue to be emitted in the code.


Is there a reason scope(success) needs to set up for exception handling?
Or is this a bug / potential enhancement ?


I think you are right, adding scope(success) should just add the 
statements to the end of the scope.


Here's what I think happens: Because scope(anything) needs to put things 
like this:


try
{
   normal code
   scope(success) code
} catch(Exception e) {
   scope(failure) code
   throw e;
} finally {
   scope(exit) code
}

so any time you use a scope statement, it has to set up this framework 
so it can have the correct place to put things (there may be 
scope(failure) or scope(exit) code later). But I think we can fix this.


-Steve


Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Timoses via Digitalmars-d-learn

On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote:

Hello,
I'm not sure whether I'm missing something obvious here, but is 
there a reason for scope(success) being lowered to a try-catch 
statement?
I would have expected only scope(exit) and scope(failure) to 
actually interact with exception handling, while scope(success) 
simply places code on the path of normal control flow.


Example (windows x32):

---

// main.d
void main() {
scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---

Regardless of whether -betterC is used, you can see in the 
disassembly that having a scope(success) anywhere in the 
function causes the SEH prologue to be emitted in the code.


Is there a reason scope(success) needs to set up for exception 
handling?

Or is this a bug / potential enhancement ?


In Andrei's book 'The D Programming Language' the following is 
written:


{

scope(success) 

}
is lowered to
{

bool __succeeded = true;
try {

} catch(Exception e) {
__succeeded = false;
throw e;
} finally {
if (__succeeded)  // vice-versa for 
scope(failure): `if (!__succeeded) ...`

}
}

If it weren't and it would simply be integrated one would have to 
write


potentiallyThrowingFunc();
scope(success) {...};

I suppose? And this seems like breaking how scope works with 
failure and exit?!


Re: How do you test whether a variable is static or not?

2018-06-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/16/18 6:23 PM, Jonathan M Davis wrote:

I kind of wish that the forum software discouraged against necro-ing threads
like this, since they're easy for many of us to miss, and once someone
replies to them and brings them to the front of the list in the forum
software, folks tends to reply as if the thread were recent without noticing
how old it is.


There is somewhat of a colorization of the date based on the age, but 
it's not drastic enough for ancient threads, and it's not as obvious as 
it would be if, say, the whole line was colored differently.


-Steve


Re: scope(success) lowered to try-catch ?

2018-06-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 17 June 2018 at 10:58:29 UTC, Cauterite wrote:

Hello,
I'm not sure whether I'm missing something obvious here, but is 
there a reason for scope(success) being lowered to a try-catch 
statement?
I would have expected only scope(exit) and scope(failure) to 
actually interact with exception handling, while scope(success) 
simply places code on the path of normal control flow.


Example (windows x32):

---

// main.d
void main() {
scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---

Regardless of whether -betterC is used, you can see in the 
disassembly that having a scope(success) anywhere in the 
function causes the SEH prologue to be emitted in the code.


Is there a reason scope(success) needs to set up for exception 
handling?

Or is this a bug / potential enhancement ?


I suspect scope(success) is lowered because scope(exit) and 
scope(failure)
are, and that would result in a simpler (compiler) implementation 
of it.


does adding nothrow to main fix it? For dcompute I specifically 
allow scope(exit|success) because there will never be any 
exceptions _at all_.


If not, please do submit an issue. Also a better error message 
should be given.


range.put() to Empty Array Causes Error?

2018-06-17 Thread Vijay Nayar via Digitalmars-d-learn

This code breaks with the following error:
void main()
{
import std.range;
int[] vals = [];
vals.put(3);
}
/src/phobos/std/range/primitives.d(2328): Attempting to fetch the 
front of an empty array of int


The following code has no error:
void main()
{
import std.range;
int[] vals = [1];
vals.put(3);
}

Why is range.put() not allowed for empty arrays?




scope(success) lowered to try-catch ?

2018-06-17 Thread Cauterite via Digitalmars-d-learn

Hello,
I'm not sure whether I'm missing something obvious here, but is 
there a reason for scope(success) being lowered to a try-catch 
statement?
I would have expected only scope(exit) and scope(failure) to 
actually interact with exception handling, while scope(success) 
simply places code on the path of normal control flow.


Example (windows x32):

---

// main.d
void main() {
scope(success) {}
}


dmd -betterC main.d

Error: Cannot use try-catch statements with -betterC

---

Regardless of whether -betterC is used, you can see in the 
disassembly that having a scope(success) anywhere in the function 
causes the SEH prologue to be emitted in the code.


Is there a reason scope(success) needs to set up for exception 
handling?

Or is this a bug / potential enhancement ?


Re: How to list all the manifest constants in a class or struct

2018-06-17 Thread Heromyth via Digitalmars-d-learn

On Sunday, 17 June 2018 at 04:32:29 UTC, Jonathan M Davis wrote:
On Sunday, June 17, 2018 02:44:38 Heromyth via 
Digitalmars-d-learn wrote:

Here is a struct named S:

struct S
{
  enum X = 10;
  enum Y
  {
i = 10
  }
  enum Z = "str";
  struct S {}
  class C {}

  static int sx = 0;
  __gshared int gx = 0;

 shared void g();
}

I want list all then the manifest constants in it.

I searched the std.traits and this forums, but get nothing. 
Maybe, my real question is how to get the storage class for a 
member in a class or struct.


As the storage class isn't part of the type, type introspection 
tends to ignore it. You'll basically have to get the full list 
of members of the type and then filter out stuff that isn't a 
manifest constant, which is not exactly pleasant and can get a 
bit tricky but should be possible. You'll probably have to do 
something like filter out all of the members where you can take 
their address and filter out all of the ones that are types, 
and and at that point, you'd be close, but I'd have to 
experiment to figure out whether that was enough or not or 
whether something crept through.


Andrei has been working on coming up with a better wrapper 
around the current introspection stuff so that you'll actually 
get data types which contain the information about a symbol 
rather than having to figure out which combination of __traits 
and traits from std.traits are required to get what you want. 
So, I expect that stuff like this will get a lot easier once 
that's ready, but in the interim, if you're trying to do 
something less common, it can involve having to do a lot clever 
filtering to get exactly the stuff you want and only the stuff 
you want - and I don't think that getting the list of manifest 
constants in a type is a very typical thing for folks to do, so 
std.traits certainly doesn't have anything like 
isManifestConstant.


- Jonathan M Davis


Thanks for your answers. It's so glad to see some works have been 
taken for this.


The isManifestConstant is really necessary. For example, I want 
to port an Enum type from Java to D. It seems better to use a 
Struct instead of an Enum.


See here:
https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java
https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java

Of course, I can define a enum for members with the basic types 
in D.
Sometimes, I like to define them in a class or struct as manifest 
constants or immutable ones. So, I need isManifestConstant.