Re: Passing struct to function

2018-06-13 Thread Michał via Digitalmars-d-learn
On Wednesday, 13 June 2018 at 17:37:44 UTC, Steven Schveighoffer 
wrote:


Hm... the only way to do it in D is to provide a function that 
checks whether the small vector optimization is in play, and 
return a pointer/slice to itself.


With D it is possible to alias the getter function that 
provides the actual data to allow code to look nicer.


For example (crude example):

struct Vector(T)
{
   bool svo; // small vector optimization
   union
   {
  T[4] local;
  T[] heap;
   }
   inout(T)[] get() inout { return svo ? local[], heap; }
   alias get this;
   ... // implement specialized append, concat operators, etc.
}

Now, you can use Vector as if it were an array, and it just 
works.


-Steve


Thanks for an idea, I will try it.


Re: Docs for subpackages?

2018-06-13 Thread 9il via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 14:56:10 UTC, 9il wrote:

Hi,

I am trying to build a large project that is split into dozen 
of sub-packages.

How I can do it using dub without writing my own doc scripts?
--combined does not help here.

Best regards,
Ilya


UPDATE: --combined works, but DDOX fails

std.json.JSONException@std/json.d(1394): Got JSON of type 
undefined, expected string.


4   ddox0x000107c667fa const 
pure @safe void 
vibe.data.json.Json.checkType!(immutable(char)[]).checkType(immutable(char)[]) + 278
5   ddox0x000107c666cb inout 
@property @trusted inout(immutable(char)[]) 
vibe.data.json.Json.get!(immutable(char)[]).get() + 31
6   ddox0x000107dba2bc 
ddox.entities.Declaration 
ddox.parsers.jsonparser.Parser.parseDecl(vibe.data.json.Json, 
ddox.entities.Entity) + 72
7   ddox0x000107dba106 int 
ddox.parsers.jsonparser.Parser.parseDeclList(vibe.data.json.Json, 
ddox.entities.Entity).__foreachbody3(ref vibe.data.json.Json) + 90
8   ddox0x000107fe1fd7 int 
vibe.data.json.Json.opApply(scope int delegate(ref 
vibe.data.json.Json)) + 159
9   ddox0x000107dba09a 
ddox.entities.Declaration[] 
ddox.parsers.jsonparser.Parser.parseDeclList(vibe.data.json.Json, 
ddox.entities.Entity) + 78
10  ddox0x000107dbb024 
ddox.entities.CompositeTypeDeclaration 
ddox.parsers.jsonparser.Parser.parseCompositeDecl(vibe.data.json.Json, ddox.entities.Entity) + 712
11  ddox0x000107dba520 
ddox.entities.Declaration 
ddox.parsers.jsonparser.Parser.parseDecl(vibe.data.json.Json, 
ddox.entities.Entity) + 684
12  ddox0x000107dba106 int 
ddox.parsers.jsonparser.Parser.parseDeclList(vibe.data.json.Json, 
ddox.entities.Entity).__foreachbody3(ref vibe.data.json.Json) + 90
13  ddox0x000107fe1fd7 int 
vibe.data.json.Json.opApply(scope int delegate(ref 
vibe.data.json.Json)) + 159
14  ddox0x000107dba09a 
ddox.entities.Declaration[] 
ddox.parsers.jsonparser.Parser.parseDeclList(vibe.data.json.Json, 
ddox.entities.Entity) + 78
15  ddox0x000107db8ef3 void 
ddox.parsers.jsonparser.Parser.parseModuleDecls(vibe.data.json.Json, ddox.entities.Package) + 583
16  ddox0x000107db8c9f int 
ddox.parsers.jsonparser.parseJsonDocs(vibe.data.json.Json, 
ddox.entities.Package).__foreachbody3(ref vibe.data.json.Json) + 
91
17  ddox0x000107fe1fd7 int 
vibe.data.json.Json.opApply(scope int delegate(ref 
vibe.data.json.Json)) + 159
18  ddox0x000107db8c2d 
ddox.entities.Package 
ddox.parsers.jsonparser.parseJsonDocs(vibe.data.json.Json, 
ddox.entities.Package) + 89
19  ddox0x000107d9d53c 
ddox.entities.Package ddox.main.parseDocFile(immutable(char)[], 
ddox.settings.DdoxSettings) + 168
20  ddox0x000107d9c1ad int 
ddox.main.setupGeneratorInput(ref immutable(char)[][], out 
ddox.settings.GeneratorSettings, out ddox.entities.Package) + 777
21  ddox0x000107d9bab6 int 
ddox.main.cmdGenerateHtml(immutable(char)[][]) + 42
22  ddox0x000107d9b945 int 
ddox.main.ddoxMain(immutable(char)[][]) + 201
23  ddox0x000107c617bf _Dmain 
+ 31
24  ddox0x00010800d037 void 
rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll().__lambda1() + 39
25  ddox0x00010800cec7 void 
rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) + 31
26  ddox0x00010800cfa2 void 
rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll() + 138
27  ddox0x00010800cec7 void 
rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) + 31
28  ddox0x00010800ce35 
_d_run_main + 485
29  ddox0x000107c617e9 main + 
33
30  libdyld.dylib   0x7fff7d479014 start 
+ 0

