Re: Is it possible to call a delegate at compile time?

2017-06-22 Thread Andrew Edwards via Digitalmars-d-learn

On Friday, 23 June 2017 at 04:58:07 UTC, ketmar wrote:

Andrew Edwards wrote:

so no, even if you'll remove `ref`, it will not work. sorry.


Okay, got it. Much appreciated.


Re: Is it possible to call a delegate at compile time?

2017-06-22 Thread ketmar via Digitalmars-d-learn

Andrew Edwards wrote:

I desire to call foo() at compile...  As implemented it does not happen, 
but it's not immediately clear what I am missing. Or is this simply not 
possible as yet? What is the proper way to redesign this template so that 
it will execute at compile time?


there are two caveats. the first is `ref` in Args: that won't work for 
arguments in CTFE (it works for nested functions, though).


and second, whith you can't fight right now: "Error: closures are not yet 
supported in CTFE".


so no, even if you'll remove `ref`, it will not work. sorry.


Is it possible to call a delegate at compile time?

2017-06-22 Thread Andrew Edwards via Digitalmars-d-learn

auto foo(Args...)(ref Args args)
{
with (Module!"std.conv")
with (Module!"std.stdio") {
return () => {
string[] s;
foreach (i, arg; args) {
static if (is(Args[i] == string)) {
s ~= arg;
} else {
s ~= to!string(arg);
}
}

debug writeln(fmt());
return cast(immutable)s;
}();
}
}

template Module(string name)
{
mixin("import Module = " ~ name ~ ";");
}

void main()
{
static immutable i = 7;
static immutable s = "teen";

static immutable res = foo(i, s)();
writeln(res);
}

I desire to call foo() at compile...  As implemented it does not 
happen, but it's not immediately clear what I am missing. Or is 
this simply not possible as yet? What is the proper way to 
redesign this template so that it will execute at compile time?


Thanks,
Andrew


Re: BetterC and TypeInfo Question

2017-06-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 23 June 2017 at 02:49:27 UTC, Mike wrote:
I'm not sure what you have in mind, but TypeInfo in itself is 
not bad and has some very useful features even for resource 
constrained devices and other niche domains.


Yeah, I agree with you.

My approaches are right now for -betterC to be a filthy hack to 
get it working quick, and I still have a bunch of ways I want to 
improve the implementation and compiler interface in the main, 
non-hack-switch too.


My wrist is sore today though so I gotta take a break... but I 
think you and I have the same goals in mind.


Re: BetterC and TypeInfo Question

2017-06-22 Thread Mike via Digitalmars-d-learn

On Friday, 23 June 2017 at 02:14:08 UTC, Adam D. Ruppe wrote:

Yes, it is necessary, but how much? Can we do it with 
implicitly generated library code?


I'm pretty sure the answer is "not much" and "yes", but I still 
need to ponder the details. I think the typeinfo for a class 
good enough for dynamic cast could be about half the size we 
have now.


Though like I said, a lot of the stuff we have now is cool 
stuff, so I don't want to miss it entirely, it could be behind 
another pointer.


I'm not sure what you have in mind, but TypeInfo in itself is not 
bad and has some very useful features even for resource 
constrained devices and other niche domains.


The problem is that the current compiler-runtime requires it to 
exist just to get a build, even though it's not being used in the 
source code (implicitly or otherwise) and has no chance of ever 
being executed or referenced in the resulting binary.


Also, TypeInfo has been overused in the compiler-runtime 
implementation.  For example:  
http://forum.dlang.org/post/mrmv61$230i$1...@digitalmars.com


The compiler should be able to generate the object code in a way 
that allows the linker to discard it, if it can't find anything 
that uses it.  I think LTO has made such features even more 
intelligent.


I'd like to see 3 improvements:
1.  The compiler doesn't require TypeInfo to be implemented in 
the runtime if the user's code will never make use of it.
2.  If TypeInfo is implemented in the runtime, the compiler 
generates the object code in a way that permits the linker to 
discard it if it can't find a link to it.
3.  If only one item is needed out of TypeInfo, pass a reference 
to that instead of the entire TypeInfo object in the 
compiler-runtime implementation, so implementations can be made 
more granular.  Or perhaps TypeInfo should be broken up into a 
few smaller types.


