Re: how to debug memory errors

2016-11-08 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 8 November 2016 at 07:39:12 UTC, Era Scarecrow wrote:

On Tuesday, 8 November 2016 at 06:04:59 UTC, thedeemon wrote:
On Tuesday, 8 November 2016 at 05:36:22 UTC, Era Scarecrow 
wrote:


 Hmmm.. I had the impression that if something was referenced 
by another object, then it couldn't be collected,


Another *live* object, I.e. reachable from globals and stack. 
If you have a big tree and it becomes unreachable (you only 
had a pointer to its root and you nulled it), then this whole 
tree becomes garbage, and its nodes and leafs will be 
collected in unpredictable order, with destructors being run 
in unpredictable order, even when these dead nodes reference 
each other.


 And I can't help but hope it would start at the largest/base 
object and work it's way up. Or the largest object and then 
work it's way down. Alright...


One of the reasons it is not specified is that very often the 
hierarchy is not a simple tree, but a graph with possibly many 
cycles. As a matter of fact, very often child nodes have pointers 
to parent nodes, so that what is logically a tree is practically 
a graph with lots of cycles. So it is not possible to identify a 
root object which does not have incoming dead pointers, and no 
guarantee can be provided.




Re: how to debug memory errors

2016-11-07 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 6 November 2016 at 21:46:52 UTC, Øivind wrote:

Hi,

My app occasionally gives me a