31  ??? 0x0004 0x0 + 4


InputRange help: (1) repeated dtor calls and (2) managing resources needing free()

2018-06-13 Thread James Blachly via Digitalmars-d-learn

Hi all,

I now really appreciate the power Ranges provide and am an avid 
consumer, but am only slowly becoming accustomed to implementing 
my own.


In the present problem, I am writing a binding to a C library 
(htslib) that provides many functions related to high-throughput 
sequencing files. One of these functions is for rapid indexed 
lookup into multi-GB files. The library provides a handle to an 
iterator which must be supplied to a "get next matching row" type 
function, which overall seems perfect for implementation as a 
range.  You can see my naive implementation here:


https://github.com/blachlylab/dhtslib/blob/master/source/dhtslib/tabix.d

Note that TabixIndexedFile::region returns an InputRange; in the 
original implementation, this Range preloaded the first record 
(the ctor called popFirst()), but ultimately I realized this was 
not workable because copies of the object would always be 
non-empty. In some ways, this problem is generalizable to all 
InputRanges that represent a file or record stream.



My problems now are at least twofold.

1. If I use the range, the destructor seems to be called many, 
many times. This is directly related to problem 2, below, but I 
would be interested to understand why this is happening 
generally. For example, see:

https://github.com/blachlylab/dhtslib/blob/master/test/tabix_gffreader.d
Here, when I create the range but do not consume it, the ctor and 
dtor are called once each, as expected. However, if I 
foreach(line; r) { } the destructor is called twice. If I reason 
through this, it is because use of the range created a copy to 
consume. (?) However, if instead, I writeln( r ), the destructor 
is called *five* times. I cannot understand the reason for this, 
unless it is black magic required by writeln().


I assume the (apparent) lack of parity between ctor and dtor is 
because the "default postblit" (which I figured out for a struct 
means an empty `this(this)` ctor) is called when a copy is made. 
My understanding is that I cannot disable the default postblit 
and still act as a range, correct? Should I be overloading this?


2. Directly related to the above, I need, when the range is 
consumed, to free() the underlying library's iterator handle. 
Naively, I had the destructor do this, but obviously with 
multiple calls to ~this I end up with an error free()'ing a 
pointer that is no longer alloc'd.  What is the correct way to 
handle this situation in D?