Mike


Re: BetterC and TypeInfo Question

2017-06-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 23 June 2017 at 00:41:11 UTC, sarn wrote:
Does it matter?  C++ programmers already accept that RTTI is 
needed for certain dynamic features.


Yes, it is necessary, but how much? Can we do it with implicitly 
generated library code?


I'm pretty sure the answer is "not much" and "yes", but I still 
need to ponder the details. I think the typeinfo for a class good 
enough for dynamic cast could be about half the size we have now.


Though like I said, a lot of the stuff we have now is cool stuff, 
so I don't want to miss it entirely, it could be behind another 
pointer.


Re: struct template constructors

2017-06-22 Thread via Digitalmars-d-learn
On Friday, 23 June 2017 at 00:54:36 UTC, Petar Kirov [ZombineDev] 
wrote:

On Thursday, 22 June 2017 at 21:19:43 UTC, Boris-Barboris wrote:

On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote:
And yes, there should be one destructor, which may be a no-op 
if you grab its resource and set it to null.


On all compilers...


That's a relief, thank you for your help.



On all compilers...


... modulo bugs.

Closely Related: https://github.com/dlang/dmd/pull/6852


And also: 
https://github.com/dlang/dmd/pull/6847/files#diff-89369a835b853bb3725fd1d10d9c2d5d


Re: struct template constructors

2017-06-22 Thread via Digitalmars-d-learn

On Thursday, 22 June 2017 at 21:19:43 UTC, Boris-Barboris wrote:

On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote:
And yes, there should be one destructor, which may be a no-op 
if you grab its resource and set it to null.


On all compilers...


That's a relief, thank you for your help.



On all compilers...


... modulo bugs.

Closely Related: https://github.com/dlang/dmd/pull/6852


Re: BetterC and TypeInfo Question

2017-06-22 Thread sarn via Digitalmars-d-learn
Currently a lot of language features generate dependencies on 
TypeInfo, arguably more than needed, but this is changing.  Some 
examples are in this DConf 2017 talk:


https://www.youtube.com/watch?v=endKC3fDxqs

Also, the way the language is designed right now, all modules are 
responsible for containing TypeInfo instances for all their 
types, in case other modules *might* need them.  So, if you 
define a plain old data struct, for example, you get TypeInfo and 
its runtime dependencies.  This isn't a requirement, and Adam has 
just patched DMD to make -betterC leave out the TypeInfo.


But, even in C++, RTTI is necessary for dynamic casting... so 
how is D going to address that? I think it is necessary, but 
can prolly be quite minimal. I will think about it more later.


Does it matter?  C++ programmers already accept that RTTI is 
needed for certain dynamic features.


Re: struct template constructors

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote:
And yes, there should be one destructor, which may be a no-op 
if you grab its resource and set it to null.


On all compilers...


That's a relief, thank you for your help.




Re: struct template constructors

2017-06-22 Thread Ali Çehreli via Digitalmars-d-learn

On 06/22/2017 02:08 PM, Boris-Barboris wrote:

On Thursday, 22 June 2017 at 20:05:46 UTC, Ali Çehreli wrote:

To be complete, 'auto ref' passes lvalues by reference and rvalues by
value, which you can detect with __traits(isRef):

struct S{
}

void foo()(auto ref S s) {
static if (__traits(isRef, s)) {
pragma(msg, "lvalue");
} else {
pragma(msg, "rvalue");
}
}

void main() {
auto s = S();
foo(s);

foo(S());
}

Ali


Thank you very much! And the last question:
Is it guaranteed an all compilers, that:
1). destructor for said rvalue is called only once.
2). function taking auto ref parameter gets that exact (memory-wise)
rvalue, for example:

struct S {}

S produce() { return S(); }

consume(produce());

void consume(auto ref S s)
{
  // s passed by value, but is exactly that struct returned by produce,
as if it
  // was RVO'd inside consume's stack frame.
  // and S destructor called only once on consume's scope escape?
}