*** Error in `./hauto-test': double free or corruption 
(fasttop): 0x7f504c002a60 ***


but gives me the following on every termination

core.exception.InvalidMemoryOperationError@src/core/exception.d(693): Invalid 
memory operation

How do I go about debugging and resolving these?

-Øivind


I think that "Invalid Memory Operation" is the error the GC gives 
you when you try to allocate memory during the collection phase 
(i.e. inside a destructor). I suggest you avoid doing so.


I don't know if the double free problem is related to this. It 
may as well be a totally unrelated bug of some container you are 
using.


Re: check instance of nested variadic template

2016-11-05 Thread Lodovico Giaretta via Digitalmars-d-learn
On Saturday, 5 November 2016 at 13:34:51 UTC, Gianni Pisetta 
wrote:
When i have time i will test it with ldc and see if the result 
is the same, then it will probably be a front-end bug and i 
will report it as an issue.


I think it has already been reported.

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


Re: strange -fPIC compilation error

2016-11-01 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 1 November 2016 at 18:13:32 UTC, TheGag96 wrote:
On Monday, 31 October 2016 at 07:16:50 UTC, Sebastien Alaiwan 
wrote:

Hello,
From GCC 6.2, -fpie is becoming the default setting at compile 
and at link time.
As dmd uses GCC to link, now the code needs to be compiled 
with a special option.
Which means you need, at the moment, to add the following 
options to your dmd.conf:

 -defaultlib=libphobos2.so -fPIC
(the change from GCC is related to security and address space 
randomization).


So does this mean it's now impossible to compile statically 
until this gets fixed?


It's impossible with the default `libphobos2.a`. I didn't try, 
but I'm quite confident that if you clone the Phobos repository 
and rebuild the library yourself with -fPIC, you can then link it 
statically to PIE executables.


Re: strange -fPIC compilation error

2016-10-30 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 31 October 2016 at 00:08:59 UTC, Charles Hixson wrote:
So now I removed the repository version of dmd and dub, 
downloaded DMD64 D Compiler v2.072.0-b2, used dkpg to install 
it, and appear to get the same errors.


(Well, actually I removed the commenting out of the code, but 
it compiles and runs properly with ldc2.)


I don't think it's a problem of DMD. This is due to your gcc 
installation being hardened, that is, configured to produce PIE 
by default. To produce PIE, the linker needs to be fed PIC, which 
DMD does not produce by default. The -fPIC flags makes DMD 
produce PIC out of your sources. The problem is, libphobos2.a 
(the static version of Phobos) is not compiled with -fPIC, so 
even if your code is PIC, gcc will complain. The workaround is to 
use -defaultlib=libphobos2.so to dynamically link with the shared 
version of Phobos. Being it a shared object, it does not give any 
problem with PIE.


Looking on internet, I didn't find any clue about Debian shipping 
an hardened gcc, but this is the only cause I can think of for 
the behaviour you are experiencing.


Re: Parse a String given some delimiters

2016-10-30 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 30 October 2016 at 20:50:47 UTC, Alfred Newman wrote:

Hello,

I'm migrating some Python code to D, but I stuck at a dead 
end...


Sorry to provide some .py lines over here, but I got some 
doubts about the best (fastest) way to do that in D.


Executing the function parsertoken("_My   input.string", " 
_,.", 2) will result "input".

Parsercount("Dlang=-rocks!", " =-") will result 2,

Thanks in advance


You can take inspiration from the following snippet:

=
import std.stdio, std.regex;

void main()
{
string s = "Hello.World !";
auto ss = split(s, regex(`\.| `));
ss.length.writeln;
ss[1].writeln;
}
=


Re: strange -fPIC compilation error

2016-10-30 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 30 October 2016 at 18:02:28 UTC, Charles Hixson wrote:

 dmd --version
DMD64 D Compiler v2.071.2
Copyright (c) 1999-2015 by Digital Mars written by Walter Bright
on debian testing.

dub is installed via apt-get.

Should I revert to an earlier version?  Or what?

The program:


importstd.stdio;

voidmain()
{//int[]t1;

//t1~=1;
//t1~=2;
//writeln ("t1 = ", t1);
}

fails with the 442 lines of error:

/usr/bin/ld: test.o: relocation R_X86_64_32 against symbol 
`__dmd_personality_v0' can not be used when making a shared 
object; recompile with -fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(exception_224_3b4.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(exception_227_4a2.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(exception_229_5cc.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_626_47b.o): 
relocation R_X86_64_32 against symbol 
`_D6object9Throwable7__ClassZ' can not be used when making a 
shared object; recompile with -fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(dmain2_628_776.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC
/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(dwarfeh_62b_6b9.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC

...

/usr/bin/ld: 
/usr/lib/x86_64-linux-gnu/libphobos2.a(aaA_51a_53e.o): 
relocation R_X86_64_32 against symbol `__dmd_personality_v0' 
can not be used when making a shared object; recompile with 
-fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on 
output

collect2: error: ld returned 1 exit status
--- errorlevel 1


Are you on Ubuntu 16.10, or some other system with an hardened 
toolchain? If that's the case, you should compile with `-fPIC 
-defaultlib=libphobos2.so`. You can put those options in your 
dmd.conf configuration file, so that you don't have to type them 
every time.


List defined version specifications

2016-10-19 Thread Lodovico Giaretta via Digitalmars-d-learn

Hi!

A simple question: is there a way to list all defined version 
specifications?


Something like:

pragma(msg, __traits(allVersions));

Example output (DMD on Ubuntu x64, release build):

[all, D_InlineAsm_X86_64, X86_64, Posix, linux, DigitalMars, 
CRuntime_Glibc, D_Version2, LittleEndian, D_LP64, D_HardFloat, 
D_SIMD, D_NoBoundsChecks, ELFv2]


Thank you in advance.


Re: Symbol lookup failed in imported module

2016-10-02 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 2 October 2016 at 20:12:16 UTC, rumbu wrote:

[...]


I think you'll find the following article really interesting. It 
talks exactly about what you are experiencing.


http://dlang.org/hijack.html


Re: Getting consistent behavour for class properties

2016-10-02 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 2 October 2016 at 17:10:58 UTC, mikey wrote:
There is already a degree of transparency with how properties 
being handled for example in allowing properties to be an 
lvalue if they have a setter.


t.val = 42;


Actually, this is not specific to properties, as it also works on 
"standard" methods, if they have a single parameter:



import std.stdio;

void main()
{
writeln = 42;
}


Re: Getting consistent behavour for class properties

2016-10-02 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 2 October 2016 at 14:26:46 UTC, mikey wrote:

[...]


Yeah, a property is quite different from a variable. In fact, a 
property may refer to a computed value, which may not have an 
address and as such cannot be modified:


@property auto currentTimeMillis()
{
return currentTimeNanos/100;
}

So it is correct that `+=` doesn't work with properties, and 
neither does the "addressof" operator `&` (it returns the 
delegate). Having a getter property return by ref circumvents 
this issue, but has the drawback of bypassing any check that a 
setter property would do.


If you want to use properties as getters/setters and also want 
compound assignments to work, you can easily achieve that with a 
wrapper template as this[1] one.


[1] http://pastebin.com/38n0fEtF


Re: how to access struct member using [] operator?

2016-09-25 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:


import std.stdio;

struct Something
{
int x, y;
float z;

auto opIndex()(string member) {
switch (member) {
case "x": return this.x;
case "y": return this.y;
case "z": return this.z;
default: assert(0);
}
}
}

void main(string[] args)
{
Something s;
writeln(s["x"]);
writeln(s["z"]);
}



Doesn't work. s["x"] is returned as float in this example. The 
reason is, opIndex cannot magically change return type based on 
the passed-in string.


Re: Can someone explain to me the design choices for this function definition?

2016-09-22 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 22 September 2016 at 20:35:13 UTC, e-y-e wrote:

[...]


Disclaimer: my answers are just early guesses.

1. Why is openRight a runtime flag? Is there really a use case 
for this?


Runtime evaluation is more flexible. The reason to have 
compile-time evaluation is to allowed aggressive specialization, 
highly tuned codegen and different attribute inference. If that 
flag is going to add a single very cheap branch (compared to the 
total cost), then it may not be worth to have it as a 
compile-time argument, as this would increase the number of 
instantiations and slightly reduce the flexibility.


But there is a second possible explanation, see below.


2. Why is openRight not a Flag type?


It may be that until is quite old, predating the extensive usage 
of Flag, and maybe also the extensive use of compile-time flags.


Re: D code optimization

2016-09-22 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 22 September 2016 at 16:09:49 UTC, Sandu wrote:

It is often being claimed that D is at least as fast as C++.
Now, I am fairly new to D. But, here is an example where I want 
to see how can this be made possible.


So far my C++ code compiles in ~850 ms.


I assume you meant that it runs in that time.


While my D code runs in about 2.1 seconds.


Benchmarking C++ vs D is less trivial than it looks, for various 
reasons:

- compiler optimizations:
  - which compilers (both C++ and D) are you using? Are you aware 
of the differences in code optimization between DMD, GDC and LDC?

  - which flags are you passing to your C++ and D compilers?
  - your code is actually testing the compiler ability in loop 
unrolling, constant folding and operation hoisting
- code semantics: C++ and D, when they look similar, they usually 
produce the same results, but the often behave very differently 
internally:
  - in the posted code you allocate a lot of managed memory, 
putting a big burden on the garbage collector, which in C++ you 
don't do, because you talk directly to the C runtime


So it's difficult to extract useful data from this kind of 
benchmark.


Re: Module Clarification

2016-09-22 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 22 September 2016 at 14:29:20 UTC, Jonathan Marler 
wrote:
Actually, the more I think about it, I'm not sure there's a 
good reason for the "package.d" semantics to exist.  I guess it 
establishes a pattern when people would like to combine smaller 
modules into one public module, but it doesn't have to be used 
that way.  The opposite is true that you could use a normal 
module (not a package.d module) to publicly import smaller 
modules:


Instead of:
foo/package.d // publically imports fooPart1 and fooPart2
foo/fooPart1.d
foo/fooPart2.d

What was wrong with:
foo.d // still publically imports fooPart1 and fooPart2
foo/fooPart1.d
foo/fooPart2.d

If the package.d file didn't exist, then I don't think there 
would be any problem with hierarchical modules.  Is this the 
right conclusion?  Was package.d a mistake?  Maybe the 
reasoning is that D doesn't really like hierarchical modules, 
so creating them should look a bit odd?


foo/package.d
foo/bar/package.d
foo/bar/baz/package.d


I think that having package.d provides a better layout. Look at 
the difference between this:



ls std/experimental

drw-rw-rw- allocator
drw-rw-rw- logger
drw-rw-rw- ndslice
-rw-rw-rw- typecons.d

and this:


ls std/experimental

drw-rw-rw- allocator
-rw-rw-rw- allocator.d
drw-rw-rw- logger
-rw-rw-rw- logger.d
drw-rw-rw- ndslice
-rw-rw-rw- ndslice.d
-rw-rw-rw- typecons.d

Having to put part of a package outside the package folder is 
ugly to see and a bit more difficult to manage.


Re: Iterate over two arguments at once

2016-09-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 19 September 2016 at 18:10:22 UTC, bachmeier wrote:

Suppose I want to iterate over two arrays at once:

foreach(v1, v2; [1.5, 2.5, 3.5], [4.5, 5.5, 6.5]) {
  ...
}

I have seen a way to do this but cannot remember what it is and 
cannot find it.


You can use std.range.zip:

https://dlang.org/phobos/std_range.html#.zip

Or std.range.lockstep:

https://dlang.org/phobos/std_range.html#.lockstep


Re: Embed glade file into a binary

2016-09-17 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 17 September 2016 at 19:01:10 UTC, Geert wrote:

On Saturday, 17 September 2016 at 18:36:52 UTC, llmp wrote:

On Saturday, 17 September 2016 at 18:18:37 UTC, Geert wrote:
I've compiled a small application, and it runs when i execute 
it at the same directory where is the glade file.


Is there a way to embed a glade file into a binary?


enum fileContent = import(file);

fileContent is a static array of ubyte.
the compiler must know the path to "file" via -J"dir/subdir"


Thanks!
I've just tried that, but i get an error message with the xml 
file content, and this at the end:


// More XML here...

True
True
name="receives_default">True

  
  
True
True
2
  

  
  
True
True
6
  

  

  

': File name too long

// End of message.

This is part of the application code:

[...]

enum fileContent = import("vista.glade");

[...]

g.addFromFile(fileContent);

window = cast(Window)g.getObject("Win_01");
}

// More code here ...
}

[...]


addFromFile expects the *name* of the file. Because you already 
have the *contents* of the file, you should change method. Maybe 
addFromString is the correct one, but I'm not sure.


Re: Mutable class reference to immutable class

2016-09-10 Thread Lodovico Giaretta via Digitalmars-d-learn
On Saturday, 10 September 2016 at 19:46:51 UTC, Jonathan Marler 
wrote:
This is been bugging me for a while. Is it possible to have a 
mutable reference to an immutable class?  [...]


You are probably looking for std.typecons.Rebindable: 
https://dlang.org/phobos/std_typecons.html#.Rebindable





Re: inferred vs. annotated attributes

2016-09-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 10 September 2016 at 08:23:35 UTC, Q. Schroll wrote:

Is there a difference between inferred and annotated attributes?
Example:

struct X(T)
{
this(S)(in S[] arr) // inferred pure
{ }
}

void main() pure
{
X!uint mut = [ 1, 2 ]; // proves inference (cf. main is 
pure)

// immutable X!uint imm1 = [ 1, 2 ];
// auto imm2 = immutable X!uint([1, 2]);
}

The commented lines yield error messages claiming the 
constructor cannot deduce function from argument types 
!()(int[]) immutable, however it can, if "pure" is explicitly 
annotated.


Is this a bug or did I get something wrong about inference / 
unique expressions?


A method (included ctors) that is not annotated const, nor 
immutable, nor inout, is implicitly mutable. This implies that 
your ctor is mutable, and as such it cannot create immutable 
instances.


If you add another ctor marked immutable, everything works. An 
alternative is to mark the ctor as inout.


I tested this solution and it works, but I'm not sure if it is by 
design.


Re: Functions, nothrow and assert

2016-09-08 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 8 September 2016 at 11:40:17 UTC, Russel Winder 
wrote:

Is the fact that:

void f() nothrow {
assert(1 == 0);
}

int main() {
f();
return 0;
}

compiles fine but at run time f does indeed throw an exception 
what should happen? If it is what does nothrow actually mean?


To expand on the previous correct answers, nothrow is about not 
throwing Exceptions. Exceptions are part of the normal flow of 
the program: they are used to signal recoverable errors, much 
like error codes.


Errors, on the other hand, are unrecoverable system failures that 
should not be catched (catching them is undefined behaviour, I 
think) and will surely lead to a crash. Errors are not covered by 
nothrow.


Asserts throw Errors, not Exceptions. The reason is that asserts 
are used to test conditions that must hold, at the point that an 
optimizing compiler can analyze the expression inside the assert 
and optimize the executable based on the truthness of that 
condition. So if an assert is found false at runtime, the code 
may not be able to work at all. That's why asserts throw Errors 
and not Exceptions.


Re: Instantiating a class with range template parameter

2016-09-08 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 8 September 2016 at 08:20:49 UTC, Jon Degenhardt 
wrote:
I've been generalizing output routines by passing an 
OutputRange as an argument. This gets interesting when the 
output routine is an virtual function. Virtual functions cannot 
be templates, so instead the template parameters need to be 
part of class definition and specified when instantiating the 
class.


An example is below. It works fine. One thing I can't figure 
out: how to provide the range parameter without first declaring 
a variable of the appropriate type. What works is something 
like:


auto writer = stdout.lockingTextWriter;
auto x = new Derived!(typeof(writer));

Other forms I've tried fail to compile. For example, this fails:

auto x = new Derived!(typeof(stdout.lockingTextWriter));

I'm curious if this can be done without declaring the variable 
first. Anyone happen to know?


--Jon

Full example:

import std.stdio;
import std.range;

class Base(OutputRange)
{
abstract void writeString(OutputRange r, string s);
}

class Derived(OutputRange) : Base!OutputRange
{
override void writeString(OutputRange r, string s)
{
put(r, s);
put(r, '\n');
}
}

void main()
{
auto writer = stdout.lockingTextWriter;
auto x = new Derived!(typeof(writer));
x.writeString(writer, "Hello World");
}


I think that

auto x = new Derived!(typeof(stdout.lockingTextWriter()))(); // 
note the parenthesis


should work.



But usually, you save the writer inside the object and make a 
free function called `derived` (same as the class, but with 
lowercase first). You define it this way:


auto derived(OutputRange)(auto ref OutputRange writer)
{
auto result = new Derived!OutputRange();
result.writer = writer; // save the writer in a field of the 
object

return result;
}

void main()
{
auto x = derived(stdout.lockingTextWriter);
x.writeString("Hello world");   // the writer is saved in the 
object, no need to pass it

}


Re: Templates problem

2016-09-07 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 7 September 2016 at 11:37:44 UTC, Russel Winder 
wrote:
I'd prefer immutable, but const sometimes has to do. The idea 
is to find out how to enforce single assignment in D.


Everything depends on what you mean by "single assignment".

If you mean "I can't use opAssign", then const is definitely too 
strong. In this case, you can write a simple type wrapper that 
disables opAssign, while providing all other functionalities.


If you mean "Methods do not mutate objects; instead, they return 
new objects, mutated", the issue is deeper. In fact, input ranges 
and output ranges cannot (by definition) fulfill this 
requirement. Other ranges (forward, bidirectional, random) can 
fulfill this requirement, but it's very expensive, as it requires 
a new copy of every range every time you want to popFront or 
popBack. The same goes for every other type with mutable methods. 
If you really want this behaviour, you can easily write (again) a 
type wrapper that forwards every const method call while 
intercepting every mutable method call and applying it to a new 
copy that is returned. But I think it will severely hurt 
performance and readability.


Re: Templates problem

2016-09-07 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 7 September 2016 at 08:19:39 UTC, Russel Winder 
wrote:
On Tue, 2016-09-06 at 14:50 +, Lodovico Giaretta via 
Digitalmars-d- learn wrote:



[…]
 From a quick look, it looks like `results` is a 
`const(TickDuration[3])`, that is a fixed-length array. And 
fixed-length arrays aren't ranges. If you explicitly slice 
them, they become dynamic arrays, which are ranges.


So the solution is to call `map` with `results[]` instead of 
`results`.


So trying with results[] leads to:

run_checks.d(21): Error: mutable method 
std.algorithm.iteration.MapResult!(function (TickDuration t) => 
to(t).total(), const(TickDuration)[]).MapResult.opIndex is not 
callable using a const object
run_checks.d(21): Error: mutable method 
std.algorithm.iteration.MapResult!(function (TickDuration t) => 
to(t).total(), const(TickDuration)[]).MapResult.opIndex is not 
callable using a const object
run_checks.d(21): Error: mutable method 
std.algorithm.iteration.MapResult!(function (TickDuration t) => 
to(t).total(), const(TickDuration)[]).MapResult.opIndex is not 
callable using a const object


yes, the message is repeated three times, for unknown reason. 
Possibly because the compiler is fairly certain I am not going 
to believe it.


So the upshot of this is that I can't work with const data, 
which is dreadful in these days of single assignment being the 
way of doing things.


So what is the way of constructing a range from a const array? 
If it involves copying then D is doomed.


And yes I am under stress as I am trying to pitch D to Python 
people next week.


You have your const fixed-length array. You slice it and you 
obtain a const range to feed map. Now map will not return you an 
array. Because most of the time you don't need it. It will return 
you a range that lazily computes its elements on demand. No 
memory allocation at all. You can do a foreach on that range. If 
you need to access those elements more than once, instead of 
recomputing each of them every time it is accessed, you can store 
the results of the map. You simply have to use .array on the map 
result. This will allocate memory and give you an array with your 
results. Otherwise, no allocation at all. That result array can 
be const, if you want. If you need to access your elements only 
once, there's no need to have an array.


I really don't see what's not working in this.

And by the way, there's no need to put const on everything. An 
optimizing compiler is often able to infer things, especially for 
stack allocated local variables.


Re: Template constraints for reference/value types?

2016-09-06 Thread Lodovico Giaretta via Digitalmars-d-learn
On Tuesday, 6 September 2016 at 20:46:54 UTC, Jon Degenhardt 
wrote:
Is there a way to constrain template arguments to reference or 
value types? I'd like to do something like:


T foo(T)(T x)
if (isReferenceType!T)
{ ... }

--Jon


You can use `if(is(T : class) || is(T : interface))`.

If you also need other types, std.traits contains a bunch of 
useful templates: isArray, isAssociativeArray, isPointer, ...


Re: Templates problem

2016-09-06 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 6 September 2016 at 14:38:54 UTC, Russel Winder wrote:

The code fragment:

const results = benchmark!(run_mean, run_mode, run_stdDev)(1);
	const times = map!((TickDuration t) { return 
(to!Duration(t)).total!"seconds"; })(results);


seems entirely reasonable to me. However rdmd 20160627 begs to 
differ:


run_checks.d(20): Error: template 
std.algorithm.iteration.map!(function (TickDuration t) => 
to(t).total()).map cannot deduce function from argument types 
!()(const(TickDuration[3])), candidates are:

/usr/include/dmd/phobos/std/algorithm/iteration.d(450):
std.algorithm.iteration.map!(function (TickDuration t) => 
to(t).total()).map(Range)(Range r) if (isInputRange!(Unqual!Range))
Failed: ["dmd", "-v", "-o-", "run_checks.d", "-I."]

and I have no idea just now why it is complaining, nor what to 
do to fix it.


From a quick look, it looks like `results` is a 
`const(TickDuration[3])`, that is a fixed-length array. And 
fixed-length arrays aren't ranges. If you explicitly slice them, 
they become dynamic arrays, which are ranges.


So the solution is to call `map` with `results[]` instead of 
`results`.


Re: Inexplicable invalid memory operation when program terminates

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 5 September 2016 at 17:33:17 UTC, pineapple wrote:
I have a program which I have stripped down to a single 
offending line which, when present in my program, causes an 
invalid memory operation to occur after main has evaluated:


import mach.sdl.window;
void main(){
auto win = new Window(300, 300);
}

The program is a bit larger than that, but I do not get the 
error when I comment out that instantiation and the things 
dependent on it.


I commented out the body of the constructor that is being 
called, and I still get the error.


Am I missing something or is this an obnoxious bug with the GC?


InvalidMemoryOperationError is raised when you try to allocate 
memory inside a destructor called by the GC. I see from your 
repository that the destructor of Window uses a function called 
log defined by yourself. That function uses writeln internally. 
writeln is not @nogc, so it may be that that call to log in the 
destructor is actually allocating memory.


Re: Getting the superclass of a type?

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 5 September 2016 at 15:20:10 UTC, pineapple wrote:
I'd like to be able to write something like this, but I haven't 
been able to find anything in the docs


class Base{}
class Sub: Base{}
static assert(is(SuperClassOf!Sub == Base));


https://dlang.org/phobos/std_traits.html#.BaseClassesTuple


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 5 September 2016 at 12:15:35 UTC, dom wrote:

[...]


You misunderstood the error message and the lambda syntax (it 
also happened to me the first time).


The grammar says that you can use one of these syntaxes:

1) `(arguments) {block of code}`

2) `(arguments) => expression`, which is equivalent to 
`(arguments) {return expression;}`


3) `{block of code}`, which is equivalent to `(){block of code}`.

So if you write `(arguments) => {block of code}`, this is 
equivalent to (see rule 2) `(arguments) { return {block of code}; 
}`.


And because of rule 3, it becomes `(arguments) { return (){block 
of code} }`. So what you have is a function that returns a 
function. That's why it does not match your signature.


The fact that the compiler also adds nothrow, @nogc, @safe is not 
important in this case, as those attributes can be implicitly 
casted away.


Re: How it's better to store data from DB?

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 5 September 2016 at 10:00:26 UTC, Suliman wrote:
Usually I am storing daba from DB as array of structures. 
Something like:


struct MyData
{
 int id;
 string name;
 int age;
}

MyData mydata;

Then I am creating array of structures:
MyData [] mydatas;

And fill data in my code. Then append it to `mydatas` to get it 
iterable.


But is it's good? Maybe there there is better way?

I need main -- be able iterate thru the data. Any other 
variants?


It depends on your specific use case. My advice is to try *not* 
to store the data in memory.


I mean, if your first operation on the array is to filter it (but 
that should be done directly in the sql queries) or if you manage 
to do everything while iterating it only once, then you can avoid 
creating the array. Create a range that wraps the query result 
set and iterate it. This way you maintain in memory just one 
element at a time. This is akin to what you usually do in JDBC (I 
used that a lot, while in D I don't have any db experience).


But of course there are cases in which this advice is not 
applicable.


Re: Template-style polymorphism in table structure

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn
On Monday, 5 September 2016 at 06:45:07 UTC, data pulverizer 
wrote:
On Sunday, 4 September 2016 at 14:49:30 UTC, Lodovico Giaretta 
wrote:
Your getCol(i) could become getCol!T(i) and return an instance 
of GenericVector!T directly, after checking that the required 
column has in fact that type:


GenericVector!T getCol!T(size_t i)
{
if(typeid(cols[i]) == typeid(GenericVector!T))
return cast(GenericVector!T)cols[i];
else
// assert(0) or throw exception
}
I just realized that typeid only gives the class and not the 
actual type, so the object will still need to be cast as you 
mentioned above, however your above function will not infer T, 
so the user will have to provide it. I wonder if there is a way 
to dispatch the right type by a dynamic cast or I fear that 
ZombineDev may be correct and the types will have to be 
limited, which I definitely want to avoid!


ZombineDev is definitely correct, in that one thing is the static 
type, and another thing is the dynamic type. The type of a 
variable, or the return type of a method are based on the static 
type, computed at compile time. The "true" dynamic type is only 
available at runtime.


That's why I was showing you the use of tuples. If your code does 
not have branches that assign different column types, having the 
types statically determined as template parameters is the best 
choice.


If you really need dynamic types, then there's no alternative: 
the user must explicitly cast things to the correct dynamic type 
(my version of getCol is just a nice wrapper to do that). In 
fact, idiomatic D code tries to avoid dynamic types when 
possible, preferring templates.


Re: How compiler detects forward reference errors

2016-09-04 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 4 September 2016 at 19:15:15 UTC, Igor wrote:
So, you are saying compiler is keeping a kind of linked list of 
dependencies and then checks if any of those lists are 
circular? But how exactly would that list be structured since 
one expression can have multiple dependencies, like:


enum a = b + c + d + e;
enum b = 10 + c;
enum c = d + e + a;
...


Disclaimer: I don't know how the D compiler works internally. I 
just happen to know how generic compilers usually work.


I think the easiest solution is to keep a stack of what you are 
doing.


So in your last example, we start with evaluating a. We first see 
that a depends on b.
So we switch evaluating b. As we do so, our stack contains a and 
b.


We see that b depends on c. So we switch to evaluate c.
Our stack becomes a, b, c.

We see that c depends on d. So we evaluate d.
Our stack is a, b, c, d.

You didn't give a definition for d. Let's assume it does not 
depend on anything. So we successfully evaluated d. So we get 
back to c.

Our stack is a, b, c.

We see that c also depends on e. So we evaluate e.
Our stack is a, b, c, e.

You didn't give a definition for e. Let's assume it does not 
depend on anything. So we successfully evaluated e. So we get 
back to c.

Our stack is a, b, c.

We see that c also depends on a. So we evaluate a.
Our stack becomes a, b, c, a.

Ops... Our stack contains a two times. This means that to 
evaluate a we need the value of a. So we tell the user that we 
cannot proceed further.


By the way, the stack also tells us how a depends on itself. In 
fact, the stack a, b, c, a tells us that a depends on b which 
depends on c which depends on a.


I hope this is a clear enough explanation. If not, feel free to 
ask further.


Re: Template-style polymorphism in table structure

2016-09-04 Thread Lodovico Giaretta via Digitalmars-d-learn
On Sunday, 4 September 2016 at 14:24:12 UTC, data pulverizer 
wrote:
On Sunday, 4 September 2016 at 14:20:24 UTC, data pulverizer 
wrote:
On Sunday, 4 September 2016 at 14:07:54 UTC, data pulverizer 
wrote:

@Lodovico Giaretta Thanks I just saw your update!


@Lodovico Giaretta BTW what do you mean that my code is not 
very D style? Please expand on this ...


The constructors can be less. In fact, a typesafe variadic ctor 
also works for the single element case and for the array case. 
But you already recognized that.


Instead of reinventing the wheel for your GenericVector!T, you 
could use an `alias this` to directly inherit all operation on 
the underlying array, without having to reimplement them (like 
your append method).


Your getCol(i) could become getCol!T(i) and return an instance of 
GenericVector!T directly, after checking that the required column 
has in fact that type:


GenericVector!T getCol!T(size_t i)
{
if(typeid(cols[i]) == typeid(GenericVector!T))
return cast(GenericVector!T)cols[i];
else
// assert(0) or throw exception
}

Another solution: if you don't need to dynamically change the 
type of the columns you can have the addColumn function create a 
new type. I show you with Tuples because it's easier:


Tuple!(T,U) append(U, T...)(Tuple!T tup, U col)
{
return Tuple!(T,U)(tup.expand, col);
}

Tuple!int t1;
Tuple!(int, float) t2 = t1.append(2.0);
Tuple!(int, float, char) t3 = t2.append('c');


Re: Template-style polymorphism in table structure

2016-09-04 Thread Lodovico Giaretta via Digitalmars-d-learn
On Sunday, 4 September 2016 at 09:55:53 UTC, data pulverizer 
wrote:

[...]


Your code is not very D style and, based on your needs, there may 
be better ways to achieve your goal, but without knowing your use 
case, it's difficult to give correct advice.


Talking about that writeln statement, your code is not working 
because of a known compiler bug [1]. If you change your interface 
BaseVector to an abstract class and add the needed override 
annotation to GenericVector, then typeid returns the expected 
result.


[1] https://issues.dlang.org/show_bug.cgi?id=13833




Re: How compiler detects forward reference errors

2016-09-03 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 3 September 2016 at 14:06:06 UTC, Igor wrote:
Can anyone explain in plain English how does compiler process 
and detect a "test.d(6) Error: forward reference of variable a" 
in following code:


import std.stdio;

enum a = 1 + b;
enum d = 5 + a; // No error here
enum b = 12 + c;
enum c = 10 + a; // error here

void main()
{
writeln("Hello World!", b);
}


a needs b to be initialized. So b must be initialized before a. 
Let's write this b->a. Now b needs c. So c->b. c needs a, so 
a->c. If we sum everything, we have that a->c->b->a. This mean 
that to initialize a we need b, to initialize b we need c, but to 
initialize c we need a. So to initialize a we need a, which is 
not possible. We need a before having initialized it.


On the other hand, a->d is not a problem, as d can be initialized 
after a.


Re: InterlockedIncrement, InterlockedCompareExchange, etc

2016-08-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 28 August 2016 at 21:52:48 UTC, Illuminati wrote:
The interlocked functions generate memory barriers, does 
atomicOp do that?


Also D doesn't seem to have a volitile keyword anymore which is 
required to prevent the compiler from prematurely optimizing 
critical code.


I'm under the impression that atomicOp does not generate memory 
barriers. In fact, in its implementation, it uses atomicLoad with 
relaxed memory ordering.


There is however a function in core.atomic to generate a full 
memory barrier, if you need it.


By the way, can I ask you why you need this? Is it for low-level 
data sharing or for hardware access? If it is for low-level data 
sharing, then you probably don't need volatile, as shared should 
be enough. If it is for hardware access, the situation is more 
complex, but I'm sure I've seen some threads about how to 
implement Volatile!T in a few lines of code recently.


Re: InterlockedIncrement, InterlockedCompareExchange, etc

2016-08-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 28 August 2016 at 19:53:51 UTC, Illuminati wrote:

What are the D equivalents to these types of functions?

I do not see anything in core.atomic that can accomplish this. 
I have tried to include core.sys.windows.winbase but still get 
linker errors(I've also directly tried importing kernel32 using 
various methods and still nothing). Regardless, would be nicer 
to have a more portable solution.


I'm not an expert in this field (so probably I'm missing 
something), but I would think that InterlockedIncrement could be 
done with atomicOp!"+"(val, 1) and InterlockedCompareExchange 
with cas.


Re: __traits(getOverloads, Type, member) order of elements in tuple.

2016-08-22 Thread Lodovico Giaretta via Digitalmars-d-learn
On Monday, 22 August 2016 at 12:14:41 UTC, Alexandru Ermicioi 
wrote:

Good day.

In current implementation of dmd/ldc/gdc, does this trait 
guarantee, that the order of elements returned in tuple, is 
same, in several calls of it on same Type and member?


Also, is guaranteed that in future versions of dmd, the order 
of elements won't change?


The official spec [1] does not state anything about this, but for 
other similar traits it says that the order is not defined and 
should not be relied upon, so I'm inclined to think that 
getOverloads works that way too.


Definitely worth an enhancement request, to document this thing.

[1] https://dlang.org/spec/traits.html


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 21 August 2016 at 20:36:54 UTC, Engine Machine wrote:
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta 
wrote:

[...]


You're right. I didn't realize that variables could be shadowed 
in classes. Seems dangerous. D doesn't allow shadowing in a 
normal context and gives an error so I don't know why it 
wouldn't do that in classes. (since it wasn't giving an error I 
thought it wasn't shadowing)


You are right. It is very bad. But as far as I know Java and C++ 
allow this too.
I will open an enhancement request (if there's none about this), 
to gather some feedback on the matter.


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta 
wrote:

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:

[...]


The problem of this code has nothing to do with aliases. They 
work correctly. The problem is variable shadowing. In the 
following code, Child has two x variables, one of which is only 
accessible from a Parent reference, the other only from a Child 
reference.


class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}

void main()
{
Child child = new Child();
Parent parent = child;

child.x = child.y = 3;
parent.x = 2;

assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);

assert(parent is child); // same object (remember that a 
class is already a pointer);
assert( != ); // but there are two different 
pointers on the stack (pointing to the same object)

}


A patch to your code that makes it work, with the parts not 
displayed unchanged:


class base
{
int x;
}

class T(A...) : Rebind!(T!A, EraseLast!A)
{
static if(A[$-1] == "Animal")
int y;
else static if (A[$-1] == "Dog")
int z;
else static if (A[$-1] == "Pug")
int s;
}


Re: Rebind template(bug?)

2016-08-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:

[...]


The problem of this code has nothing to do with aliases. They 
work correctly. The problem is variable shadowing. In the 
following code, Child has two x variables, one of which is only 
accessible from a Parent reference, the other only from a Child 
reference.


class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}

void main()
{
Child child = new Child();
Parent parent = child;

child.x = child.y = 3;
parent.x = 2;

assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);

assert(parent is child); // same object (remember that a 
class is already a pointer);
assert( != ); // but there are two different 
pointers on the stack (pointing to the same object)

}



Re: compile error while use `extern(C++, class)`

2016-08-18 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 18 August 2016 at 16:19:41 UTC, Johan Engelen wrote:
On Thursday, 18 August 2016 at 11:43:03 UTC, Lodovico Giaretta 
wrote:
Which compiler version are you using? On DMD 2.071.0 this does 
not work.


Note: this does work with LDC 1.1.0 even though it is based on 
DMD 2.071.


https://github.com/ldc-developers/ldc/releases/tag/v1.1.0-beta2


Well, LDC 1.1.0 is based on DMD 2.071.1, while I tested the above 
code on asm.dlang.org with DMD 2.071.0, so maybe on DMD 2.071.1 
it works too. On nightly it works for sure.
So again nothing wrong here, just a matter of having the most 
recent compiler version.


Re: compile error while use `extern(C++, class)`

2016-08-18 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 18 August 2016 at 11:11:10 UTC, mogu wrote:
On Thursday, 18 August 2016 at 10:45:14 UTC, Lodovico Giaretta 
wrote:


Which kind of error? An error message by the compiler? One by 
the linker? The compiler crashes?




Compiler Error exactly. The minimal code is(dmd or ldc2 in 
ubuntu 16.04 lts):

```
extern (C++, struct)
class A {}
```

Error: identifier expected for C++ namespace found 'struct' 
when expecting ')' declaration expected, not ')'


Which compiler version are you using? On DMD 2.071.0 this does 
not work. On nightly build it compiles without errors. So 
probably it is a feature that is present, but didn't ship yet. I 
suggest you download the latest beta or a nightly build from the 
site.


Re: Sequence separation

2016-08-17 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 17 August 2016 at 19:15:48 UTC, ag0aep6g wrote:

On 08/17/2016 08:38 PM, Engine Machine wrote:
On Wednesday, 17 August 2016 at 08:37:32 UTC, Lodovico 
Giaretta wrote:

[...]

You mean something like:

struct MySequence(Args...)
{
enum length = Args.length;
alias args = Args;
}

alias x = MySequence!(a, b, MySequence!(c, d));

static assert(x.length == 3)
static assert(x.args[2].length == 2);


Thanks, basically works.

How can I test, though, if a argument uses a MySequence? I 
can't do if
(Args[0] == MySequence) because MySequence is templated. While 
I could
test for a length, that doesn't work because some types have a 
length. I

could add another enum to MySequence, but again, not safe.

I could do some string tests, but that doesn't work.

in your exmaple,

if (x.args[2] == MySequence) ??

I simply need to differentiate between a parameter/arg being a
MySequence and not.


With MySequence being a type, you can do this:


static if (is(x.args[2] == MySequence!Args, Args ...))
{
  ...
}


Aside from this check, there is probably not much use for 
MySequence being a type. So I'm be tempted to find a way to do 
the check with a raw template MySequence.


import std.traits: TemplateOf;
static if (__traits(isSame, TemplateOf!(x.args[2]), MySequence))
{
...
}

std.traits.TemplateOf extracts the symbol representing the 
uninstantiated template.


__traits(isSame, symbol1, symbol2) evaluates at compile time to 
true if and only if the two symbols represent the same thing (be 
it a type, an uninstantiated template, an instantiated one or 
whatever else).


Re: having a trivial anonymous function call in template prevents compilation?

2016-08-17 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 17 August 2016 at 13:21:16 UTC, Cauterite wrote:
On Wednesday, 17 August 2016 at 13:18:06 UTC, Adam D. Ruppe 
wrote:
Best you can do is use them in an alias argument directly, but 
you cannot use them in an enum argument.


I think you missed the point; it works perfectly fine without 
having this `({return 0;})()` in the template body (which, as 
far as I can see, doesn't appear to interact at all with the 
template argument).


I think he meant that  ({ return 0;})() cannot be executed at 
compile time and assigned to an enum. That's why the 
instantiation is failing.


Re: Sequence separation

2016-08-17 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 16 August 2016 at 23:18:28 UTC, Adam D. Ruppe wrote:
On Tuesday, 16 August 2016 at 19:17:27 UTC, Engine Machine 
wrote:

alias x = AliasSeq!(a, b, AliasSeq!(c, d));

results in a flat sequence. I would like to be able to keep 
them separate so I can have sub sequences.


wrap them in a struct.


You mean something like:

struct MySequence(Args...)
{
enum length = Args.length;
alias args = Args;
}

alias x = MySequence!(a, b, MySequence!(c, d));

static assert(x.length == 3)
static assert(x.args[2].length == 2);


Re: Template type reduction

2016-08-16 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 16 August 2016 at 19:23:51 UTC, Engine Machine wrote:
On Tuesday, 16 August 2016 at 17:39:14 UTC, Lodovico Giaretta 
wrote:
On Monday, 15 August 2016 at 19:31:14 UTC, Engine Machine 
wrote:

[...]


I don't know if this is exactly what you want:

=
import std.traits: hasMember;

struct Q(T)
if (hasMember!(T, "x"))
{
T s;

@property auto x() { return s.x; }
}
auto makeQ(T)(auto ref T val)
{
return Q!T(val);
}

auto s = myTypeWithFieldX();
auto q = makeQ(s);
assert(q.x == s.x);
=

`Q` can store any type with an `x` field and gives access to 
it. The auxiliary function `makeQ` acts as a constructor for 
`Q` with template parameter deduction.


I realize now that D simply cannot do what I ask directly 
because It's type parameters are part of the type. It can't be 
told that in some cases they are not. Any use of the 
parameters, as I am using them, will result in this issue.


I'm now trying a different method which builds the based types 
using partial oop and partial CT code. The CT code is only for 
performance and convenience anyways.


You are right in that it is not possible to strip part of the 
type informations.


The only problem is Q is still defined by T. Your makeQ then 
requires the type implicitly, which I don't necessarily have. 
You've simply added complexity to the problem but the issue is 
still there.


How is it possible that you don't have T? Your variable will 
surely have a type! Can you provide more background? Because 
maybe I'm not completely getting your point here...


Re: Template type reduction

2016-08-16 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 15 August 2016 at 19:31:14 UTC, Engine Machine wrote:

Suppose I have a templated type like

struct S(T) { int x; static if (T is Y) int y; }

I would like to be able to create a reference to S(T) for any T,

struct Q
{
  S!* s; // Can hold any type of S.
}

and be able to access s.x, since it is common to all S.

Can D do anything like this? It is sort of like runtime 
inheritance, but at the compile time level.


I do not want to have to cast to S!T every time just to access 
x, e.g.,


struct Q
{
   Object s;
}

which is too general as s can be things that are not of type 
S!*.



Is this possible?


I don't know if this is exactly what you want:

=
import std.traits: hasMember;

struct Q(T)
if (hasMember!(T, "x"))
{
T s;

@property auto x() { return s.x; }
}
auto makeQ(T)(auto ref T val)
{
return Q!T(val);
}

auto s = myTypeWithFieldX();
auto q = makeQ(s);
assert(q.x == s.x);
=

`Q` can store any type with an `x` field and gives access to it. 
The auxiliary function `makeQ` acts as a constructor for `Q` with 
template parameter deduction.


Re: Converting a Visual Studio Solution with many Projects into DUB package?

2016-08-16 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 16 August 2016 at 15:46:23 UTC, WhatMeWorry wrote:


I've got a large Visual Studio Solution which contains lots of 
Projects.  Each project is a standalone D/OpenGL tutorial.  I 
want to make it OS and IDE agnostic so it can be easily played 
with on Windows, Linux, and Mac OS so I thought it best to make 
it a dub package.


I've been reading the DUB documentation but can't seem to find 
a way. So in short, does DUB allow something like sub-packages?

 Or collections of packages?

No is fine.  I just wanted to check before I go off and create 
a flat file system of dub packages.


I think you are looking for this:
https://code.dlang.org/package-format?lang=json#sub-packages


Re: new XML and JSON libs and replacement of std.net.curl

2016-08-15 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 15 August 2016 at 15:01:13 UTC, Oleg B wrote:

Hello.
In std.xml docs I read that is deprecated, [...]

For XML I found this project 
https://github.com/lodo1995/experimental.xml. Is this really 
candidate to std, or author just called it as he want?


Hi!
I'm the developer of that XML library. It is still under heavy 
development, so if you decide to use it and find any problem, 
feel free to contact me on GitHub. Feedback from actual usage is 
very important to understand what needs more work. Thank you.


As a side note, the GSoC is almost over, so the iter for 
inclusion in Phobos should start soon.


Re: Retreive method given object, name and arguments

2016-08-11 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 11 August 2016 at 20:27:51 UTC, Michael Coulombe 
wrote:
Is there a way to implement "getSymbolOfCall" and 
"getDelegateOfCall" such that doit is functionally equivalent 
to calling the method directly?


auto doit(C, string methodName, Args...)(C c, Args args) {
alias methodSymbol = getSymbolOfCall!(c, methodName, Args);
pragma(msg, hasUDA!(methodSymbol, "my attr"));
auto dg = getDelegateOfCall!(c, methodName, Args);
return dg(args);
}

They should deal with getting the right overload, 
opDispatch-ing, and deducing template arguments from the real 
argument list to get a concrete delegate pointer. methodSymbol 
should give access to compile-time introspection like full 
signature and UDAs.


The ability to do this for non-member functions would be cool 
too, but is beyond my use case.


Maybe I'm not understanding correctly, but I think you can use 
string mixins:


auto doit(string methodName, C, Args...)(C c, Args args)
{
mixin("return c." ~ methodName ~ "(args);");
}


Re: Template parameters that don't affect template type

2016-08-11 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:

[...]


If, in your case, it is possible to use one type as the other, 
then specify it.
I mean, implement a templated opAssign that allows you to assign 
values of one instantiation to values of another. While doing so, 
remember that this will not change the behaviour of the 
assigned-to variable, but will only transfer the runtime state 
from one variable to the other.


struct S(T1, T2)
{
T1 t;
void opAssign(T)(auto ref S!(T1, T) other)
{
t = other.t;
}
}
unittest
{
S!(int, float) x(1);
S!(int, char) y(3);

x = y;
assert(x.t == 3);// the value 
of x is changed
static assert(is(typeof(x) == S!(int, float)))   // the type 
of x isn't changed

}




Re: Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 10 August 2016 at 21:00:01 UTC, Lodovico Giaretta 
wrote:
On Wednesday, 10 August 2016 at 20:54:15 UTC, Steven 
Schveighoffer wrote:

[...]


Wow. Thanks. I didn't know the compiler would try opSlice. I 
will file it.


Filed on bugzilla:

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


Re: Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 10 August 2016 at 20:54:15 UTC, Steven 
Schveighoffer wrote:

On 8/10/16 2:08 PM, Lodovico Giaretta wrote:

[...]


The issue is that it tries using [] on the item to see if it 
defines a range-like thing. Since you don't define opSlice(), 
it automatically goes to the subrange.


This breaks for int[] as well as Array.

If I add opSlice to your code (and return this) it works.

This is definitely a bug, it should try range functions before 
opSlice. Please file.


-Steve


Wow. Thanks. I didn't know the compiler would try opSlice. I will 
file it.


Re: Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 19:37:39 UTC, Ali Çehreli wrote:
A quick read reveals popFront() is implemented only for bool 
Arrays. That explains the issue.


I don't know whether it's an oversight.

Ali


First of all, thank you for spending your time on this issue. I 
really appreciate that.


I may be reading that code wrong but...
Isn't popFront implemented for every type here?
https://github.com/dlang/phobos/blob/master/std/container/array.d#L128


Re: Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 18:38:00 UTC, Ali Çehreli wrote:
RangeWrapper does not provide the InputRange interface, so the 
compiler uses 'alias this' and iterates directly on the member 
range.


I tried making RangeWrapper an InputRange but failed. It still 
uses 'range'.


// Still fails with these:
@property bool empty() {
return range.empty;
}

void popFront() {
range.popFront();
}

I don't know how the decision process works there.

Ali


That's strange, as RangeWrapper works correctly if instantiated 
with any underlying range EXCEPT std.container.Array.
Also, RangeWrapper does provide the InputRange interface, 
partially directly and partially with alias this. RangeWrapper 
should be "opaque", as it should not matter whether the methods 
needed for the InputRange interface are defined directly or 
inherited with alias this.


Re: Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 10 August 2016 at 18:08:02 UTC, Lodovico Giaretta 
wrote:

I'm probably missing something stupid but...
Why on earth do the two loops in main print a different result?
It looks like the foreach lowering is ignoring my definition of 
front...


=
import std.stdio, std.container.array;

struct RangeWrapper(Range)
{
Range range;
alias range this;

auto front()
{
return range.front + 1;
}
}
auto rangeWrapper(Range)(auto ref Range range)
{
return RangeWrapper!Range(range);
}

void main()
{
Array!int array;
array.insertBack(3);

foreach (i; rangeWrapper(array[]))
writeln(i);   // prints 3, which is wrong

// isn't the above foreach equivalent to the following 
loop ?


for (auto r = rangeWrapper(array[]); !r.empty; r.popFront())
writeln(r.front); // correctly prints 4
}
=

Thank you for your help.


This actually only happens with std.container.Array. Other ranges 
are ok. Even stranger...


Unexpected foreach lowering

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

I'm probably missing something stupid but...
Why on earth do the two loops in main print a different result?
It looks like the foreach lowering is ignoring my definition of 
front...


=
import std.stdio, std.container.array;

struct RangeWrapper(Range)
{
Range range;
alias range this;

auto front()
{
return range.front + 1;
}
}
auto rangeWrapper(Range)(auto ref Range range)
{
return RangeWrapper!Range(range);
}

void main()
{
Array!int array;
array.insertBack(3);

foreach (i; rangeWrapper(array[]))
writeln(i);   // prints 3, which is wrong

// isn't the above foreach equivalent to the following 
loop ?


for (auto r = rangeWrapper(array[]); !r.empty; r.popFront())
writeln(r.front); // correctly prints 4
}
=

Thank you for your help.


Re: Template method in interfaces

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 15:54:42 UTC, Adam D. Ruppe wrote:
On Wednesday, 10 August 2016 at 15:48:10 UTC, Lodovico Giaretta 
wrote:
I read the spec again, and found out that it says interfaces 
cannot contain templated functions... So either my 
interpretation is the intended one and the spec is outdated, 
or the spec is right and the compiler is bugged.


Spec must be out of date, I remember this being a conscious 
decision to add them.


Last line of this page: 
https://dlang.org/spec/template.html#limitations


I'll file a bug report for this and an enhancement request for 
implicit final in interfaces.


Re: Template method in interfaces

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn
On Wednesday, 10 August 2016 at 15:48:10 UTC, Lodovico Giaretta 
wrote:

On Wednesday, 10 August 2016 at 15:39:19 UTC, Arafel wrote:
Would it even make sense to "force" (deprecation warning) a 
"final" keyword in any implicitly-final function (I wasn't 
even aware of those, I have to admit)? It would make things 
much clearer, like with "override"...


I read the spec again, and found out that it says interfaces 
cannot contain templated functions... So either my 
interpretation is the intended one and the spec is outdated, or 
the spec is right and the compiler is bugged.


Anyway what I said about implicit final is true for classes. In 
classes, I don't like the idea of having to put an explicit 
final, but this is debatable. For interfaces, I'm ok with forcing 
an explicit final attribute (but as I said the spec does not 
allow templated functions in interfaces, even if the compiler 
does).


Re: Template method in interfaces

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 15:39:19 UTC, Arafel wrote:
On Wednesday, 10 August 2016 at 15:25:40 UTC, Lodovico Giaretta 
wrote:
Because templated functions cannot be virtual, it follows that 
I.func is final. Having no body, the compiler thinks that its 
body will be found by the linker in another object file, but 
this does not happen, so the linker complains.
Being I.func final, C.func just hides it, so you would not 
incur any problem if you called func explicitly on an object 
of type C.


So what you found is not a bug, but some unintuitive behaviour 
due to templated functions being implicitly final and forward 
declarations. Maybe the compiler should emit a warning about 
implicitly-final functions in interfaces.


Would it even make sense to "force" (deprecation warning) a 
"final" keyword in any implicitly-final function (I wasn't even 
aware of those, I have to admit)? It would make things much 
clearer, like with "override"...


I read the spec again, and found out that it says interfaces 
cannot contain templated functions... So either my interpretation 
is the intended one and the spec is outdated, or the spec is 
right and the compiler is bugged.


Re: Template method in interfaces

2016-08-10 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 10 August 2016 at 15:20:37 UTC, Arafel wrote:
I'm not sure if the following is even expected to work, since 
I'm not sure how the vtable for the interface would look like 
(well, that would be applicable to any overriden templated 
method, though):


---
public interface I {
void func(T)(T t);
}

public class C : I {
void func(T)(T t) {
}
}

void main() {
I i = new C();
i.func(1);
}
---

But since the error I get is in the linker, and not in the 
compiler, I guess that's somehow a bug? Or how should it work 
then?


https://dpaste.dzfl.pl/7a14fa074673

/d31/f76.o: In function `_Dmain': 
/d31/f76.d:(.text._Dmain+0x24): undefined reference to 
`_D3f761I11__T4funcTiZ4funcMFiZv' collect2: error: ld returned 
1 exit status --- errorlevel 1


PS: Now I see [1] that it shouldn't, so perhaps the compiler 
should reject templated methods in interfaces from the 
beginning?


[1]: http://forum.dlang.org/post/jg504s$1f7t$1...@digitalmars.com


Because templated functions cannot be virtual, it follows that 
I.func is final. Having no body, the compiler thinks that its 
body will be found by the linker in another object file, but this 
does not happen, so the linker complains.
Being I.func final, C.func just hides it, so you would not incur 
any problem if you called func explicitly on an object of type C.


So what you found is not a bug, but some unintuitive behaviour 
due to templated functions being implicitly final and forward 
declarations. Maybe the compiler should emit a warning about 
implicitly-final functions in interfaces.


Re: When I should to call destroy?

2016-07-29 Thread Lodovico Giaretta via Digitalmars-d-learn

On Friday, 29 July 2016 at 13:18:00 UTC, Suliman wrote:
Use the `destroy` function to finalize an object by calling its 
destructor. The memory of the object is not immediately 
deallocated, instead the GC will collect the memory of the 
object at an undetermined point after finalization:


class Foo { int x; this() { x = 1; } }
Foo foo = new Foo;
destroy(foo);
assert(foo.x == int.init);  // object is still accessible


But I can't understand if D have GC it should remove objects 
when their life is finished. When I should to call `destroy`? 
What would be if I will not call it?


Destroy will call the destructors, but memory will not actually 
be deallocated before the next GC cycle. It is used because the 
GC cycle does not guarantee to run the destructors, so using 
destroy the destructor is ran immediately (guaranteed). Then, on 
next GC iteration, the memory will be freed. Until then, 
referencing it will not cause segfault, but will cause undefined 
behaviour, as after a destructor the state of the object is 
undefined (I think).


Re: Question about destructor of database and multiple use access

2016-07-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 28 July 2016 at 15:24:22 UTC, Dechcaudron wrote:
On Thursday, 28 July 2016 at 15:18:24 UTC, Lodovico Giaretta 
wrote:
3) at program end, live objects are not scheduled for 
finalization;
4) at program end, pending finalizations from previous 
collections may not be run.


I didn't know these two, can I get source on them?


I don't have any specific knowledge about the D collector, but it 
is my understanding that most collectors out there work this way, 
because it would be very expensive and bug-prone to do otherwise 
(remember that destructors may do things like get stuck in a loop 
or "resurrect" themselves or other collected objects).


Also, I'm assuming what I said about calling destroy(instance) 
is as correct as calling a cleanup method?


Yes, I think so.


Re: Question about destructor of database and multiple use access

2016-07-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 28 July 2016 at 15:02:58 UTC, Dechcaudron wrote:
On Thursday, 28 July 2016 at 14:43:32 UTC, Lodovico Giaretta 
wrote:
No! Never run important finalization in a class destructor! 
The GC is not obliged to run the destructors, so you may end 
up with your objects destroyed but the connections still open. 
For this kind of important things, you have to do them 
manually.


I always thought that the moment of finalization is 
undetermined, but that the GC does indeed run the destructor... 
Weird, I'll have to look into that. After all what would be the 
point of destructors if they are not guaranteed to be run?


The collector does not immediately finalize objects. It just 
schedules them for finalization at a later time. So:
1) If you don't get low on memory, no collection is performed, so 
no object is scheduled for finalization;
2) even if a collection is performed, false pointers may prevent 
some unreachable object from becoming garbage and being scheduled 
for finalization;
3) at program end, live objects are not scheduled for 
finalization;
4) at program end, pending finalizations from previous 
collections may not be run.


Re: Question about destructor of database and multiple use access

2016-07-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 28 July 2016 at 14:33:26 UTC, Dechcaudron wrote:

On Thursday, 28 July 2016 at 14:01:45 UTC, Suliman wrote:

2. Should I call destructor and how it's should like?
You certainly want to close the connection to the db. 
Basically, the destructor is intended to free resources such as 
dynamic memory, closing connections... the GC will take care of 
dynamic memory, but closing the connection to the DB is up to 
you. So do that in the destructor.


No! Never run important finalization in a class destructor! The 
GC is not obliged to run the destructors, so you may end up with 
your objects destroyed but the connections still open. For this 
kind of important things, you have to do them manually.
This is true of all major programming languages: JDBC (Java DB 
framework, one of the most used in the world) requires calling 
explicit methods to close connections, statements and result 
sets, because the GC cannot be relied upon. The same goes for C# 
sql library.


Re: Autodecode in the wild and An Awful Hack to std.regex

2016-07-28 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 28 July 2016 at 09:10:33 UTC, Kagamin wrote:
Create an RFE? Given that regex returns results as slices of 
the input string, using the replacement character doesn't 
introduce data corruption.


(RFE = Request For Enhancement, right?)
Yes, all algorithms that use decode internally shall provide a 
template parameter to useReplacementDchar. There's no reason not 
to expose this option, given that it allows not to brutally abort 
any computation in such situations, and also has the bonus point 
of making decode @nogc.


Re: Cannot compare object.opEquals is not nogc

2016-07-24 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 24 July 2016 at 15:31:28 UTC, lqjglkqjsg wrote:
Almost off topic but I've recognized a typical error here, I 
think that many of us have already seen it too. You develop a 
nice class. You put attributes everywhere @safe pure nothrow 
@nogc. Yay the unittest pass.


Later you use it for real and you realize then that the 
attributes must be removed because you can't do anything in the 
overriden methods.


That's why I'm against putting @nogc on Object.
You must only annotate specific sub-hierarchies that you know 
will never need the GC (or whatever: @system, impure, throwing). 
This often means that you can only annotate closed hierarchies. 
This is correct: you must not annotate open ended classes unless 
you decide that you really NEED (NEED != WANT) these limitations. 
And your users will probably find them restrictive, so you need a 
compelling reason that cannot be solved in other ways.


Re: Cannot compare object.opEquals is not nogc

2016-07-24 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 24 July 2016 at 15:28:53 UTC, Jonathan Marler wrote:
Whoa wait a second...I didn't know you could do this.  I 
thought everything had to inherit from the object class.  Can 
you share the syntax to define a class that doesn't derive from 
object?


Currently, you cannot. Everything inherits from Object. I 
personally think this is not the best idea. But it's not that 
horrible either, so probably not worth a big change.


But you can just ignore it. You can put on your opCmp all the 
attributes you want and forget about it inheriting from Object. 
You can decide to never write a method that takes Object. Always 
take the root of your sub-hierarchy, so that you know what 
attributes you have.
If it derives from Object or not, nobody cares as long as your 
sub-root overrides all opXXX with new (even abstract) 
declarations that have @nogc.


Re: Cannot compare object.opEquals is not nogc

2016-07-24 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 24 July 2016 at 14:54:11 UTC, Jonathan Marler wrote:
I believe Rufus was only referring to the virtual methods 
defined in the object class.  That would be:


toHash (Note: this is already nothrow, that's intersting and 
quite restrictive)

opCmp
opEquals

I think all 3 of these are good candidates for @nogc.  However, 
AFAIK, making them @nogc would break any code that implements 
them because they would have to add the @nogc attribute to 
their implementations (unless I am mistaken?  Do subclass 
overrides need to explicitly have @nogc if the parent class 
does?).  If adding @nogc is not required in the implementation, 
then the only code that would break would be implementations 
that actually do allocate GC memory.


Some would think that restricting GC usage inside these virtual 
methods is a good thing because it has the benefit of 
discouraging memory allocation for these types of operations.  
Really, you probably shouldn't be allocating memory to perform 
a comparison.  If you really need to, you can either allocate 
non GC memory, or use a different mechanism then the 
opCmp/opEquals methods.


Yes, making them @nogc would require all existing overrides to be 
changed (overrides cannot throw away attributes, but must specify 
them explicitly as in the parent class, or stricter).
The real problem making these @nogc is that with the current 
state of things @nogc implies nothrow, thus preventing exceptions 
(of course we should work to change this thing, and I'm 
personally researching convenient ways of doing it; I'll soon 
write a post on General about this).


Remember that comparison of complex objects may require 
normalization, which may change the objects themselves and 
allocate memory. Also, comparisons may throw exceptions that need 
the GC (see above). So I'm personally against making those 
methods @nogc.


But I'm also against a singly-rooted hierarchy. Removing Object 
and having multiple class hierarchies would entirely solve the 
issue. But please note that you can already "do" that: if you 
never use Object, but always subclasses, the fact that Object 
isn't @nogc is no longer an issue. While Object (if it exists) 
must support any kind of descendant (and thus cannot pose 
arbitrary limitations like @nogc is), the roots of 
domain-specific hierarchies can exploit the fact that they are 
domain-specific to impose meaningful limitations, based on the 
expected usage and behaviour, and can thus be @nogc. And you can 
either limit your algorithm inputs to objects of a specific 
hierarchy or, if you want it generic, use a template (read as: 
you don't use Object explicitly, as if it doesn't exists).


Re: Cannot compare object.opEquals is not nogc

2016-07-24 Thread Lodovico Giaretta via Digitalmars-d-learn

On Sunday, 24 July 2016 at 02:17:27 UTC, Rufus Smith wrote:
This just isn't right. What your saying is that because someone 
screwed up, we must live with the screw up and build everyone 
around the screw up. This mentality is why everyone is so 
screwed up in the first place, do you not see that?


And I think you really have a misconception about the GC vs 
nogc. One can rewrite GC code, such as an GC based opEquals, 
without limitations. They can allocate on the stack, use malloc 
and free when done, etc. opEquals generally doesn't have state. 
So you it is possible to around around. It's probably always 
possible to rewrite a GC opEquals to use nogc without too much 
difficulty.


Now you are telling me to "program by trust", because there's 
nothing ensuring that I remember to free everything I allocated 
with malloc/free, while a GC would guarantee no memory leaks. 
Again there's nothing stopping me from returning pointers to 
things allocated on the stack. And now there are lots...
Before you told me that programming by trust is a wrong attitude, 
and now you propose me to use it, risking memory leakage in a 
function that may be executed hundreds of times per second.


BUT, it is impossible to use a GC opEquals in nogc code! This 
means there is no work around. What you claim is that we accept 
the impossiblity(which makes nogc useless) just to avoid having 
to rewrite some GC opEquals code. We can't rewrite the nogc 
side, it's set in stone. We are screwed from the start when we 
attempt to do nogc code because at some point we will have to 
do comparisons. It's the same problem with purity and any other 
transitive relationship.


All "workarounds" are just as limited because basically we 
added the relationship if A is nogc and A uses B, then B must 
be nogc. Yet, we start with B is GC. Hence we never ever have A 
use B, because A's can only use nogc.


To see it simpler, What if everything in D was GC based. All 
code was marked GC(even statements, types, etc). Do you agree 
that nogc would be absolutely useless? We couldn't build up 
anything because we couldn't include any code. This is the 
extreme case.


Conversely, if everything was built up using nogc, we could 
write GC based code just fine, could we not?


No. If you put a big @nogc attribute on Object.opXXX, then nobody 
can write GC code in his classes. So if everything is @nogc, you 
cannont write GC code, because it woudn't interact with Phobos. 
Example: if you mark an algorithm that takes a delegate @nogc, 
then you cannot pass GC delegates to it. So you cannot use it in 
GC code.


Therefore, claiming that we stay with GC based code just 
prevents using more and more nogc code. The more GC based code 
D gets, the less useful nogc gets and we are back were we 
started.


Since nogc is more critical in the foundational layers, as it 
affects everything built on it, all core features should be 
nogc. This way, the user isn't can decide when to break away 
from the GC code, which will only affect everything after that 
point.


Yes. All building blocks must be as much @nogc as possible. But 
customization points (virtual functions, delegate arguments, ...) 
must not be @nogc, otherwise it is no possible to have classes 
that use the GC or callbacks that use the GC.


This is a one way street, pretending it is two way only 
enriches the lawyers and eventually makes everyone unhappy. 
Making the D dependent on the GC was a mistake that many wasted 
man hours will go in to trying to unravel.  Trying to carry on 
this mistake just wastes more hours.


I understand that it is a mess, but it got that way from the 
mistake in the first place, not from trying to undo the 
mistake(which is illogical because there would be no nogc if 
there wasn't a gc in the first place).  I also understand that 
there is some desire to keep things "backwards compatible". 
This is also a mistake, not only does it prolong the pain and 
suffering but is irrational. 1. A fork can be made. Those 
people that have based their code on the GC can continue using 
an older version. Their code works at that point, does it not? 
So just stop going down that dead end path. They have what they 
need, it's not like they will lose anything(virtually nothing 
except in most cases). Moving in the correct direction is 
always better, regardless of who's panties get in a wad.


I still don't understand why you want Object.opXXX @nogc. As I 
already said, you can still make your functions @nogc, just 
accepting parameters of @nogc types. It's obvious. If I wrote a 
wonderful library that uses the GC, you will not use it. If I 
have a class that uses the GC in opXXX (and I am free to have it, 
because maybe I need it, and maybe it's the most efficient way 
for my use case), you will not use it. The same applies here. 
You'll have your algorithms work only on classes that declare 
opXXX as @nogc.


Not all memory allocation patterns are good for malloc/free. Not 
all of them 

Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 23 July 2016 at 21:44:05 UTC, Rufus Smith wrote:
On Saturday, 23 July 2016 at 17:27:24 UTC, Lodovico Giaretta 
wrote:
- we trust what we are doing: e.g. we cannot mark a thing 
@nogc, but we know it is and the profiler confirms that no 
allocation happens, so we are happy; our aim is having code 
that doesn't freeze because of collections, and not marking 
code @nogc.


This is bad. It only creates a faulty foundation. The whole 
point of nogc is to enforce nogc behavior. If you don't use it 
your not enforcing anything and then things slip by only to 
create problems later. This mentality is completely wrong and 
leads to decay.


While you are right on this, we must be pragmatical: we currently 
do not enforce that pointers point to valid memory locations, 
that private members are not accessed outside the module with 
tricky arithmetics, we have tons of things that work by 
convention, because the compiler simply can't check them all and 
some are even intrinsically uncheckable. In this environment of 
"code by trust", @nogc is the least of the problems, also 
because, I insist, it can be checked with the profiler, or you 
can plug a custom GC to druntime that asserts every time you try 
to call its functions (work is being made to make the GC 
independent and pluggable).


This is exactly why we are discussing this right now, because 
someone decided that it was ok to ignore other use cases which 
eventually turn out to be quite important.


Well, I think that deciding that opXXX must always be @nogc, 
ignoring other use cases that may need the GC, is blatantly 
wrong. By asking that Object.opXXX be @nogc, you are making the 
error the error you said others made.


Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 23 July 2016 at 21:44:05 UTC, Rufus Smith wrote:
Templates are not the end all be all. They don't allow for 
run-time polymorphism, which is an important aspect of software.


Ok, so you need runtime polymorphism. And you want it in @nogc 
code. That's not difficult. Just have the base class of your 
hierarchy declare its opXXX @nogc. This is possible, because 
non-@nogc functions can be overridden by @nogc ones (as logical). 
Now you can have your function accept parameters of your base 
class, and it will be @nogc. And without forcing every class of 
the D world to have opXXX @nogc.

I don't see why this wouldn't be enough...


Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 23 July 2016 at 17:04:42 UTC, Jonathan Marler wrote:
On Saturday, 23 July 2016 at 16:46:20 UTC, Jonathan Marler 
wrote:

[...]


Actually Im going to disagree with myself. This technique 
actually wouldn't work with virtual methods:)


I don't think we have the big problems with @nogc that people 
points out.


I mean, we cannot decide that specific methods or opXXX must 
always be @nogc. That's too restrictive.


So, what we need to do is:

- use templates: with them, we can have our algorithms be @safe 
when applied to @safe types, @nogc when applied to @nogc types, 
and so on; for example, instead of taking a specific delegate 
type, we shall always accept a generic type, and use traits to 
guarantee it is some delegate; in this way, we can accept @safe 
delegate and propagate @safety to our algorithm, or accept 
@system and have our algorithm usable in @system code; same with 
@nogc et al.


- when we use virtual methods, we are giving up all 
compiler-checked attributes; in this situation we have two 
options:
- we trust what we are doing: e.g. we cannot mark a thing 
@nogc, but we know it is and the profiler confirms that no 
allocation happens, so we are happy; our aim is having code that 
doesn't freeze because of collections, and not marking code @nogc.
- we must have @nogc (or @whatever): then we know we cannot 
use certain classes, because they are definitely @nogc; so we 
cast the objects we get to the classes/interfaces that we know 
are @nogc (and are marked as such), and then our code is @nogc; 
as you see, you don't need Object to have @nogc methods; you only 
need the specific classes you use have it; if you want to work on 
generic objects, and as such cannot do specific casts, then you 
should definitely be using templates.


The only real problems I found till now are:
- some things in Phobos that shall be @nogc are not; they shall 
be refactored to have that attribute (but this is not always easy 
and requires time)
- the interface IAllocator is mostly used with @nogc allocators, 
but cannot have the said attribute (as I explained above, it must 
not restrict the possibility of allocators); it shall have a 
sub-interface NoGCAllocator, so that code can accept a @nogc 
allocator parameter without using templates (of course templates 
are fine, and are what we use now, but if everyone uses 
templates, why have IAllocator in the first place? IMHO we must 
have or both or none).


Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 23 July 2016 at 14:53:49 UTC, Rufus Smith wrote:

Um, this isn't right. GC code can always call non-gc code.

If you mark opEquals nogc, it breaks nothing except 
implementations of opEquals that use the GC. GC code can still 
call it nogc opequals, it only enforces opEquals code to avoid 
the GC itself, which isn't a terrible thing.


That's what I meant. Sorry for being not clear. IMHO, it is very 
limiting to forbid the use of the GC in opEquals. And it would 
definitely break a lot of code.


What is terrible is that nogc code can never have any equality 
comparisons! It is impossible unless one manually tests them, 
but how? Every method would be brittle. Do a memory test? 
compare element by element? One can't predict what to do.


@nogc code can have @nogc comparisons, as long as it does not use 
other objects whose comparison requires the GC. See more below.


So, you are trying off laziness to break nogc. As it stands, if 
nogc code can't compare equality, it is broken and useless. Why 
put it in the language then?


struct S(T)
{
   @nogc void test(T t1, T t2)
   {
  if (t1 == t2) return true;
  return false;
   }
}

Broke! Even if opEquals of T does not use any GC we can't write 
test to be nogc, which means we can't have S be nogc or 
anything that depends on S that is nogc. This must be a dirty 
trick played by the implementors of nogc to keep everyone on 
the gc nipple?


If opEquals of T does not use the GC, then the compiler will 
infer the attribute @nogc for your test function. Remember: 
templated functions will be inferred @nogc whenever possible. 
Just, don't put @nogc explicitly, so the code will be @nogc if 
T.opEquals is @nogc and otherwise it will be not-@nogc.


Equality comparison is more fundamental than the GC in 
programming. There is no fundamental reason why equality 
comparison depends on the GC.


All I can hope for now is that there is a robust way to compare 
that I can use that is marked nogc. Else all my nogc code is 
broke. I guess one has this problem with all opOp's!


With templates (as you show in your code) you have no problem, 
just let the compiler infer the attributes, as I said.
With runtime OOP it is more of a trouble, but in D runtime OOP is 
not used that much, and it is rarely used in critical @nogc code.


Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Lodovico Giaretta via Digitalmars-d-learn

On Saturday, 23 July 2016 at 13:18:03 UTC, Rufus Smith wrote:
Trying to compare a *ptr value with a value in nogc code 
results in the error:


Error: @nogc function '...' cannot call non-@nogc function 
'object.opEquals'		


Shouldn't object opEquals be marked?


If object.opEquals is marked @nogc, than all D classes must 
implement it as @nogc, because (of course) you cannot override a 
@nogc method with a not-@nogc one (while the opposite is 
possible, of course).
So marking it @nogc is not only a big breaking change, but also 
very limiting.


Re: Building phobos GDC

2016-07-22 Thread Lodovico Giaretta via Digitalmars-d-learn

On Friday, 22 July 2016 at 20:26:50 UTC, Rufus Smith wrote:
On Friday, 22 July 2016 at 19:52:59 UTC, Lodovico Giaretta 
wrote:

On Friday, 22 July 2016 at 18:30:13 UTC, Rufus Smith wrote:
Trying to compile code that uses GDC, had to import phobos 
files from dmd in to project since they are not in the GDC's 
phobo lib(the core.sys.windows stuff).


Almost all the errors are related to stuff like

PALETTEENTRY* peNew() return { return _peNew.ptr; }


Does that even make sense?


I'll add that, in general, it's a bad idea to mix the 
libraries of the various compilers. In fact, the library has 
the same release cycle as the frontend, and is specific to the 
frontend version it comes with. GDC is several frontend 
versions behind DMD, so GDC cannot support the new features / 
characteristics of the recent DMD libraries.
You should always use a Phobos version as old as the frontend 
of the compiler you're using.


I don't agree with this. The versions are too far out of sync. 
It is better to test the different versions together because 
they are not consistent. As I yet I can neither use GDC or LDC 
because they don't compile the code that works with DMD. This 
is a problem with those compilers. If one could guarantee that 
the oldest compiler was always compatible, 
eventually(reasonably), with the newest one, it would be a 
different story. But bugs creep in. I'd rather work with the 
reference compiler, the actual one the language is based off 
of, rather than work with one that is not even guaranteed to be 
maintained properly.


With dmd, I know exactly what I'm getting and I only bother 
with the other compilers due to performance, which is not 
priority when developing. Hence, I hope that the other 
compilers are up to speed once I am finished with developing. 
This is a risk, but no more than expecting those compilers to 
eventually be updated. Given that the maintenance of LDC and 
GDC are rather low compared to DMD, I'd rather stick with DMD.


LDC is fairly up to date. In fact, it recently shipped an alpha 
version with support for the 2.071 frontend, while DMD 2.072 is 
still in beta. So, not that bad, just one version behind. I 
started a project a couple months ago with DMD 2.071. I'm still 
working on it, and now I can also use LDC.

The real problem is GDC, which apparently is currently at 2.066.


Re: Building phobos GDC

2016-07-22 Thread Lodovico Giaretta via Digitalmars-d-learn

On Friday, 22 July 2016 at 18:30:13 UTC, Rufus Smith wrote:
Trying to compile code that uses GDC, had to import phobos 
files from dmd in to project since they are not in the GDC's 
phobo lib(the core.sys.windows stuff).


Almost all the errors are related to stuff like

PALETTEENTRY* peNew() return { return _peNew.ptr; }


Does that even make sense?


I'll add that, in general, it's a bad idea to mix the libraries 
of the various compilers. In fact, the library has the same 
release cycle as the frontend, and is specific to the frontend 
version it comes with. GDC is several frontend versions behind 
DMD, so GDC cannot support the new features / characteristics of 
the recent DMD libraries.
You should always use a Phobos version as old as the frontend of 
the compiler you're using.


Re: Building phobos GDC

2016-07-22 Thread Lodovico Giaretta via Digitalmars-d-learn

On Friday, 22 July 2016 at 18:30:13 UTC, Rufus Smith wrote:
Trying to compile code that uses GDC, had to import phobos 
files from dmd in to project since they are not in the GDC's 
phobo lib(the core.sys.windows stuff).


Almost all the errors are related to stuff like

PALETTEENTRY* peNew() return { return _peNew.ptr; }


Does that even make sense?


The peculiarity of this code is that it uses DIP 25.
I don't know if GDC supports it, nor if you need some compiler 
switch.

In DMD you need the -dip25 switch.

For more infos on DIP 25: https://wiki.dlang.org/DIP25


Re: Default implementations in inherited interfaces

2016-07-21 Thread Lodovico Giaretta via Digitalmars-d-learn
On Thursday, 21 July 2016 at 09:46:10 UTC, Lodovico Giaretta 
wrote:

Interesting.
This is worth a bugzilla issue, IMHO. In fact, if you try the 
other way (i.e.: you provide an implementation of func in class 
C), you get the opposite error, that you are overriding a final 
function (B.func).


Submitted as issue 16306
https://issues.dlang.org/show_bug.cgi?id=16306


Re: Default implementations in inherited interfaces

2016-07-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 21 July 2016 at 09:41:27 UTC, Saurabh Das wrote:
I have an interface A which declares a certain function. A 
second interface B inherits from A and wishes to provide a 
default implementation for that function. How can I achieve 
this? I'm facing an error when I try this:


interface A
{
int func(int);
}

interface B : A
{
final int func(int)
{
return 0;
}
}

class C : B
{
}

rdmd it.d:
it.d(14): Error: class it.C interface function 'int func(int)' 
is not implemented


Thanks,
Saurabh


Interesting.
This is worth a bugzilla issue, IMHO. In fact, if you try the 
other way (i.e.: you provide an implementation of func in class 
C), you get the opposite error, that you are overriding a final 
function (B.func).


Re: How to search for an enum by values and why enum items aren't unique

2016-07-20 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 20 July 2016 at 18:08:14 UTC, stunaep wrote:
On Wednesday, 20 July 2016 at 05:45:21 UTC, Jonathan M Davis 
wrote:
On Wednesday, July 20, 2016 04:03:23 stunaep via 
Digitalmars-d-learn wrote:

[...]


If you want the list of members in an enum, then use 
std.traits.EnumMembers and you'll get a compile-time list of 
them. It can be made into a runtime list by being put into an 
array literal.


[...]


Coming from Java I've learned to love enums that are separate 
objects, that can store multiple values, and that can have 
methods that can be in their scope. Seems to me like there's no 
reason to even use enums in D. What's the point when just 
making a constant would do the same exact thing?


You can easily emulate Java enums in D.

class MyEnumClass
{
// fields and methods, as a class
private int val;
public int foo()
{
 return val * 2;
}

// private ctor: user cannot instantiate the class
private this(int i)
{
val = i;
}

// your enumerated instances
static immutable ONE;
static immutable TWO;
static immutable THREE;

// initialize the enumerate values on program startup
shared static this()
{
ONE = new MyEnumClass(1);
TWO = new MyEnumClass(2);
THREE = new MyEnumClass(3);
}
}

It's not much longer than the equivalent Java code and is way 
clearer (you know exactly what's going on under the hood).


In java an enum is just an extension of the singleton pattern, 
where there's a finite set of instantiation instead of exactly 
one.


A D enum (or a C one, or a C++ one) is a totally different thing.


Re: Why typeof(template) is void?

2016-07-20 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 20 July 2016 at 05:54:41 UTC, mogu wrote:

On Wednesday, 20 July 2016 at 01:50:37 UTC, Adam D. Ruppe wrote:

On Wednesday, 20 July 2016 at 01:14:05 UTC, mogu wrote:

Why S's type isn't something like `S: (T) -> S`?


Because S isn't a type... think of a template as being like a 
function that returns a type.


int foo(int) { return 0; }

There, you wouldn't expect typeof(foo) to be int, no, 
typeof(foo) is a function that returns an int.


The template is the same thing - it isn't a type, it is a 
template that returns a type.


So it's a higher kinded type aka type class in Haskell. But D's 
reflection cannot get enough information about template's kind. 
Only a `void` given. It may be inconvenient in distinction 
between an alias of template and void. The only solution AFAIK 
is by string of the type property .stringof.


Note that void is a type, while S is not. So you can do:

assert(is(void)) // is(type) returns true
assert(!is(S))   // is(template) returns false;


Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

[...]


But this doesn't create a function with all the attributes of 
the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly the 
same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only if 
the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a 
simple solution; but I'm not an expert, so I hope someone else 
will give you a better answer.


What is strange is I cannot even pass an extern(C) function to 
foo.


void foo(R, A...)(R function(A) bar);

extern(C) void bar();

foo()

fails. Remove extern and it passes. I have not figured out how 
to allow for extern(C) functions to be passed.


That's because an extern function must be called with a different 
code. So it cannot be cast to a non-extern(C) function pointer, 
which is what your foo accepts. If you follow my advice, and make 
the entire function type a parameter of foo, then foo will at 
least accept your extern(C) function, but it will not be 
extern(C) itself.


Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like 
the attributes to be able to "fall" through so I get overload 
like behavior. I only care that I am passing a function, not 
if it is shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type 
to instantiate other functions like bar. I have to create a 
foo for each attribute combination, which is not worth while. 
The code seems to break only for extern, the best I can tell, 
most attributes do pass through. But type does not contain 
these attributes.


You shall do something like this (please note that I didn't 
check the docs while writing this; you shall definitely have a 
look at std.traits and consider the following as pseudo-code 
and not actual D):


void foo(Fun)(Fun bar)
if (isSomeFunction!Fun)   // your constraint that bar is a 
function

{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;

alias type = Fun;
pragma(msg, type);

// do some magic
}


But this doesn't create a function with all the attributes of 
the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly the 
same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only if 
the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a simple 
solution; but I'm not an expert, so I hope someone else will give 
you a better answer.


Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like 
the attributes to be able to "fall" through so I get overload 
like behavior. I only care that I am passing a function, not if 
it is shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type 
to instantiate other functions like bar. I have to create a foo 
for each attribute combination, which is not worth while. The 
code seems to break only for extern, the best I can tell, most 
attributes do pass through. But type does not contain these 
attributes.


You shall do something like this (please note that I didn't check 
the docs while writing this; you shall definitely have a look at 
std.traits and consider the following as pseudo-code and not 
actual D):


void foo(Fun)(Fun bar)
if (isSomeFunction!Fun)   // your constraint that bar is a 
function

{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;

alias type = Fun;
pragma(msg, type);

// do some magic
}


Re: Passing a single tuple or multiple values

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 15:36:42 UTC, Lodovico Giaretta wrote:
As you have to do `isTuple!(T[0])`, you also have to do 
`x[0].expand`.
That's because T... works "as if" it was an array of types, and 
x, being of type T, it works "as if" it was an array of values. 
So you have to use an index in both cases.


You can find this out from the error, which says that you can't 
expand an object of type `(Tuple!(int, int))`. Note the 
surrounding parenthesis: they tell you that what you have is not 
a Tuple, but an AliasSeq whose only member is a Tuple. If you do 
`[0]` on it, you obtain the correct type, i.e. `Tuple!(int, 
int)`, without the parenthesis.


Re: Passing a single tuple or multiple values

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 13:33:41 UTC, jmh530 wrote:

On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote:


auto bar(T...)(T x)
{
  static if (T.length == 1 && isTuple!(T[0]))
return foo(x.expand);
  else
return foo(x);
}



Hmm, this actually doesn't seem to be resolving my issue. I'm 
still getting the error about not being able to expand x.


I tried it like below and got the same error.

auto bar(T...)(T x)
{
static if (T.length > 1)
{
return foo(x);
}
else static if (T.length == 1 && isTuple!(T))
{
return foo(x.expand);
}
}


As you have to do `isTuple!(T[0])`, you also have to do 
`x[0].expand`.
That's because T... works "as if" it was an array of types, and 
x, being of type T, it works "as if" it was an array of values. 
So you have to use an index in both cases.


Re: counting characters

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 12:23:11 UTC, celavek wrote:
On Tuesday, 19 July 2016 at 09:57:27 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

Works for me:

size_t[char] counts;
const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars(dna_chain, "A");


It was failing for me as I was using "countchars!". I thought 
that I should use the "!" in order to instantiate a template in 
D. I'm still confused why it is working without the "!". Anyway 
the compiler message was not very helpful.


The declaration is:

countchars(S, S1)(S str, S1 pattern)

So the most verbose way to instantiate it is:

countchars!(string, string)(dna_chain, "A")

But as S and S1 are the types of the two arguments, the compiler 
can easily infer them, so you can write:


countchars(dna_chain, "A")

And have the compiler infer:

countchars!(typeof(dna_chain), typeof("A"))(dna_chain, "A")

The error message is technically correct: you cannot instantiate 
countchars with template parameters `dna_chain` and `"A"`, which 
is what you were actually doing.


Re: counting characters

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 09:42:40 UTC, celavek wrote:

On Tuesday, 19 July 2016 at 09:41:32 UTC, John wrote:

On Tuesday, 19 July 2016 at 09:34:11 UTC, celavek wrote:

Hi,

I am trying to count characters in a string like:

const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars!(dna_chain, 'A');


countchars(dna_chain, "A");


Not working. Same error.


Works for me:

size_t[char] counts;
const string dna_chain = 
"AGCCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAGAGTGTCTGATAGCAGC";

counts['A'] = countchars(dna_chain, "A");


Re: Iterate all visible symbols, even from imported modules

2016-07-18 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 18 July 2016 at 21:12:38 UTC, Meta wrote:
On Monday, 18 July 2016 at 13:00:16 UTC, Lodovico Giaretta 
wrote:
As per title, is it possible to iterate all visible symbols of 
the current module and of all imported modules and packages? 
My aim is to find everything in scope that has a specific UDA.


module foo;

import std.stdio, std.array, std.algorithm;

void bar(){}

struct S{}

void main()
{
// prints ["object", "std", "bar", "S", "main"]
// how do I discover that "std" is a package?
writeln([__traits(allMembers, foo)]);


// prints ["object", "core", "std", "KeepTerminator", 
"GCC_IO", ... ]
// strange thing: it looks the same even if I remove all 
imports other than std.stdio

writeln([__traits(allMembers, foo.std)]);
}

Thank you in advance.


This answer to a similar question on StackOverflow may be 
useful:


http://stackoverflow.com/questions/2329/d-finding-all-functions-with-certain-attribute/25560800#25560800


Wow!
Looks exactly what I was looking for. I'll give this a try as 
soon as possible.

Thank you.


Re: Iterate all visible symbols, even from imported modules

2016-07-18 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 18 July 2016 at 18:21:41 UTC, ketmar wrote:

short answer: no.

there is still no way to write a reliable enumerator like this: 
too much things to hack around.


as for module symbols, it is easy: they has no type. literally: 
`!is(typeof(...))`.


`is(typeof(...))` is a necessary safeguard anyway if you are 
enumerating symbols in module, as you can't do much with module 
names anyway, and you *have* to filter 'em out with top-level 
static if.


Thank you.
It looks like the check `is(typeof(T)) || is(T)` is passed by 
every symbol `T` that is not a module nor a package, so I think 
I'll use its complementary as a filter.


Iterate all visible symbols, even from imported modules

2016-07-18 Thread Lodovico Giaretta via Digitalmars-d-learn
As per title, is it possible to iterate all visible symbols of 
the current module and of all imported modules and packages? My 
aim is to find everything in scope that has a specific UDA.


module foo;

import std.stdio, std.array, std.algorithm;

void bar(){}

struct S{}

void main()
{
// prints ["object", "std", "bar", "S", "main"]
// how do I discover that "std" is a package?
writeln([__traits(allMembers, foo)]);


// prints ["object", "core", "std", "KeepTerminator", 
"GCC_IO", ... ]
// strange thing: it looks the same even if I remove all 
imports other than std.stdio

writeln([__traits(allMembers, foo.std)]);
}

Thank you in advance.


Re: Templates args

2016-07-14 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 14 July 2016 at 19:28:23 UTC, Andrey wrote:

On Thursday, 14 July 2016 at 19:27:14 UTC, Andrey wrote:

Hi guys!

Help a newbie please.

Playing with D and trying to understand some features.
Here is my try to carry out my code from C++ project to D

struct Sigmoid(T)
{
  const T Function(T value)
  {
   ...
  }
  const T DerivateFunction(const T value)
  {
   ...
  }
}

struct Neurons_layer(T = float, size_t neurons_num = 0, F = 
Sigmoid!T)

  if(isFloatingPoint!T && is(typeof(F.Function)))
{
private:
  static if(neurons_num > 0)
T[neurons_num] _neurons_arr;
  else
T[] _neurons_arr;

private:
  alias Function = F.Function;
}

unittest
{
  Neurons_layer!(float,5,Sigmoid!float) nf;
}


The question is - How to make in pretty way this line:
 Neurons_layer!(float,5,Sigmoid!float) nf;


to something like - Neurons_layer!(float,5,Sigmoid) nf;


You don't need Sigmoid!float at all. This will work:

Neurons_layer!(float, 5) nf;

as you provided a default value for the third argument.


Re: I can has @nogc and throw Exceptions?

2016-07-14 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 22:42:36 UTC, Adam Sansier wrote:
On Wednesday, 13 July 2016 at 21:27:16 UTC, Lodovico Giaretta 
wrote:
At the end, all memory comes from one of these: GC heap, 
malloc, mmap, sbrk. All other allocators build on top of these 
(or on top of user supplied buffers, which come from these as 
well). What those "wrapper" allocators do is managing the 
given memory, either using different allocations strategies 
for different allocation sizes, or keeping lists of free 
blocks instead of returning them using "free", or other things 
(have a look at the docs). So at the end they do what you 
would manually do in C/C++ to "personalize" the allocations, 
with the aim of reducing waste and/or being faster. They are 
also arbitrarily composable on top of each other.


I don't know how Phobos will handle exceptions. Maybe use 
reference counting (coming soon in D, maybe)? Maybe algorithms 
that already have to allocate will switch from using the GC to 
using a user-supplied custom allocator, and will use it for 
exceptions too.


Currently I'm working on a replacement for std.xml and I'm 
making every component take a template parameter to specify 
the allocator. Initially the allocators look like a real mess, 
but after a couple of days playing with them, you start 
understanding the mechanics and at the end you really enjoy 
them. Changing a single parameters allows to switch between 
@safe gc code and @nogc code in the unittests, without 
changing the implementation.


Ok. Is there a way to bundle allocations so that one free will 
work?


For example, your exception handling looks good but I need to 
supply custom messges. If I use sformat I have to create the 
array for the buffer to create the message in. This means I 
would have to free both the exception and the string. It would 
be nice to be able to do this in one go.


Sometimes it's nice to include runtime info in an error message 
such as an OS error code.


As you probably saw, sformat still has some problems with @nogc, 
because it internally uses std.uft.encode, which may throw a 
GC-allocated exception, but this can be solved.


Not all allocators keep track of the memory ranges they allocated 
(e.g.: Mallocator). The ones that do (like Region) usually 
provide a deallocateAll method. So the idea is that you allocate 
all data needed by your exception (string buffers or whatever) 
and the exception itself with one of these allocators, and at the 
end of a catch you deallocateAll.


Also, could one create a struct or class for the exception so 
that it is automatically free'ed at the end of a catch block, 
if caught? Probably not without language help?


I don't think it's feasible without language support for 
reference counted classes (which may be added sooner or later, as 
it has been asked and proposals have been made, and would be very 
useful). Also note that you don't want RAII or scope(exit) in 
this case but scope(success), as the exception shall not be 
deallocated if another one is raised in the catch block, because 
in D the second exception does not "overwrite" the first, but is 
chained to it, so that an outer catch can see both of them.


Re: I can has @nogc and throw Exceptions?

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 21:12:29 UTC, Adam Sansier wrote:

The advantages over a simple malloc are:
1) You can change between GC allocation, malloc, mmap and 
other allocators by changing a single line, instead of 
changing every throw;


Ok, I like!
2) you can use very fast allocators, based on your needs; this 
example uses the Region allocator, which is way faster than a 
call to malloc;


I like too! But I'll have to assume you are right since I have 
no proof.


3) the Region allocator has the added value of working even if 
there's no more memory available (because it preallocated it).


Well, one could do this with malloc because one can 
pre-allocate it too. I figure this is why you stated 2 though 
because it is pre-allocated? So, really only point 1 stands, 
but that is probably not even valid since one can wrap the 
allocator in a template. This is probably exactly what is being 
done..


So, ultimately no real benefit except the implementation 
details have been removed. That's not a bad thing as long as it 
works ;)


In general, the allocators library provides facilities that 
may seem overkill for simple tasks (and in fact they are), but 
prove very flexible and useful for advanced uses, or to write 
generic highly customizable code.
Of course, being experimental, this library has still some 
issues...


Well, I will try out the code and see. You've provided an 
example and if it works then it should be good enough in my 
case. If it doesn't limit what I need to do then I'm happy ;)


How is phobo's going to deal with such things when it is trying 
to get off the GC? It surely has to throw exceptions. Similar 
method or something entirely different?


Thanks.


At the end, all memory comes from one of these: GC heap, malloc, 
mmap, sbrk. All other allocators build on top of these (or on top 
of user supplied buffers, which come from these as well). What 
those "wrapper" allocators do is managing the given memory, 
either using different allocations strategies for different 
allocation sizes, or keeping lists of free blocks instead of 
returning them using "free", or other things (have a look at the 
docs). So at the end they do what you would manually do in C/C++ 
to "personalize" the allocations, with the aim of reducing waste 
and/or being faster. They are also arbitrarily composable on top 
of each other.


I don't know how Phobos will handle exceptions. Maybe use 
reference counting (coming soon in D, maybe)? Maybe algorithms 
that already have to allocate will switch from using the GC to 
using a user-supplied custom allocator, and will use it for 
exceptions too.


Currently I'm working on a replacement for std.xml and I'm making 
every component take a template parameter to specify the 
allocator. Initially the allocators look like a real mess, but 
after a couple of days playing with them, you start understanding 
the mechanics and at the end you really enjoy them. Changing a 
single parameters allows to switch between @safe gc code and 
@nogc code in the unittests, without changing the implementation.


Re: I can has @nogc and throw Exceptions?

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 20:44:52 UTC, Adam Sansier wrote:
On Wednesday, 13 July 2016 at 16:28:23 UTC, Lodovico Giaretta 
wrote:


It's actually quite easy. Here's the code (untested):



import std.experimental.allocator.building_blocks.region;
import std.experimental.allocator.mallocator;
import std.experimental.allocator;


Region(shared(Mallocator)) exception_allocator;
enum EXCEPTION_MEM_SIZE = 256*1024;
static this()
{
exception_allocator = 
typeof(exception_allocator)(EXCEPTION_MEM_SIZE);

}



And here is an usage example (untested, too):



void throwingFunction()
{
// try to do something, but fail
throw exception_allocator.make!Exception("my wonderful 
error message");

}

void throwingThrowingFunction()
{
try
{
// try to call function, which fails
throwingFunction;
}
catch (Exception exc)
{
// try to recover from failure, but generate other 
exception (just to show chaining)
throw exception_allocator.make!Exception("I love 
exception chaining");

}
}

void main()
{
try
{
// try to call function, which fails
throwingThrowingFunction;
}
catch (Exception exc)
{
// recover from failure, then deallocate the 
exceptions no longer needed

exception_allocator.deallocateAll;
}
}



Doesn't work. identifier expected on shared.

What's the difference of simply using malloc to allocate the 
memory and creating the exceptions their? Seems like a long and 
winded way go about it or is there some benefit to using the 
experimental allocators?


`Region(shared(Mallocator))` shall be `Region!(shared 
Mallocator)` (again, I'm just looking at the code, didn't test 
it).


The advantages over a simple malloc are:
1) You can change between GC allocation, malloc, mmap and other 
allocators by changing a single line, instead of changing every 
throw;
2) you can use very fast allocators, based on your needs; this 
example uses the Region allocator, which is way faster than a 
call to malloc;
3) the Region allocator has the added value of working even if 
there's no more memory available (because it preallocated it).


In general, the allocators library provides facilities that may 
seem overkill for simple tasks (and in fact they are), but prove 
very flexible and useful for advanced uses, or to write generic 
highly customizable code.
Of course, being experimental, this library has still some 
issues...


Re: I can has @nogc and throw Exceptions?

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 16:13:21 UTC, Adam Sansier wrote:
On Wednesday, 13 July 2016 at 11:39:11 UTC, Lodovico Giaretta 
wrote:

On Wednesday, 13 July 2016 at 00:57:38 UTC, Adam Sansier wrote:

[...]


You shall use a static per-thread Region allocator[1] backed 
by Mallocator[2].

Then you just make[3] exceptions inside it and throw them.
So you can allocate and chain exceptions until you end the 
memory established on creation.
Whenever you don't need the exception chain anymore (i.e.: you 
catched them and program is back in "normal" mode, you just 
reset the region allocator, so you have all of your memory 
again, for the next exception chain).


[1] 
https://dlang.org/phobos/std_experimental_allocator_building_blocks_region.html
[2] 
https://dlang.org/phobos/std_experimental_allocator_mallocator.html

[3] https://dlang.org/phobos/std_experimental_allocator.html


Am I going to have to do all this myself or is it already done 
for me somewhere?


It's actually quite easy. Here's the code (untested):



import std.experimental.allocator.building_blocks.region;
import std.experimental.allocator.mallocator;
import std.experimental.allocator;


Region(shared(Mallocator)) exception_allocator;
enum EXCEPTION_MEM_SIZE = 256*1024;
static this()
{
exception_allocator = 
typeof(exception_allocator)(EXCEPTION_MEM_SIZE);

}



And here is an usage example (untested, too):



void throwingFunction()
{
// try to do something, but fail
throw exception_allocator.make!Exception("my wonderful error 
message");

}

void throwingThrowingFunction()
{
try
{
// try to call function, which fails
throwingFunction;
}
catch (Exception exc)
{
// try to recover from failure, but generate other 
exception (just to show chaining)
throw exception_allocator.make!Exception("I love 
exception chaining");

}
}

void main()
{
try
{
// try to call function, which fails
throwingThrowingFunction;
}
catch (Exception exc)
{
// recover from failure, then deallocate the exceptions 
no longer needed

exception_allocator.deallocateAll;
}
}



Re: Best way to clear dynamic array for reuse

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 12:37:26 UTC, Miguel L wrote:
I tried Appender, but for some reason garbage collector still 
seems to be running every few iterations.
I will try to expand a little on my code because maybe there is 
something i am missing:


 Appender!(A[]) a;

 void foo( out Appender!(A[]) bar)
{
...
bar~= lot of elements
}

 for()
 {
 //a=[]; //discard array contents
 a.clear();
 foo(a) appends thousand of elements to a
 ... use a for some calculations
 }


Well, I think foo's parameter should be `ref Appender!(A[]) bar` 
instead of `out Appender!(A[]) bar`. Also, if you know you will 
append lots of elements, doing a.reserve(s), with s being an 
estimate of the number of appends you expect, might be a good 
idea.


Re: Best way to clear dynamic array for reuse

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 12:20:07 UTC, cym13 wrote:

The best option would be a.clear(). From the language specs:

“Removes all remaining keys and values from an associative 
array. The array is not rehashed after removal, to allow for 
the existing storage to be reused. This will affect all 
references to the same instance and is not equivalent to 
destroy(aa) which only sets the current reference to null.”


I don't think OP is using associative arrays, but dynamic arrays 
(if I understood correctly).


Re: Best way to clear dynamic array for reuse

2016-07-13 Thread Lodovico Giaretta via Digitalmars-d-learn

On Wednesday, 13 July 2016 at 11:59:18 UTC, Miguel L wrote:

I am using a temporary dynamic array inside a loop this way:
A[] a;
for()
{
a=[]; //discard array contents
... appends thousand of elements to a
... use a for some calculations
}

I would like to know which would be the best way to clear a 
contents avoiding reallocations, as there seems to be lots of 
garbage collection cycles taking place.


The options would be:

a=[];
a.length=0;
a=null;
...
any other?

Can you help me please?


Use std.array.Appender. It allows faster appends, and has a handy 
.clear method that zeroes the length of the managed array, 
without de-allocating it, so the same buffer is reused.


  1   2   >