Other Range and destructor advice generally (e.g., "You should 
totally change your design or approach to X instead") is always 
welcomed.


James


Re: Which character set does D use?

2018-06-13 Thread Uknown via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 23:34:02 UTC, Murilo wrote:
Does D use ASCII or UNICODE? It seems to use ASCII since it 
causes error whenever I use a non-ASCII character.


Your system might be misconfigured. D can use UTF-8 (Unicode) 
too. See https://dlang.org/spec/lex.html#source_text


Which character set does D use?

2018-06-13 Thread Murilo via Digitalmars-d-learn
Does D use ASCII or UNICODE? It seems to use ASCII since it 
causes error whenever I use a non-ASCII character.


Re: Class qualifier vs struct qualifier

2018-06-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, June 13, 2018 14:33:48 Jonathan M Davis via Digitalmars-d-
learn wrote:
> On Wednesday, June 13, 2018 07:35:25 RazvanN via Digitalmars-d-learn 
wrote:
> > Hello,
> >
> > I'm having a hard time understanding whether this inconsistency
> > is a bug or intended behavior:
> >
> > immutable class Foo {}
> > immutable struct Bar {}
> >
> > void main()
> > {
> >
> >  import std.stdio : writeln;
> >  Foo a;
> >  Bar b;
> >
> >  writeln("typeof(a): ", typeof(a).stringof);
> >  writeln("typeof(b): ", typeof(b).stringof);
> >
> > }
> >
> > prints:
> >
> > typeof(Foo): Foo
> > typeof(Bar): immutable(Bar)
> >
> >
> > It seems like the class storage class is not taken into account
> > which leads to some awkward situations like:
> >
> > immutable class Foo
> > {
> >
> >  this() {}
> >
> > }
> >
> > void main()
> > {
> >
> >  Foo a = new Foo(); // error: immutable method `this` is not
> >
> > callable using a
> >
> > // mutable object
> >
> > }
> >
> > To make it work I have to add immutable to both sides of the
> > expression : immutable Foo a = new immutable Foo(); this is a
> > wonder of redundancy. I already declared the class as immutable
> > so it shouldn't be possible to have mutable instances of it (and
> > it isn't), however I am forced to write the immutable twice even
> > though it is pretty obvious that the class cannot be mutated.
>
> Honestly, from what I understand of how this works, what I find weird is
> the struct case. immutable on classes does _not_ make the class itself
> immutable. It just makes all of its members immutable - hence the error
> about trying to allocate new Foo instead of new immutable Foo. So, that
> is exactly what I would expect. And honestly, being able to write Foo and
> have it imply immutable Foo would get _really_ confusing when reading and
> debugging code.
>
> What's bizarre is that marking the struct with immutable would affect
> anything other than its members.
>
> Bar b;
>
> should not claim that typeof(b) is immutable(Bar). b was not marked as
> immutable. It was listed as Bar, not immutable Bar. So, b shouldn't be
> immutable.

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

- Jonathan M Davis



Re: Class qualifier vs struct qualifier

2018-06-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, June 13, 2018 07:35:25 RazvanN via Digitalmars-d-learn wrote:
> Hello,
>
> I'm having a hard time understanding whether this inconsistency
> is a bug or intended behavior:
>
> immutable class Foo {}
> immutable struct Bar {}
>
> void main()
> {
>  import std.stdio : writeln;
>  Foo a;
>  Bar b;
>
>  writeln("typeof(a): ", typeof(a).stringof);
>  writeln("typeof(b): ", typeof(b).stringof);
> }
>
> prints:
>
> typeof(Foo): Foo
> typeof(Bar): immutable(Bar)
>
>
> It seems like the class storage class is not taken into account
> which leads to some awkward situations like:
>
> immutable class Foo
> {
>  this() {}
> }
>
> void main()
> {
>  Foo a = new Foo(); // error: immutable method `this` is not
> callable using a
> // mutable object
> }
>
> To make it work I have to add immutable to both sides of the
> expression : immutable Foo a = new immutable Foo(); this is a
> wonder of redundancy. I already declared the class as immutable
> so it shouldn't be possible to have mutable instances of it (and
> it isn't), however I am forced to write the immutable twice even
> though it is pretty obvious that the class cannot be mutated.

Honestly, from what I understand of how this works, what I find weird is the
struct case. immutable on classes does _not_ make the class itself
immutable. It just makes all of its members immutable - hence the error
about trying to allocate new Foo instead of new immutable Foo. So, that is
exactly what I would expect. And honestly, being able to write Foo and have
it imply immutable Foo would get _really_ confusing when reading and
debugging code.

What's bizarre is that marking the struct with immutable would affect
anything other than its members.

Bar b;

should not claim that typeof(b) is immutable(Bar). b was not marked as
immutable. It was listed as Bar, not immutable Bar. So, b shouldn't be
immutable.

- Jonathan M Davis



Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-13 Thread concepthf via Digitalmars-d-learn

On Friday, 8 June 2018 at 08:21:39 UTC, evilrat wrote:

On Friday, 8 June 2018 at 08:06:27 UTC, Arafel wrote:

On Thursday, 7 June 2018 at 13:07:21 UTC, evilrat wrote:


I don't think so. It clearly states that children must mixin 
too, which can mean it just grabs symbols in scope only, and 
base class has no way of knowing about its subclasses. It 
also has "agressive mode" that will make metadata for all 
public symbols(?) it can walk, this may or may not be helpful 
depending on your requirements.




Yes, that's what I understood from looking at it, but perhaps 
I was just missing something. I wonder though how the 
"agressive mode" would work with separate compilation / 
dlopen'ed libraries. Perhaps I should give it a try and see 
what happens.


Besides there is no way(not that I am aware of) to make self 
registering stuff happen, you still need to call it 
somewhere. The most transparent option is probably just doing 
a mixin in each module that performs registration of all 
module symbols in module ctor.
The point is that there is absolute requirement to make 
explicit call for that, be it a module ctor mixin, class 
mixin or even user provided registration both at compile time 
or run time.
But since it is MIT licensed you can probably use the code as 
the starting point and adjust to your own needs.




BTW plug-ins is something that is right now possible on 
Linux(not sure about support on other *NIX systems), but in a 
very primitive form on Windows.
This is related to DLL support issues(such as type 
information not being passed across process/DLL boundaries), 
these issues also may include runtime issues as well such as 
inability to delegate the GC, which will mean there will be 
2(or more) concurrent running GC's. But again I am not aware 
of the current situation.


Well, I'm already tightly coupled to linux, so this is not a 
big concern for me :-)


I'll keep trying, as I said, my intention was to let plugin 
writers do it as easily as possible, but well, adding some 
kind of "register" function might be necessary in the end...


A.


Yep. Like I said probably the easiest to use way is to place 
single call in each module. And there probably no other 
solution, because modules creates sort of isolated graph via 
imports. And I am not aware of any way to get list of modules 
passed in with compiler invocation to perform some sort of 
centralized one-liner registration.


But anyway look at this, might give some tips on how it can be 
done


mixin
https://github.com/Circular-Studios/Dash/blob/b7d589ad4ca8993445c136b6a4ae170932bb7962/source/dash/components/component.d#L208



(note that it uses static this() - module constructor. I think 
this behavior was changed around 2015-2016 and now it will 
cause cyclic dependency errors when modules with ctors import 
each other)


usage
https://github.com/Circular-Studios/Dash/blob/b7d589ad4ca8993445c136b6a4ae170932bb7962/source/dash/components/lights.d#L12


Thanks very much for these links!