I'm not sure whether it's RVO or moving in what condition, but yes, 
there will be no copy. You will get the bit representation of the 
constructed object.


And yes, there should be one destructor, which may be a no-op if you 
grab its resource and set it to null.


On all compilers...

Ali



Re: struct template constructors

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 20:05:46 UTC, Ali Çehreli wrote:
To be complete, 'auto ref' passes lvalues by reference and 
rvalues by value, which you can detect with __traits(isRef):


struct S{
}

void foo()(auto ref S s) {
static if (__traits(isRef, s)) {
pragma(msg, "lvalue");
} else {
pragma(msg, "rvalue");
}
}

void main() {
auto s = S();
foo(s);

foo(S());
}

Ali


Thank you very much! And the last question:
Is it guaranteed an all compilers, that:
1). destructor for said rvalue is called only once.
2). function taking auto ref parameter gets that exact 
(memory-wise) rvalue, for example:


struct S {}

S produce() { return S(); }

consume(produce());

void consume(auto ref S s)
{
  // s passed by value, but is exactly that struct returned by 
produce, as if it

  // was RVO'd inside consume's stack frame.
  // and S destructor called only once on consume's scope escape?
}


Re: struct template constructors

2017-06-22 Thread Ali Çehreli via Digitalmars-d-learn

On 06/22/2017 12:57 PM, Boris-Barboris wrote:
> On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote:
>> No time to think about the rest of the design but just to get the code
>> compiled, replace 'ref' with 'auto ref' like so:
>
> Ok, looks like this indeed passes rhs by reference, thank you.

To be complete, 'auto ref' passes lvalues by reference and rvalues by 
value, which you can detect with __traits(isRef):


struct S{
}

void foo()(auto ref S s) {
static if (__traits(isRef, s)) {
pragma(msg, "lvalue");
} else {
pragma(msg, "rvalue");
}
}

void main() {
auto s = S();
foo(s);

foo(S());
}

Ali



Re: struct template constructors

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote:
No time to think about the rest of the design but just to get 
the code compiled, replace 'ref' with 'auto ref' like so:


Ok, looks like this indeed passes rhs by reference, thank you.

destcalls - number of times UniquePtr destructor was called
deallocs - number of times internal pointer was freed.

unittest
{
deallocs = destcalls = 0;

class A {}
class B: A {}

{
UniquePtr!B b = UniquePtr!B.make();
assert(b.owner);
{
UniquePtr!A a = b;
assert(!b.owner);
assert(a.owner);
assert(destcalls == 0);
assert(deallocs == 0);
}
assert(destcalls == 1);
assert(deallocs == 1);
}
assert(destcalls == 2);
assert(deallocs == 1);
}




Re: Dealing with the interior pointers bug

2017-06-22 Thread ag0aep6g via Digitalmars-d-learn

On 06/22/2017 08:38 PM, Boris-Barboris wrote:
Casts are part of the type system. Yes, D type system allows invalid 
operations. It's not the compiler's fault, it's type system's fault.


unittest
{
 immutable int a = 4;
 int* b = cast(int*) 
 *b = 5;
 assert(*() == 5);
 assert(a == 4);
}


This is just arguing semantics, of course, but I wouldn't say that the 
type system allows this specific invalid operation. Rather, with casting 
you can step out of the type system, and break its guarantees.


Point is, you need a way to say that the operation is invalid. It's 
invalid because it breaks what `immutable` promises. `immutable` is part 
of the type, so I'd say the guarantee is part of the type system.


Re: struct template constructors

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote:
No time to think about the rest of the design but just to get 
the code compiled, replace 'ref' with 'auto ref' like so:


this(DT)(scope auto ref UniquePtr!DT rhs)
{
// ...
}

Ali


i added this static variable:

static int destcalls = 0;

changed constructor to:

this(DT)(scope auto ref UniquePtr!DT rhs)
{
// here rhs releases pointer
pragma(msg, typeof(rhs));
}

wich prints "UniquePtr!(B)" on my machine,
and destructor:

~this() { destcalls++; }

Following code compiles and runs ok:

class A {}
class B: A {}
UniquePtr!A a = UniquePtr!A.make();
assert(destcalls == 0);
UniquePtr!A b = UniquePtr!B.make();
assert(destcalls == 1);

Destructor is called for the result of "UniquePtr!B.make();", and 
if it actually was passed by value (wich is indicated by pragma's 
output), b's internal pointer would refer to freed heap block.


Re: Dealing with the interior pointers bug

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 19:11:19 UTC, Cym13 wrote:
Here it's the programmer's fault really. You should never use 
casts in normal code, cast is the ultimate switch to say "Look, 
I know what I'm doing, so disable all safety, don't try to make 
sense of it, and let me do my thing. If I'm telling you it's a 
cat, then it is dammit.". You can't blame the type system not 
to do something coherent here, you explicitely went out of your 
way to lie to that very same type system in the most unsafe way 
possible.
We're on the same page, I just think that ability to lie is part 
of the type system, that's all.


Re: struct template constructors

2017-06-22 Thread Ali Çehreli via Digitalmars-d-learn

On 06/22/2017 12:06 PM, Boris-Barboris wrote:
> Hi
>
> https://dpaste.dzfl.pl/0def4e286564
>
> Is there a cleaner way to go than the one on the line 26? And why is the
> constructor
>
> /d475/f781.d(37): f781.UniquePtr!(A).UniquePtr.__ctor(DT)(ref scope
> UniquePtr!DT rhs)
>
> unfit for line 51?
> Is it because the expression " = UniquePtr!B.make()" cannot be
> interpreted as "scope ref"? It must release ownership of a pointer it
> holds, and looks like it cannot do it in this form.