I'm currently also trying to get a crack at runtime introspection 
for enabling richer serialization capabilities. It is nice to 
have compile time code generation, but it really sucks when 
dealing with object hierarchies and API interfaces.


I'm doing kind of the same thing as witchcraft with explicit 
mixins (putting a "mixin reflect" into every stuff I want to 
reflect on.)
But I'd like to have selective reflection/introspection, with a 
C#-esque flavor of having a "centralised repository" of reflected 
stuff.



Also I need to inject static this(). A serious drawback.

On that note, you can pass:
--DRT-oncycle=ignore

to your compiled app to instruct the runtime to ignore cycle 
warnings.

linux ex.: "./app --DRT-oncycle=ignore"

It is ugly as hell to disable this check, but I would accept it 
gladly if this would be the only impediment of getting runtime 
reflection.


Sadly it is not, and I don't want to ramble right now :)



Re: What is the point of nothrow?

2018-06-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, June 13, 2018 10:56:41 wjoe via Digitalmars-d-learn wrote:
> On Wednesday, 13 June 2018 at 03:14:33 UTC, Jonathan M Davis
>
> wrote:
> > Most programs do not handle the case where they run out of
> > memory and cannot continue at that point. For better or worse,
> > D's GC was designed with that in mind, and it treats failed
> > allocations as an Error. In the vast majority of cases, this is
> > desirable behavior. In those cases when it isn't, alternate
> > memory allocation schemes such as malloc can be used. But
>
> But manual memory management sucks and is a huge waste of
> everyone's time and I was hoping to get the best from both worlds
>
> :)
> :

Well, I think that the reality of the matter is that the number of programs
that even attempt to recover from not having enough memory is extremely
small such that you're dealing with a very niche case if you're going to try
it, and if the GC fails to allocate more memory for you, your options are
typically pretty limited. So, even if the GC provided a way to allocate
memory that returned null on failure instead of throwing an Error, I don't
know that it would do you a lot of good, but regardless, the GC was not
designed with that in mind, and even GC.malloc throws OutOfMemoryError on
allocation failure rather than null. So, there isn't much choice on the
matter.

> > regardless of whether the decision to treat failed memory
> > allocations as an Error was a good one or not, the fact remains
> > that as soon as an Error is thrown, you lose the ability to
> > deal with things cleanly, because full clean up is not done
> > when an Error is thrown (and can't be due to things like how
> > nothrow works). So, regardless of whether a failed memory
> > allocation is a condition that can be recovered from in
> > principle, the way that D handles GC allocations make it
> > unrecoverable in practice - at least as far as GC-allocated
> > memory is concerned.
>
> Did I get that right?
> You say when an error is thrown destructors, scope statements,
> etc. are not executed - if declared as nothrow because the
> exception handler mechanism stuff is missing, is that correct?
> And it does execute if not declared as nothrow but can't be
> relied upon because some other  nothrow functions could have
> omitted some of those statements?

Yes, and there's no guarantee that clean-up will occur even if nothing is
nothrow. While the current implementation will do clean-up in those cases,
it didn't used to, and Walter has repeatedly stated that it is not
guaranteed to do so. Errors are _not_ intended to be caught and recovered
from. They're essentially a segfault that prints a message and stack trace
but which for some reason uses the exception throwing mechanism to get to
the code that prints the message and exits the program.

> So I shoot myself in the foot with nothrow and if I don't use it
> I'm still in a world of hurt?
>
> I understand the idea that an Error is not supposed to be caught
> but why would such a 'feature' be desirable? Where's the benefit
> if nothing can be relied upon ?
>
> If all errors would be treated like an exception, the developer
> could decide whether it is an error which needs to terminate
> right away or be able to handle the issue and continue or
> gracefully shutdown.

The idea is that because your program is in an invalid state, attempting a
graceful shutdown is unsafe. But regardless of whether you agree with that,
the fact that nothrow doesn't do clean-up pretty much ensures that it isn't
safe in the general case, and nothrow can't do clean-up without negating one
of the main reasons that it exists in the first place - which is to improve
performance by not emitting exception-handling code.

> Could even set a break point or force a core
> dump right there.

The fact that Errors don't immediately kill the program and instead sort of
unwind the stack is a definite problem for getting good debug information on
crashes. I suspect that Walter doesn't quite understand the issues here,
because whenever anyone raises issues related to stuff like this, he has a
tendancy to basically tell people to rerun their program - which works
fantastically in the world he typically programs in (compilers) but doesn't
work very well with stuff like OSes or server programs where you frequently
have no clue how to replicate the problem. My guess is that Errors work they
do in part because he's not used to debugging situations where a coredump
being created at the point of failure the first time it happens (rather than
during attempts to reproduce the problem) is what you really need.

I think that the reasons that this is not a bigger problem than it is stem
primarily from the fact that Errors are going to be very rare in production
code unless it wasn't properly tested. So, the problem shouldn't pop up
often. However, when it does, having a coredump at the site of the failure
would definitely be valuable.

> If the exception would be ignored the 

Re: Passing struct to function

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

On 6/13/18 1:08 PM, Michał wrote:

On Wednesday, 13 June 2018 at 16:40:51 UTC, Steven Schveighoffer wrote:

On 6/13/18 10:43 AM, Michał wrote:
When I pass my struct to function something is going wrong. I don't 
know how to fix it.


Code:
import std.stdio;


void print(ref Vector v, string s){
 writefln("%s==%s    %s", , v.ptr, s);
}

struct Vector {
 int x;
 int* ptr;

 this(this) {
 ptr = 
 print(this, "postblit");
 }
}

void someFunc(Vector t) {
 print(t, "in someFunc");
}

void main() {
 auto tmpA = Vector();
 tmpA.ptr = 
 print(tmpA, "start");

 someFunc(tmpA);
}


Result on my machine:
7FFF7D70BC00==7FFF7D70BC00    start
7FFF7D70BBF0==7FFF7D70BBF0    postblit
7FFF7D70BBD0==7FFF7D70BBF0    in someFunc

In the last line pointers are not matching. I thought that postblit 
will do the thing but it is not the case. How to make 'ptr' to be 
null or '' all the time?


D allows moving any struct instance without calling postblit, as long 
as the original is no longer used.


The optimizer is likely seeing here that the memory can be copied 
without calling postblit, because nobody is using tmpA after the call.


In general, you should NOT store an internal pointer in a struct, 
unless you allocate it on the heap.


-Steve



I need internal pointer because I want to implement vector(like in C++) 
with 'small vector optimization', when i have internal pointer it is 
very easy and functions like 'add' don't have additional checks.


If storing internal pointers is forbidden do you know some way to 
implement 'small vector optimization' without additional checks in 'add' 
function?


Hm... the only way to do it in D is to provide a function that checks 
whether the small vector optimization is in play, and return a 
pointer/slice to itself.


With D it is possible to alias the getter function that provides the 
actual data to allow code to look nicer.


For example (crude example):

struct Vector(T)
{
   bool svo; // small vector optimization
   union
   {
  T[4] local;
  T[] heap;
   }
   inout(T)[] get() inout { return svo ? local[], heap; }
   alias get this;
   ... // implement specialized append, concat operators, etc.
}

Now, you can use Vector as if it were an array, and it just works.

-Steve


Re: Passing struct to function

2018-06-13 Thread Michał via Digitalmars-d-learn
On Wednesday, 13 June 2018 at 16:40:51 UTC, Steven Schveighoffer 
wrote:

On 6/13/18 10:43 AM, Michał wrote:
When I pass my struct to function something is going wrong. I 
don't know how to fix it.


Code:
import std.stdio;


void print(ref Vector v, string s){
     writefln("%s==%s    %s", , v.ptr, s);
}

struct Vector {
 int x;
 int* ptr;

 this(this) {
     ptr = 
     print(this, "postblit");
 }
}

void someFunc(Vector t) {
 print(t, "in someFunc");
}

void main() {
 auto tmpA = Vector();
 tmpA.ptr = 
 print(tmpA, "start");

 someFunc(tmpA);
}


Result on my machine:
7FFF7D70BC00==7FFF7D70BC00    start
7FFF7D70BBF0==7FFF7D70BBF0    postblit
7FFF7D70BBD0==7FFF7D70BBF0    in someFunc

In the last line pointers are not matching. I thought that 
postblit will do the thing but it is not the case. How to make 
'ptr' to be null or '' all the time?


D allows moving any struct instance without calling postblit, 
as long as the original is no longer used.


The optimizer is likely seeing here that the memory can be 
copied without calling postblit, because nobody is using tmpA 
after the call.


In general, you should NOT store an internal pointer in a 
struct, unless you allocate it on the heap.


-Steve



I need internal pointer because I want to implement vector(like 
in C++) with 'small vector optimization', when i have internal 
pointer it is very easy and functions like 'add' don't have 
additional checks.


If storing internal pointers is forbidden do you know some way to 
implement 'small vector optimization' without additional checks 
in 'add' function?


Re: What is the point of nothrow?

2018-06-13 Thread wjoe via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 13:05:44 UTC, Kagamin wrote:

On Wednesday, 13 June 2018 at 10:56:41 UTC, wjoe wrote:
I understand the idea that an Error is not supposed to be 
caught but why would such a 'feature' be desirable? Where's 
the benefit if nothing can be relied upon ?


It's a debugging facility for development stage that allows to 
print the error message and stack trace instead of silent 
termination. Because it still needs to be caught for this, 
explicit catch still works, but other cleanup mechanisms don't.


My question was more like what's the benefit of having thrown 
Errors corrupt your program state  rendering it useless for 
debugging ?


Re: What is the point of nothrow?

2018-06-13 Thread wjoe via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 12:59:27 UTC, Kagamin wrote:

On Wednesday, 13 June 2018 at 02:02:54 UTC, wjoe wrote:
it is possible to install a signal handler for almost every 
signal on POSIX, including segfault. The only signal you can't 
catch is signal 9 - sigkill if memory serves.
So I could for instance install a clean up handler on a 
segfault via memset, or a for loop, and then terminate.