(Going pedantic, you mean "struct constructor templates" or "templated 
struct constructors".)


No time to think about the rest of the design but just to get the code 
compiled, replace 'ref' with 'auto ref' like so:


this(DT)(scope auto ref UniquePtr!DT rhs)
{
// ...
}

Ali



Re: Dealing with the interior pointers bug

2017-06-22 Thread Cym13 via Digitalmars-d-learn

On Thursday, 22 June 2017 at 18:38:59 UTC, Boris-Barboris wrote:

On Thursday, 22 June 2017 at 13:56:29 UTC, ag0aep6g wrote:
For example, the type system guarantees that immutable data 
never changes. But the compiler allows you to cast from 
immutable to mutable and change the data. It's an invalid 
operation, but the compiler is not expected to catch that for 
you.
Casts are part of the type system. Yes, D type system allows 
invalid operations. It's not the compiler's fault, it's type 
system's fault.


unittest
{
immutable int a = 4;
int* b = cast(int*) 
*b = 5;
assert(*() == 5);
assert(a == 4);
}


Here it's the programmer's fault really. You should never use 
casts in normal code, cast is the ultimate switch to say "Look, I 
know what I'm doing, so disable all safety, don't try to make 
sense of it, and let me do my thing. If I'm telling you it's a 
cat, then it is dammit.". You can't blame the type system not to 
do something coherent here, you explicitely went out of your way 
to lie to that very same type system in the most unsafe way 
possible.


struct template constructors

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

Hi

https://dpaste.dzfl.pl/0def4e286564

Is there a cleaner way to go than the one on the line 26? And why 
is the constructor


/d475/f781.d(37): f781.UniquePtr!(A).UniquePtr.__ctor(DT)(ref 
scope UniquePtr!DT rhs)


unfit for line 51?
Is it because the expression " = UniquePtr!B.make()" cannot be 
interpreted as "scope ref"? It must release ownership of a 
pointer it holds, and looks like it cannot do it in this form.


Re: Dealing with the interior pointers bug

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 13:56:29 UTC, ag0aep6g wrote:
For example, the type system guarantees that immutable data 
never changes. But the compiler allows you to cast from 
immutable to mutable and change the data. It's an invalid 
operation, but the compiler is not expected to catch that for 
you.
Casts are part of the type system. Yes, D type system allows 
invalid operations. It's not the compiler's fault, it's type 
system's fault.


unittest
{
immutable int a = 4;
int* b = cast(int*) 
*b = 5;
assert(*() == 5);
assert(a == 4);
}


Re: Is there s.th. like enforceSuffix for arrays (string)?

2017-06-22 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jun 22, 2017 at 06:18:22PM +, Andre Pany via Digitalmars-d-learn 
wrote:
> Hi,
> 
> i often need to check whether an array(string) ends with a specific
> text and if not I need to add this text.
> 
> For example I have a variable url and / has to be added to the end in
> case it is missing.
> 
> I want to write:
> ...new RegistryPackageSupplier(URL(url.enforceSuffix("/"))...
> 
> Of course the logic is rather simple to implement on my side but I
> often has this requirement and I cannot believe this functionality is
> missing in Phobos.
[...]

What about:

import std.string : chomp;
url.chomp('/') ~ '/'

The .chomp removes the "/" if there's one, then the ~ adds it back in
either way, so the result always ends with "/".

Phobos provides the primitives to build what you need, but it's a little
unreasonable to expect that it should provide names for every possible
combination of existing functions -- we'd run out of names because of
combinatorial explosion.


T

-- 
Life is too short to run proprietary software. -- Bdale Garbee


Is there s.th. like enforceSuffix for arrays (string)?

2017-06-22 Thread Andre Pany via Digitalmars-d-learn

Hi,

i often need to check whether an array(string) ends with a 
specific text and if not I need to add this text.


For example I have a variable url and / has to be added to the 
end in case it is missing.


I want to write:
...new RegistryPackageSupplier(URL(url.enforceSuffix("/"))...

Of course the logic is rather simple to implement on my side but 
I often has this requirement and I cannot believe this 
functionality is missing in Phobos.


Have I missed it in the documentation?

Kind regards
André


Re: GDC generate wrong .exe ("not a valid win32 application")

2017-06-22 Thread Sebastien Alaiwan via Digitalmars-d-learn

On Thursday, 22 June 2017 at 05:57:59 UTC, bauss wrote:
On Wednesday, 21 June 2017 at 15:55:27 UTC, David Nadlinger 
wrote:
On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer 
wrote:

Fresh install of GDC. (tried with 32x ad 32_64x)


Where did you get the GDC executable from? The GDC project 
doesn't currently offer any official builds that target 
Windows; the 6.3.0 builds from 
https://gdcproject.org/downloads in fact generate Linux 
binaries.


 — David


I see Windows distributions below the Linux ones.


They run on Windows, and produce binaries that run on GNU/Linux.


Re: Dealing with the interior pointers bug

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

On 6/21/17 1:23 PM, H. S. Teoh via Digitalmars-d-learn wrote:

On Wed, Jun 21, 2017 at 05:11:41PM +, TheGag96 via Digitalmars-d-learn 
wrote:

On Wednesday, 21 June 2017 at 15:42:22 UTC, Adam D. Ruppe wrote:

This comes from the fact that D's GC is conservative - if it sees
something that *might* be a pointer, it assumes it *is* a pointer
and thus had better not get freed.


So is the GC then simply made to be "better-safe-than-sorry" or is
this a consequence of how the GC does things? Or rather, does the GC
know the type of any references to its memory at all?


The reason the GC must be conservative is because (1) D is a systems
programming language, and also because (2) D interfaces directly with C.


There are actually two categories of reasons: Design and Implementation.

In the Design category, D can never have a truly precise scanning 
capability because of void * and unions. These two features would be 
impossible to determine what the actual layout of pointers for a given 
block actually is.


In the Implementation category, precise scanning (to a certain degree) 
is achievable. But the current GC treats all blocks as "every 
size_t.sizeof bytes are a pointer" or "there are no pointers". With a 
better understanding of the layout of memory, the GC could be smarter 
about scanning. However, there are costs to the complexity.


In addition, the GC does not know the stack layout of memory. So the 
stack can always create false pointers as it must be scanned 
conservatively. We could potentially create a precise map of the stack, 
but that involves either restricting the compiler from reassigning stack 
data to mean something else, or keeping a running map of what stack data 
is actually used. Both don't seem appealing to a performance-oriented 
language (system) language. Add alloca to the design category of memory 
that can't be precisely scanned as well.


So we could do better in this front, but I don't know that it will 
happen because of the performance concerns. Rainer Schuetze implemented 
a precise scanner a while back, and did a dconf talk on it. So it is 
definitely possible (to a certain degree).


-Steve


Re: BetterC and TypeInfo Question

2017-06-22 Thread jmh530 via Digitalmars-d-learn

On Thursday, 22 June 2017 at 14:50:45 UTC, Adam D. Ruppe wrote:

[snip]


I appreciate the reply.


Re: BetterC and TypeInfo Question

2017-06-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 22 June 2017 at 14:30:31 UTC, jmh530 wrote:
I was looking through the C++ standard library headers and 
noticed  that has a typeid also. One difference with 
D is that it is opt-in as there is some cost using it.


C++ also leaves most the properties for typeinfo to be 
implementation defined, meaning things like .name can just return 
an empty string. I believe the only thing the standard requires 
is consistent opEquals.


Additionally, C++ will only generate it for classes with at least 
one virtual member (the main use of it is dynamic casts, or 
substitutes thereof, and using those is often bad object oriented 
design anyway!)


I suppose I'm wondering what other differences there are. Could 
TypeInfo be made optional in D, like it is in C++?


Much of it can, yes, and it can also be defined to offer less (or 
more! I'm actually a fan of runtime reflection) than it does now. 
There's an effort to convert typeinfo to be library templates 
instead of a compiler-provided blob like it is now.


But, even in C++, RTTI is necessary for dynamic casting... so how 
is D going to address that? I think it is necessary, but can 
prolly be quite minimal. I will think about it more later.


BetterC and TypeInfo Question

2017-06-22 Thread jmh530 via Digitalmars-d-learn
I should preface this by saying I don't really have a good sense 
of how either BetterC or the D runtime work.


The recent BetterC thread made me wonder about TypeInfo in the D 
runtime. My (surface level) understanding is that this is what 
makes typeid work at run time.


I was looking through the C++ standard library headers and 
noticed  that has a typeid also. One difference with D 
is that it is opt-in as there is some cost using it.


I suppose I'm wondering what other differences there are. Could 
TypeInfo be made optional in D, like it is in C++?


Re: Dealing with the interior pointers bug

2017-06-22 Thread ag0aep6g via Digitalmars-d-learn

On 06/22/2017 12:34 PM, Boris-Barboris wrote:
Everything the language allows to compile is allowed by it's type 
system, or is a bug in the compiler.


No. D is not supposed to be completely verifiable by the compiler.

For example, the type system guarantees that immutable data never 
changes. But the compiler allows you to cast from immutable to mutable 
and change the data. It's an invalid operation, but the compiler is not 
expected to catch that for you.


Re: Dealing with the interior pointers bug

2017-06-22 Thread Boris-Barboris via Digitalmars-d-learn

On Thursday, 22 June 2017 at 09:45:09 UTC, Russel Winder wrote:
I think the term "systems programming language" contains no 
actual data, so needs to be retired. In this situation it 
provides no reason for conservative garbage collection.


It means the intent of language designer to let you write 
operating system with his language, wich implies certain building 
blocks available to you. Whether it actually allows it or not is 
another question.



Why should any language allow anything outside the type system.
Everything the language allows to compile is allowed by it's type 
system, or is a bug in the compiler.



Strong typing means strong typing
Define strong typing then. Pointer is part of the type system, 
all casts and operations on it are too. If you pass wrongly-typed 
pointer, it won't compile.


Maybe then the fault is having a weak type system, as any 
language is that allows ints to be pointers and vice versa.


What's wrong with pointers in a language? You're not forced to 
use them, you know? But some tasks force you. If you seek 
compile-time verifyability, use different coding patterns \ 
languages, designed around this intent.


Maybe type systems should be strong and all FFI be by value 
with no references to memory allowed?


No, they definetly should not.

Why can't GC use staticaly available type info (all 
pointer\reference variables and fields are visible in program 
text, why not just scan only them)? I don't know, probably it's 
harder, since it requires more cooperation between compiler and 
runtime, and increases GC signature (you have to store a huge 
list of pointers to all pointers on all stacks (and probably heap 
too), and compiler should generate code to populate this list on 
every function call). At this point you would be better off with 
RAII, wich will be more efficient and explicit and do exactly 
what you tell it to do.





Cannot implicitly convert expression (struct this)

2017-06-22 Thread Andre Pany via Digitalmars-d-learn

Hi,

I created a custom type which enables me to have enums which have 
in their initial state, the init value of their base type. 
Something similiar to Nullable...


enum Reason : string {CO = "Co", FU = "Fu", CA = "Ca"}
struct TestStruct {InitialEnum!Reason reason;}

This line raises the error:
TestStruct s2 = TestStruct(Reason.FU);
Error: cannot implicitly convert expression ("Fu") of type 
Reason to InitialEnum!(Reason)


While this line is working fine:
TestStruct s1 = {reason: Reason.FU};

What do I miss?

Kind regards
André

struct InitialEnum(T)
{
import std.traits: OriginalType, EnumMembers;
import std.conv: to;

private T _value;
private bool _isEmpty = true;
alias EnumBaseType = OriginalType!T;

	@property EnumBaseType baseTypeValue() { return (_isEmpty) ? 
EnumBaseType.init : _value; }

@property T value() { return _value; }
@property bool isEmpty() { return _isEmpty; }

alias baseTypeValue this;

void opAssign(EnumBaseType value)
{
if (value == EnumBaseType.init)
{
_isEmpty = true;
return;
}

foreach (member; EnumMembers!T)
{
if (value == member)
{
_value = member;
_isEmpty = false;
return;
}   
}
		throw new Exception("Value "~value.to!string~" is not a valid 
enum value");

}

this(T t)
{
_isEmpty = false;
_value = t;
}

this(EnumBaseType value)
{
opAssign(value);
}
}



Re: Dealing with the interior pointers bug

2017-06-22 Thread Russel Winder via Digitalmars-d-learn
On Wed, 2017-06-21 at 10:23 -0700, H. S. Teoh via Digitalmars-d-learn
wrote:
> […]
> 
> The reason the GC must be conservative is because (1) D is a systems
> programming language, and also because (2) D interfaces directly with
> C.

I think the term "systems programming language" contains no actual
data, so needs to be retired. In this situation it provides no reason
for conservative garbage collection.

Interfacing with a foreign language, not just C, does bring problems,
but only if there is a shared address space, or the type system is weak
or allows unions including pointers.

> Being a systems programming language means you should be able to do
> things outside the type system (in @system code, of course, not in
> @safe
> code), including storing pointers as int values.  Any C code that
> your D
> program interoperates with may also potentially do similar things.

Why should any language allow anything outside the type system. Strong
typing means strong typing (*).

> Because of this, the GC cannot simply assume that an int value isn't
> actually a pointer value in disguise, so if that int value happens to
> coincide with an address of an allocated memory block, the only sane
> thing it can do is to assume the worst and assume that the memory is
> still live (via that (assumed) reference).  It's not safe for the GC
> to
> assume that it's merely an int, because if it actually turns out to
> be a
> pointer, then you'll end up with a dangling pointer and the ensuing
> memory corruption, security holes, and so forth.  But assuming that
> the
> value is a pointer is generally harmless -- the memory block just
> doesn't get freed right away, but if the int is mutated afterwards,
> eventually the GC will get around to cleaning it up.

Maybe then the fault is having a weak type system, as any language is
that allows ints to be pointers and vice versa. Maybe type systems
should be strong and all FFI be by value with no references to memory
allowed?

> The only big problem is in 32-bit code, where because of the very
> limited space of pointer values, the chances of a random int value
> coinciding with a valid pointer value is somewhat high, so if you
> have a
> large allocated memory block, the chances of a random int being
> mistaken
> for a reference to the block is somewhat high, so you could
> potentially
> run out of memory due to large blocks not being freed when they could
> be.  Fortunately, though, in 64-bit land the space of pointer values
> is
> generally so large that it's highly unlikely that a random int would
> look like a pointer, so this generally isn't a problem if you're
> using
> 64-bit, which is the case more and more now as vendors are slowly
> phasing out 32-bit support.

If there is a problem for 32-bit there is a problem for 64-bit. If it
is possible it will happen.



(*) OK, this joke probably only works in the UK.
-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Manually calling postblots recursively

2017-06-22 Thread Johannes Loher via Digitalmars-d-learn

On Sunday, 18 June 2017 at 14:16:03 UTC, Basile B. wrote:

On Sunday, 18 June 2017 at 09:41:01 UTC, Johannes Loher wrote:
Hey, I'm trying to work on 
https://issues.dlang.org/show_bug.cgi?id=15708 so I decided it 
might be interesting to find a way to (recursively) call all 
postblits that belong to certain struct or static array. This 
is what I came up with so far:


[...]


"@disable" postblits are detected as valid postblits.
I think that you have to AndAnd the detection with 
std.traits.isCopyable


Here is my new version. Additionally to taking care of @disable 
this(this); I added compile time checks if the underlying fields 
have an "elaborate copy constructor" so that I only call 
callPostblits on them if needed. Is this reasonable? It increases 
compiletime, but could possibly decrease runtime a little. On the 
other hand, the empty function calls should probably just get 
optimized away...?


While doing all that I realized that hasElaborateCopyConstructor 
is true for structs with @disable this(this). Is that intended? 
It looks a bit weird to me...




import std.traits;

void callPostblits(S)(ref S s)
{
static if (isStaticArray!S && S.length && 
hasElaborateCopyConstructor!(ElementType!S))

{
foreach (ref elem; s)
callPostblits(elem);
}
else static if (is(S == struct))
{
foreach (field; FieldNameTuple!S)
{
static if 
(hasElaborateCopyConstructor!(typeof(__traits(getMember, s, 
field

{
callPostblits(__traits(getMember, s, field));
}
}

static if (hasMember!(S, "__postblit") && isCopyable!S)
{
s.__postblit();
}
}
}

unittest
{

struct AnotherTestStruct
{
int b = 0;

this(this)
{
b = 1;
}
}

struct TestStruct
{
int a = 0;

this(this)
{
a = 1;
}

AnotherTestStruct anotherTestStruct;
}


TestStruct[2] testStructs;

assert(testStructs[0].a == 0 && 
testStructs[0].anotherTestStruct.b == 0);
assert(testStructs[1].a == 0 && 
testStructs[1].anotherTestStruct.b == 0);


callPostblits(testStructs);

assert(testStructs[0].a == 1 && 
testStructs[0].anotherTestStruct.b == 1);
assert(testStructs[1].a == 1 && 
testStructs[1].anotherTestStruct.b == 1);


struct YetAnotherTestStruct
{
@disable this(this);
}

YetAnotherTestStruct yetAnotherTestStruct;
callPostblits(yetAnotherTestStruct); // This will also compile
}


Re: GDC generate wrong .exe ("not a valid win32 application")

2017-06-22 Thread cym13 via Digitalmars-d-learn

On Thursday, 22 June 2017 at 05:57:59 UTC, bauss wrote:
On Wednesday, 21 June 2017 at 15:55:27 UTC, David Nadlinger 
wrote:
On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer 
wrote:

Fresh install of GDC. (tried with 32x ad 32_64x)


Where did you get the GDC executable from? The GDC project 
doesn't currently offer any official builds that target 
Windows; the 6.3.0 builds from 
https://gdcproject.org/downloads in fact generate Linux 
binaries.


 — David


I see Windows distributions below the Linux ones.


They're used for cross-compiling.


Re: GDC generate wrong .exe ("not a valid win32 application")

2017-06-22 Thread bauss via Digitalmars-d-learn

On Wednesday, 21 June 2017 at 15:55:27 UTC, David Nadlinger wrote:

On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer wrote:

Fresh install of GDC. (tried with 32x ad 32_64x)


Where did you get the GDC executable from? The GDC project 
doesn't currently offer any official builds that target 
Windows; the 6.3.0 builds from https://gdcproject.org/downloads 
in fact generate Linux binaries.


 — David


I see Windows distributions below the Linux ones.