What will you do with this? 
https://github.com/dlang/druntime/blob/master/src/core/internal/abort.d


Are you asking what I would do in case sigabrt is received by my 
program instead of sigsegv ?


I would install the same cleanup functionality in this handler. 
Zero out memory, send a signal to stop an engine or whatever 
mandatory clean up is required and return from the handler. Then 
let the OS take care of the rest, i.e. terminate the process.


Re: Passing struct to function

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

On 6/13/18 10:43 AM, Michał wrote:
When I pass my struct to function something is going wrong. I don't know 
how to fix it.


Code:
import std.stdio;


void print(ref Vector v, string s){
     writefln("%s==%s    %s", , v.ptr, s);
}

struct Vector {
 int x;
 int* ptr;

 this(this) {
     ptr = 
     print(this, "postblit");
 }
}

void someFunc(Vector t) {
 print(t, "in someFunc");
}

void main() {
 auto tmpA = Vector();
 tmpA.ptr = 
 print(tmpA, "start");

 someFunc(tmpA);
}


Result on my machine:
7FFF7D70BC00==7FFF7D70BC00    start
7FFF7D70BBF0==7FFF7D70BBF0    postblit
7FFF7D70BBD0==7FFF7D70BBF0    in someFunc

In the last line pointers are not matching. I thought that postblit will 
do the thing but it is not the case. How to make 'ptr' to be null or 
'' all the time?


D allows moving any struct instance without calling postblit, as long as 
the original is no longer used.


The optimizer is likely seeing here that the memory can be copied 
without calling postblit, because nobody is using tmpA after the call.


In general, you should NOT store an internal pointer in a struct, unless 
you allocate it on the heap.


-Steve


Re: What is the point of nothrow?

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

On 6/13/18 8:44 AM, Kagamin wrote:

On Tuesday, 12 June 2018 at 14:15:42 UTC, Steven Schveighoffer wrote:
I predict at some point when Errors actually don't do proper cleanup, 
it is going to be a really difficult time for D.


Looks like it already doesn't: https://run.dlang.io/is/OhDwtW


Damn, that's interesting. And it's been that way since 2.061!

So much for my shitty predictions :)

BTW, Seb, I edited this to change it to Exception to see what happens, 
and then I wanted to re-run the original, so I closed it and re-clicked 
on the link, and it brought up my EDITED code. I had to clear the 
cookies on run.dlang.io from my browser to get it to restore. This is 
quite annoying, can it be fixed?


-Steve


Re: implicit or module-wide @nogc

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

On 6/13/18 3:24 AM, Mike Franklin wrote:

Because D is more evolution then intelligent design, unfortunately.


I had to LOL on this, nice :)

-Steve



Re: Class qualifier vs struct qualifier

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

On 6/13/18 3:35 AM, RazvanN wrote:

Hello,

I'm having a hard time understanding whether this inconsistency is a bug 
or intended behavior:


immutable class Foo {}
immutable struct Bar {}

void main()
{
     import std.stdio : writeln;
     Foo a;
     Bar b;

     writeln("typeof(a): ", typeof(a).stringof);
     writeln("typeof(b): ", typeof(b).stringof);
}

prints:

typeof(Foo): Foo
typeof(Bar): immutable(Bar)


It seems like the class storage class is not taken into account which 
leads to some awkward situations like:


immutable class Foo
{
     this() {}
}

void main()
{
     Foo a = new Foo(); // error: immutable method `this` is not 
callable using a

    // mutable object
}

To make it work I have to add immutable to both sides of the expression 
: immutable Foo a = new immutable Foo(); this is a wonder of redundancy. 
I already declared the class as immutable so it shouldn't be possible to 
have mutable instances of it (and it isn't), however I am forced to 
write the immutable twice even though it is pretty obvious that the 
class cannot be mutated.


Just on the principle of least surprise, I'd call this a bug. I don't 
know what the intention is, but if the intention is for this behavior, 
we should re-visit.


-Steve


Re: remove not callable for char[]

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

On 6/13/18 1:18 AM, Flaze07 wrote:

I see, so it means that only char is affected, gotcha



Well, char[] and wchar[]. dchar[] is treated as an array by Phobos. But 
calling byCodeUnit on a dchar array should work just like an array as 
well, so using it is the most generic solution.


-Steve


Docs for subpackages?

2018-06-13 Thread 9il via Digitalmars-d-learn

Hi,

I am trying to build a large project that is split into dozen of 
sub-packages.

How I can do it using dub without writing my own doc scripts?
--combined does not help here.

Best regards,
Ilya


Passing struct to function

2018-06-13 Thread Michał via Digitalmars-d-learn
When I pass my struct to function something is going wrong. I 
don't know how to fix it.


Code:
import std.stdio;


void print(ref Vector v, string s){
writefln("%s==%s%s", , v.ptr, s);
}

struct Vector {
int x;
int* ptr;

this(this) {
ptr = 
print(this, "postblit");
}
}

void someFunc(Vector t) {
print(t, "in someFunc");
}

void main() {
auto tmpA = Vector();
tmpA.ptr = 
print(tmpA, "start");

someFunc(tmpA);
}


Result on my machine:
7FFF7D70BC00==7FFF7D70BC00start
7FFF7D70BBF0==7FFF7D70BBF0postblit
7FFF7D70BBD0==7FFF7D70BBF0in someFunc

In the last line pointers are not matching. I thought that 
postblit will do the thing but it is not the case. How to make 
'ptr' to be null or '' all the time?


Re: What is the point of nothrow?

2018-06-13 Thread Kagamin via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 10:56:41 UTC, wjoe wrote:
I understand the idea that an Error is not supposed to be 
caught but why would such a 'feature' be desirable? Where's the 
benefit if nothing can be relied upon ?


It's a debugging facility for development stage that allows to 
print the error message and stack trace instead of silent 
termination. Because it still needs to be caught for this, 
explicit catch still works, but other cleanup mechanisms don't.


Re: What is the point of nothrow?

2018-06-13 Thread Kagamin via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 02:02:54 UTC, wjoe wrote:
it is possible to install a signal handler for almost every 
signal on POSIX, including segfault. The only signal you can't 
catch is signal 9 - sigkill if memory serves.
So I could for instance install a clean up handler on a 
segfault via memset, or a for loop, and then terminate.


What will you do with this? 
https://github.com/dlang/druntime/blob/master/src/core/internal/abort.d


Re: What is the point of nothrow?

2018-06-13 Thread Kagamin via Digitalmars-d-learn
On Tuesday, 12 June 2018 at 14:15:42 UTC, Steven Schveighoffer 
wrote:
I predict at some point when Errors actually don't do proper 
cleanup, it is going to be a really difficult time for D.


Looks like it already doesn't: https://run.dlang.io/is/OhDwtW


Re: Pass arguments at compile time

2018-06-13 Thread bauss via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 10:57:27 UTC, Malte wrote:
I want to import a config file at compile time, but also need a 
way to have multiple configurations.


With gcc you could do something like 
-DIMPORTFROM='"MyConfigFile.txt"'. Is there any equivalent in D?


Hardcoding the config files for different versions and using 
that is not an option. Requiring a fixed filename and using 
different paths to configure with -J wouldn't be a good 
solution for my specific situation either.


So far my best idea was to write the wanted filename to a file 
and import twice.

enum config = import(import("importFrom.txt"));

That works, but that is additional work for the build script 
and feels like a hack.


If you're using dub just specify "stringImportPath" as a folder 
to the configuration files.


You can't retrieve the files though, so you'd need to know the 
names of the files you want to use.


However if they're located in the path then you can just do enum 
config = import("MyconfigFile.txt");


Pass arguments at compile time

2018-06-13 Thread Malte via Digitalmars-d-learn
I want to import a config file at compile time, but also need a 
way to have multiple configurations.


With gcc you could do something like 
-DIMPORTFROM='"MyConfigFile.txt"'. Is there any equivalent in D?


Hardcoding the config files for different versions and using that 
is not an option. Requiring a fixed filename and using different 
paths to configure with -J wouldn't be a good solution for my 
specific situation either.


So far my best idea was to write the wanted filename to a file 
and import twice.

enum config = import(import("importFrom.txt"));

That works, but that is additional work for the build script and 
feels like a hack.


Re: What is the point of nothrow?

2018-06-13 Thread wjoe via Digitalmars-d-learn
On Wednesday, 13 June 2018 at 03:14:33 UTC, Jonathan M Davis 
wrote:
Most programs do not handle the case where they run out of 
memory and cannot continue at that point. For better or worse, 
D's GC was designed with that in mind, and it treats failed 
allocations as an Error. In the vast majority of cases, this is 
desirable behavior. In those cases when it isn't, alternate 
memory allocation schemes such as malloc can be used. But


But manual memory management sucks and is a huge waste of 
everyone's time and I was hoping to get the best from both worlds 
:)


regardless of whether the decision to treat failed memory 
allocations as an Error was a good one or not, the fact remains 
that as soon as an Error is thrown, you lose the ability to 
deal with things cleanly, because full clean up is not done 
when an Error is thrown (and can't be due to things like how 
nothrow works). So, regardless of whether a failed memory 
allocation is a condition that can be recovered from in 
principle, the way that D handles GC allocations make it 
unrecoverable in practice - at least as far as GC-allocated 
memory is concerned.




Did I get that right?
You say when an error is thrown destructors, scope statements, 
etc. are not executed - if declared as nothrow because the 
exception handler mechanism stuff is missing, is that correct?
And it does execute if not declared as nothrow but can't be 
relied upon because some other  nothrow functions could have 
omitted some of those statements?


So I shoot myself in the foot with nothrow and if I don't use it 
I'm still in a world of hurt?


I understand the idea that an Error is not supposed to be caught 
but why would such a 'feature' be desirable? Where's the benefit 
if nothing can be relied upon ?


If all errors would be treated like an exception, the developer 
could decide whether it is an error which needs to terminate 
right away or be able to handle the issue and continue or 
gracefully shutdown. Could even set a break point or force a core 
dump right there.
If the exception would be ignored the program will crash 
regardless but at least there would be a stack trace that I could 
rely upon instead of this unreliable and possibly corrupt state 
which is good for nothing.


This concept is a bit like color everyone with the same brush or 
one shoe fits all. Where in reality it depends on the 
circumstances whether it is an error or an exception.
But maybe I feel that way because currently there's a bit of a 
blur regarding what's defined as Errors and Exceptions.


Anyways I took a lot from your awesome explanations so far. 
Thanks a ton!


Class qualifier vs struct qualifier

2018-06-13 Thread RazvanN via Digitalmars-d-learn

Hello,

I'm having a hard time understanding whether this inconsistency 
is a bug or intended behavior:


immutable class Foo {}
immutable struct Bar {}

void main()
{
import std.stdio : writeln;
Foo a;
Bar b;

writeln("typeof(a): ", typeof(a).stringof);
writeln("typeof(b): ", typeof(b).stringof);
}

prints:

typeof(Foo): Foo
typeof(Bar): immutable(Bar)


It seems like the class storage class is not taken into account 
which leads to some awkward situations like:


immutable class Foo
{
this() {}
}

void main()
{
Foo a = new Foo(); // error: immutable method `this` is not 
callable using a

   // mutable object
}

To make it work I have to add immutable to both sides of the 
expression : immutable Foo a = new immutable Foo(); this is a 
wonder of redundancy. I already declared the class as immutable 
so it shouldn't be possible to have mutable instances of it (and 
it isn't), however I am forced to write the immutable twice even 
though it is pretty obvious that the class cannot be mutated.


Re: implicit or module-wide @nogc

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

On Wednesday, 13 June 2018 at 07:19:24 UTC, Gokhhy wrote:

Nevermind, it doesn't affect functions inside classes and 
structs.


Yeah, that's kindof unfortunate isn't it.  Just do the same thing 
within the class/struct scope.


class C {
   @nogc:

   void nogcMethod1() {}
   void nogcMehtod2() {}
}

I would be interested in what influenced the design decision to 
make opting out of garbage collection so difficult.


Because D is more evolution then intelligent design, 
unfortunately.


Mike



Re: implicit or module-wide @nogc

2018-06-13 Thread Gokhhy via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 07:14:35 UTC, Gokhhy wrote:

On Wednesday, 13 June 2018 at 07:11:56 UTC, Mike Franklin wrote:

On Wednesday, 13 June 2018 at 06:45:27 UTC, Gokhhy wrote:
Is there a way to define an entire module as @nogc or 
otherwise make it so I don't have to qualify every single 
function as @nogc?


You can put attributes at the top of a module followed by a 
":" to have them apply to everything below them.


module mymodule;

@nogc:

void nogcFunction1() { }

void nogcFunction2() { }

Mike


Thanks, just what I was looking for.


Nevermind, it doesn't affect functions inside classes and structs.

I would be interested in what influenced the design decision to 
make opting out of garbage collection so difficult.


Re: implicit or module-wide @nogc

2018-06-13 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 06:45:27 UTC, Gokhhy wrote:
Is there a way to define an entire module as @nogc or otherwise 
make it so I don't have to qualify every single function as 
@nogc?


---
module module_wide-nogc;

@nogc:

/*
declarations or statements...
*/
---

But this is not considered as a good practice.
1. One can work on the module and miss the global nogc
2. unittest are affected (array literals for example must be 
declared static immutable)

3. it cannot be temporarily canceled.

It depends on the context too. 200 slocs module or 5000 sloc 
module ? for a small one this could be ok.


Re: implicit or module-wide @nogc

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

On Wednesday, 13 June 2018 at 06:45:27 UTC, Gokhhy wrote:
Is there a way to define an entire module as @nogc or otherwise 
make it so I don't have to qualify every single function as 
@nogc?


You can put attributes at the top of a module followed by a ":" 
to have them apply to everything below them.


module mymodule;

@nogc:

void nogcFunction1() { }

void nogcFunction2() { }

Mike


Re: implicit or module-wide @nogc

2018-06-13 Thread Gokhhy via Digitalmars-d-learn

On Wednesday, 13 June 2018 at 07:11:56 UTC, Mike Franklin wrote:

On Wednesday, 13 June 2018 at 06:45:27 UTC, Gokhhy wrote:
Is there a way to define an entire module as @nogc or 
otherwise make it so I don't have to qualify every single 
function as @nogc?


You can put attributes at the top of a module followed by a ":" 
to have them apply to everything below them.


module mymodule;

@nogc:

void nogcFunction1() { }

void nogcFunction2() { }

Mike


Thanks, just what I was looking for.


implicit or module-wide @nogc

2018-06-13 Thread Gokhhy via Digitalmars-d-learn
Is there a way to define an entire module as @nogc or otherwise 
make it so I don't have to qualify every single function as @nogc?