Re: What is the current progress on "Safety and Memory Management"?

2016-07-19 Thread maik klein via Digitalmars-d

On Sunday, 17 July 2016 at 06:05:27 UTC, qznc wrote:
If I were your advisor, I would suggest not to think about 
Phobos. Just build your own library and publish via dub. 
Getting a contribution into Phobos is not a good use of time 
for a bachelor thesis.


Apart from that: Ownership semantics as a library is a great 
topic! Go for it.


That was the initial idea, but its not completely feasible to 
have it as a standalone library because a few things in phobos 
just need to be fixed for it to be practical. For example 
"Tuple", I could and will have a separate Tuple implementation 
but it would be very nice if I could at one point forward some 
changes to phobos. Probably in combination with a DIP and why 
those changes are needed.


Also some safety features of Rust could also be implemented as a 
library for example Sync and Send. See 
https://doc.rust-lang.org/nomicon/send-and-sync.html


My major concern is that I am not sure if the D community wants 
to have similar ownership semantics of C++ / Rust.


Walter and Andrei have, in the past, stated many times that 
they believe Rust's approach to the memory safety problem is 
too complex and not a good fit for D. They have been exploring 
alternative solutions for a while now, and will probably 
announce something eventually.


Nothing significant gets added to the language, runtime, or 
standard library without their approval - no matter how popular 
it is with the community.


So, make sure that you get explicit pre-approval from them 
before you waste your time, unless everything you want to do 
can be implemented as a normal stand-alone DUB package.


I don't want to implement any memory safety at all, I just want 
to implement a proper library to avoid the GC. I just listed Rust 
because Rusts's std lib is open source, readable and feature 
rich. (+ I am already familiar with it)


Re: What is the current progress on "Safety and Memory Management"?

2016-07-16 Thread maik klein via Digitalmars-d

On Saturday, 16 July 2016 at 20:38:05 UTC, The D dude wrote:

On Friday, 15 July 2016 at 12:59:39 UTC, maik klein wrote:

https://wiki.dlang.org/Vision/2016H2

Safety and Memory Management

Safety and making the GC optional remain important concerns 
through the end of this year. We are putting them together 
because the GC alternatives we endorse must address safety.



Has there been any progress so far? Are there any DIPs to 
improve no gc code?


I can see these two:

http://wiki.dlang.org/DIP18 (a bit outdated)
http://wiki.dlang.org/DIP68

I can remember that there was talk about making allow to use a 
custom allocator with `new`, but I haven't seen a proposal yet.


I do encourage you to volunteer, doing the research & 
submitting your idea(s) for a change ;-)


I was actually thinking of contributing something bigger as part 
of my bachelor thesis. (Not sure if I am allowed to do that)


What I wanted to do is to translate a big part of Rust's std to 
D. Stuff like Rc, Arc, Box, Optional + all the necessary tools 
for ownership semantics.


Also implement data structures that work with ownership semantics 
(Rc, Box, Arc etc)  like Vec, HashMap.


Add ownership semantics to phobos, for example a lot of stuff in 
phobos can't be used with non copyable types. (A lot of things 
rely on copying)


I have already implemented a small part of Rusts std but it felt 
like that I was the only one interested in this. (I am aware of 
RefCounted, Unique, Nullable etc)


I would definitely put some spare time into researching this a 
bit more if there is some interest.





What is the current progress on "Safety and Memory Management"?

2016-07-15 Thread maik klein via Digitalmars-d

https://wiki.dlang.org/Vision/2016H2

Safety and Memory Management

Safety and making the GC optional remain important concerns 
through the end of this year. We are putting them together 
because the GC alternatives we endorse must address safety.



Has there been any progress so far? Are there any DIPs to improve 
no gc code?


Re: Interior immutability and rvalues

2016-07-15 Thread maik klein via Digitalmars-d-learn

On Friday, 15 July 2016 at 12:05:47 UTC, ag0aep6g wrote:

On 07/15/2016 10:29 AM, maik klein wrote:

[...]


Sure. Just instantiate Rc with a const/immutable T. I.e., write 
`Rc!(const int)` instead of `const Rc!int`. Or with auto and 
makeRc: `auto rc = makeRc(immutable int(5));`.



[...]


When you pass an rvalue to a function, the parameter inside the 
function is still an lvalue. The argument being an rvalue just 
means that you can't pass it in a ref parameter.



[...]


Ok, not being copyable is the problem.


[...]


If args[0] can be moved, can args[1] and args[2] be moved, too? 
I mean, can you just move everything without testing for 
hasElaborateCopyConstructor? Just a thought.


Thanks I didn't know that you could have type qualifiers inside 
templates, D still surprises me sometimes.


I don't think it is practical to call move on "everything", for 
example maybe you just want to pass a `ref` or a `class`.


Interior immutability and rvalues

2016-07-15 Thread maik klein via Digitalmars-d-learn

There are two things that bothered me for quite some time

Interior immutability:

Consider a something like this

https://dpaste.dzfl.pl/fa5be84d26bc

The implementation is totally wrong and it doesn't make sense, 
but it shows that Rc can not be const/immutable because at least 
"dup" needs to increment the counter.


Is it possible to express that Rc should be mutable but the value 
that it wraps should be either mutable or const/immutable?


Rvalues and forwarding:

The problem is that when you pass an rvalue to a function you 
lose the information that is an rvalue. There is nothing like 
std::forward from c++ that I am aware of.


That becomes a problem when I use variadics with non copyable 
types. I need to call move on types that can not be copied.


I guess what I could do is to use 
https://dlang.org/phobos/std_traits.html#hasElaborateCopyConstructor to detect which types in the variadic args are actually non copyable and then call .move on them.


Is this how you would do it? The use case would be something like 
this


void test(Args...)(Args args){
someOtherTest(args); // doesn't work because args contains 
some non copyable types

}

void test(Args...)(Args args){
someOtherTest(mixin forward!(args));
}

//expands to

void test(Args...)(Args args){
someOtherTest(args[0].move, args[1], args[2]);
}


Re: A comparison between Rust and D

2016-06-24 Thread maik klein via Digitalmars-d

On Friday, 24 June 2016 at 17:37:20 UTC, jmh530 wrote:

On Friday, 24 June 2016 at 17:26:58 UTC, maik klein wrote:

https://maikklein.github.io/post/cmp-rust-d/

https://www.reddit.com/r/programming/comments/4po2j5/a_comparison_between_rust_and_d/


On interior mutability in arrays, does this help:
void main()
{
immutable(int)[] x = [1, 2, 3];
x = [2, 3, 4]; //this works
x[0] = 1; //this doesn't

immutable(int[]) y = [1, 2, 3];
y = [2, 3, 4]; //this doesn't
y[0] = 1; //this doesn't
}


I should probably be more clearer, I this context I just meant 
std.container.Array.


And in general stuff like refcounted. I wonder how Andrej handles 
immutability for the refcounted string.


A comparison between Rust and D

2016-06-24 Thread maik klein via Digitalmars-d

https://maikklein.github.io/post/cmp-rust-d/

https://www.reddit.com/r/programming/comments/4po2j5/a_comparison_between_rust_and_d/




Re: I implemented delegates in D

2016-06-11 Thread maik klein via Digitalmars-d

On Thursday, 9 June 2016 at 23:53:33 UTC, BBasile wrote:

On Thursday, 9 June 2016 at 21:02:26 UTC, maik klein wrote:
I am currently writing a task system and I have this case 
where I want to send a delegate to a different thread but this 
delegate also captures a variable. I use this to implement a 
"future".


Now as far as I know this delegate will allocate GC memory and 
I just wanted to avoid that, just for fun.


Here is the code https://dpaste.dzfl.pl/cd77fce99a5b

I have only worked on it a couple of hours and I am sure there 
are many problems with it.


Basically the idea is that you can use normal lambda syntax. 
If you want a function that returns and int and takes an int, 
you can write it like this:


(int i) => i

If you want a function that returns an int, takes an int, but 
also captures and int you would write it like this


(int i, int captured) => i + captured

But you also have to declare the base function type without 
the captured variables beforehand.


Fn!(FnType!(int, int), (int i, int captured) => i + 
captured)(42);


That is how I know what the captured variables are.

The only part that is currently missing are polymorphic 
delegates. They are not too useful if I can't pack them into 
the same array.


I guess I have to do this with classes/interfaces.

Thoughts?

Has this been done before?


What you have here is more functor, to the extent that you can 
memorize the parameters. The problem is that it's not 
compatible with the delegates as defined in the language.


Actual D delegates get collected when we take the address and 
the context of a member function with "&". To allocate the 
delegate itself in the non GC heap is easy (with a struct that 
contains two pointers).


Your message has motivated me to make this, thanks to a union 
true nogc delegates are possible:


=
module runnable;

union Delegate(FT)
{
// delegate layout as defined in the D ABI
struct DgMembers
{
void* ptr;
FT funcptr;
}
DgMembers members;

// the 2nd member is "true" D delegate type
import std.array: replace;
mixin("alias DT = " ~ FT.stringof.replace("function", 
"delegate") ~ ";");

DT dg;
}

void main() @nogc
{
static struct Foo
{
@nogc string delegate() test;
@nogc string source() {return "test";}
}

import std.experimental.allocator.mallocator;
import std.experimental.allocator;

Foo foo;
alias DelegateT = Delegate!(typeof());

//  takes the static address, i.e in the data 
segment

DelegateT* dg = make!DelegateT(Mallocator.instance);
dg.members.ptr = 
dg.members.funcptr = 

foo.test = dg.dg;
assert(foo.test() == "test");
}
=

Here you have a true D delegate that's conform with the 
language.


The problem is I currently do this

struct LocalTaskQueue{
...
Array!(Box!Fiber) work;
Array!(Box!Fiber) queuedWork;
...
}

This is where I submit my delegates to, but before that I also 
wrap them inside a fiber. Btw "Box" is my version of Unique.


I execute a fiber inside work and if it is done I want to delete 
it, because it is not needed anymore. If it is on hold it 
transfer it from "work" to queuedWork.


That means I need be able to put my delegates inside a fiber, 
this is the constructor for a Fiber currently.



this( void delegate() dg, size_t sz = PAGESIZE*4 ) nothrow
in
{
assert( dg );
}
body
{
allocStack( sz );
reset( dg );
}

I mean I can easily convert my "Fn" version to delegate with 
, but then I would not know how long my "Fn" should 
stay alive.


I think what I can do is switch my struct Fn to a class and 
implement my own function polymorphism.


I would then do

Array!(Box!Fiber) work;
Array!(Box!PolymorphicFn!(void, void)) rawFunction;

and when I delete a fiber from work I can delete it from 
rawFunction.


But that seems to be so much trouble just to avoid a bit of GC.







Re: I implemented delegates in D

2016-06-11 Thread maik klein via Digitalmars-d

On Friday, 10 June 2016 at 00:23:13 UTC, Mathias Lang wrote:
2016-06-10 1:20 GMT+02:00 maik klein via Digitalmars-d < 
digitalmars-d@puremagic.com>:



Did you try to send a native delegate ? I would be very 
surprised if you were allowed to do so.


That is what I am currently doing and it at least appears to be 
working as intended.


Note that not all delegates allocate. Function local delegate 
refering to variable do, but the one refering to aggregate 
never do.


All my closures/delegated need to capture a local variable. They 
capture a pointer to a heap allocated "Cell". I use the cell as a 
primitive to write my result into. It has an internal atomic 
counter, if the counter as decremented to 0, I know that I can 
safely read from it.


I am not sure how I would implement it differently.

So that means that all my delegates allocate, and they allocate 
with the GC.




Re: D's memory-hungry templates

2016-06-10 Thread maik klein via Digitalmars-d
On Friday, 10 June 2016 at 10:27:09 UTC, Andrei Alexandrescu 
wrote:

On 6/9/16 7:56 PM, maik klein wrote:
Also C++ beat D in every compile time meta programming 
benchmark that I

have tested.


Intriguing. Do you have a couple of representative benchmarks 
along with their C++ counterparts to post to bugzilla? Thanks! 
-- Andrei


Not in a presentable form, I still have a framework on my other 
machine. I basically generated new D files from within D and then 
compiled them using ldc/dmd.


I could clean it up and upload it when I have some time.



Re: I implemented delegates in D

2016-06-09 Thread maik klein via Digitalmars-d

On Thursday, 9 June 2016 at 22:06:24 UTC, Mathias Lang wrote:
To avoid the delegate being GC allocated, use `scope foo = (int 
i) { ... }`

at call site.
You can also make your function signature as `void func(scope 
void
delegate() dg)` in which case it won't allocate if you pass a 
literal

directly.

2016-06-09 23:57 GMT+02:00 maik klein via Digitalmars-d < 
digitalmars-d@puremagic.com>:



On Thursday, 9 June 2016 at 21:32:33 UTC, Alex Parrill wrote:


On Thursday, 9 June 2016 at 21:02:26 UTC, maik klein wrote:


Has this been done before?



Well, yes, the entire point of delegates is to be able to 
capture variables (as opposed to function pointers, which 
cannot).



auto createADelegate(int captured) {
return (int a) => captured + a;
}

void main() {
auto dg1 = createADelegate(5);
auto dg2 = createADelegate(32);
assert(dg1(5) == 10);
assert(dg1(10) == 15);
assert(dg2(8) == 40);
assert(dg2(32) == 64);
}

https://dpaste.dzfl.pl/90ebc29651f6

(Unfortunately template delegates, like the ones used with 
map, don't keep their captured variables alive after the 
captured variables go out of scope, but it doesn't sound like 
you need those)




I meant, "has this been implement as a library before". I am 
well aware that delegates exist in the language but as far as 
I know you can not do manual allocation with delegates (to 
avoid the GC).


But that means that the closure will be allocated on the stack 
right? What happens when I send it with 
http://dpldocs.info/experimental-docs/std.concurrency.send.html


Will it copy the function or will it only send the pointer?

Also scope on local vars is marked to be deprecated, see 
http://stackoverflow.com/a/4713064/944430


I don't think that I can use delegates (without the gc), what I 
basically do is send a delegate to a thread, create a fiber on 
that thread and put it in a thread local array.


The delegate contains a "future" that I can access on a different 
thread. I use it as mechanism to share results. (Its synchronized 
with atomics)


I mean currently I just use gc delegates, but I am exploring some 
alternatives.







Re: I implemented delegates in D

2016-06-09 Thread maik klein via Digitalmars-d

On Thursday, 9 June 2016 at 21:32:33 UTC, Alex Parrill wrote:

On Thursday, 9 June 2016 at 21:02:26 UTC, maik klein wrote:

Has this been done before?


Well, yes, the entire point of delegates is to be able to 
capture variables (as opposed to function pointers, which 
cannot).



auto createADelegate(int captured) {
return (int a) => captured + a;
}

void main() {
auto dg1 = createADelegate(5);
auto dg2 = createADelegate(32);
assert(dg1(5) == 10);
assert(dg1(10) == 15);
assert(dg2(8) == 40);
assert(dg2(32) == 64);
}

https://dpaste.dzfl.pl/90ebc29651f6

(Unfortunately template delegates, like the ones used with map, 
don't keep their captured variables alive after the captured 
variables go out of scope, but it doesn't sound like you need 
those)


I meant, "has this been implement as a library before". I am well 
aware that delegates exist in the language but as far as I know 
you can not do manual allocation with delegates (to avoid the GC).


I implemented delegates in D

2016-06-09 Thread maik klein via Digitalmars-d
I am currently writing a task system and I have this case where I 
want to send a delegate to a different thread but this delegate 
also captures a variable. I use this to implement a "future".


Now as far as I know this delegate will allocate GC memory and I 
just wanted to avoid that, just for fun.


Here is the code https://dpaste.dzfl.pl/cd77fce99a5b

I have only worked on it a couple of hours and I am sure there 
are many problems with it.


Basically the idea is that you can use normal lambda syntax. If 
you want a function that returns and int and takes an int, you 
can write it like this:


(int i) => i

If you want a function that returns an int, takes an int, but 
also captures and int you would write it like this


(int i, int captured) => i + captured

But you also have to declare the base function type without the 
captured variables beforehand.


Fn!(FnType!(int, int), (int i, int captured) => i + captured)(42);

That is how I know what the captured variables are.

The only part that is currently missing are polymorphic 
delegates. They are not too useful if I can't pack them into the 
same array.


I guess I have to do this with classes/interfaces.

Thoughts?

Has this been done before?


Re: D's memory-hungry templates

2016-06-09 Thread maik klein via Digitalmars-d

On Thursday, 9 June 2016 at 14:46:12 UTC, tsbockman wrote:
While working on a small PR 
(https://github.com/dlang/phobos/pull/4420), I noticed that D's 
template computation system has horrific memory consumption (as 
well as being very slow).


[...]


I run into the same issues with 
https://maikklein.github.io/2016/03/01/metaprogramming-typeobject/


I think doing metaprogramming that way is really neat but the 
memory consumption if I remember correctly was around 50 times 
worse than doing it without "type objects".


Also C++ beat D in every compile time meta programming benchmark 
that I have tested.


The only time when D was roughly as fast as C++ was with string 
mixins but they are even more memory hungry.


Stuff like filtering odd integers from an AliasSeq of 100k 
elements etc. I mostly recreated those benchmarks in D 
https://github.com/boostorg/hana/tree/master/benchmark


The only time when D compiled roughly as fast as C++ was with 
string mixins and they are even more memory hungry.


Re: Andrei's list of barriers to D adoption

2016-06-06 Thread maik klein via Digitalmars-d

On Monday, 6 June 2016 at 02:20:52 UTC, Walter Bright wrote:
Andrei posted this on another thread. I felt it deserved its 
own thread. It's very important.

-
I go to conferences. Train and consult at large companies. 
Dozens every year, cumulatively thousands of people. I talk 
about D and ask people what it would take for them to use the 
language. Invariably I hear a surprisingly small number of 
reasons:


* The garbage collector eliminates probably 60% of potential 
users right off.


* Tooling is immature and of poorer quality compared to the 
competition.


* Safety has holes and bugs.

* Hiring people who know D is a problem.

* Documentation and tutorials are weak.

* There's no web services framework (by this time many folks 
know of D, but of those a shockingly small fraction has even 
heard of vibe.d). I have strongly argued with Sönke to bundle 
vibe.d with dmd over one year ago, and also in this forum. 
There wasn't enough interest.


* (On Windows) if it doesn't have a compelling Visual Studio 
plugin, it doesn't exist.


* Let's wait for the "herd effect" (corporate support) to start.

* Not enough advantages over the competition to make up for the 
weaknesses above.
I am a D user since probably 6 months now, I can give you my list 
from the point of view of a game dev.


I concentrate on the negatives

* The garbage collector eliminates probably 60% of potential 
users right off.


I think that is mostly true, while it is possible to avoid the GC 
it is not easy. The biggest problem is that you would need to use 
something like unqiue_ptr and shared_ptr.


While you can create this, almost nothing in Phobos works with 
non copyable types. Unqiue and RefCounted both still use the GC 
and Unique can't be used (any?) container in Phobos currently. 
You can't even use writeln on it, because almost anything in 
Phobos "copies" behind your back.


This makes avoiding the GC not really practical unless you are 
recreating a lot of stuff from scratch and make it move aware. I 
don't think many want to do this on their own.


* Tooling is immature and of poorer quality compared to the 
competition.


Honestly I think most languages have very poor tooling but D's is 
especially bad. I say that without any anger nor do I want to 
point fingers. I basically use D without any tooling right now 
except GDB and only use DCD for autocompleting import statements.


* Error messages

I think most error messages are actually not bad, but some error 
messages especially compile time lambdas that are passed into 
templates are especially bad. Most of the time you literally get 
no message at all if the error message is inside that lambda.


* Compiler not written in D

DMD backend is not open source and is written in(C++?). ldc is 
written in C++.


I don't think that is a big issue now, but at the time of 
evaluating D I was mostly wondering why D's compiler weren't 
implemented in D itself.


* Long standing issues

There are so many long standing issues in the bug tracker that 
also made me wonder how active the community is in fixing stuff. 
Most issues that I encountered where phobos issues that I worked 
around by creating my own stuff. Like a zipped range not being 
able to mutate its elements.


At one point I will try contribute all this stuff but my 
implementations use a lot of stuff that I have written myself and 
are not currently in phobos.


* Size of community and getting help

I think D's community is very helpful and we have a few experts 
that are answering my questions on stackoverflow very often.


But you usually have to wait for some answers quite some time. 
For example most questions have already been answered for C++ and 
if you have some advanced question for C++ you usually get an 
answer in a matter of minutes.


I think D is a amazingly well designed language and if we could 
"fix" tooling(autocompletion, renaming, goto definition etc), gc 
and error messages, I think the other issues would be fixed 
indirectly by having more users.




Implicit conversion without alias this?

2016-06-03 Thread maik klein via Digitalmars-d-learn

I have my own version of Algebraic

struct Ok(T){
T value;
}

struct Err(E){
E value;
}

auto ok(T)(auto ref T value){
return Ok!T(value);
}

auto err(E)(auto ref E err){
return Err!E(err);
}

alias Result(T, E) = Algebraic!(Ok!T, Err!E);

I have a constructor and opAssign which allows me to write

Result!(int, string) res = ok(5);

But it seems strange that I can not do the same thing to function 
returns


Result!(int, string) test(){
return ok(5); // Error: cannot implicitly convert expression 
(ok(5)) of type Ok!int to Algebraic!(Ok!int, Err!string)

}

I can not add implicit conversion with alias this from Ok!T to 
Result!(T, ???) because "Ok" doesn't know about the error type.


That is a bit unergonomic because I always seem to need the full 
type


like

auto ok(T, E)(auto ref T value){
return Result!(T, E)(Ok!T(value));
}

I basically try to mirror 
http://rustbyexample.com/std/result.html but I don't think that 
is possible.


Any ideas?





Re: std.experimental.alloctor does not work with non default constructible types

2016-06-03 Thread maik klein via Digitalmars-d

On Friday, 3 June 2016 at 12:16:54 UTC, Andrei Alexandrescu wrote:

On 6/3/16 7:57 AM, maik klein wrote:
On Friday, 3 June 2016 at 11:52:52 UTC, Andrei Alexandrescu 
wrote:

On 6/3/16 7:47 AM, maik klein wrote:

[...]


Looks like a bug. Do you have a short repro? -- Andrei


import std.experimental.allocator;
struct Foo{
 @disable this();
}
auto foos = theAllocator.makeArray!Foo(100);

Error messsage:

../../.dub/packages/experimental_allocator-2.70.0-b1/src/std/experimental/allocator/package.d(576,34):
Error: variable
std.experimental.allocator.uninitializedFillDefault!(Foo).uninitializedFillDefault.t
default construction is disabled for type immutable(Foo)
../../.dub/packages/experimental_allocator-2.70.0-b1/src/std/experimental/allocator/package.d(612,36):
Error: template instance
std.experimental.allocator.uninitializedFillDefault!(Foo) error
instantiating
source/breeze/util/algebraic.d(91,43):instantiated 
from here:

makeArray!(Foo, IAllocator)


That should be fixable, please submit to bugzilla. Thanks! -- 
Andrei


Thanks, I opened an issue here 
https://issues.dlang.org/show_bug.cgi?id=16117


I just used makeArray because it was just so convenient to use 
but I guess I could also switch to the untyped interface if this 
proves to be a blocker.




Re: std.experimental.alloctor does not work with non default constructible types

2016-06-03 Thread maik klein via Digitalmars-d

On Friday, 3 June 2016 at 11:52:52 UTC, Andrei Alexandrescu wrote:

On 6/3/16 7:47 AM, maik klein wrote:
I rely a lot on std.experimental.alloctor for my "game 
engine". I have
just finished creating my own version for "Algebraic" and I 
want to

disable to default construction as it would make no sense.

I have also created my own containers, the problem is that I 
can not use
my version of "Algebraic" in any of my containers because all 
of them
are using std.experimental.alloctor.makeArray which can not be 
used with

non default constructible types.

While I don't want to have any default constructed type of 
Algebraic, I
really don't care for uninitialized values that I will never 
use anyway.


I am sure there is a workaround with unions but it would be 
nice if
makeArray/expandArray would just support non default 
constructible types.


Thoughts?


Looks like a bug. Do you have a short repro? -- Andrei


import std.experimental.allocator;
struct Foo{
@disable this();
}
auto foos = theAllocator.makeArray!Foo(100);

Error messsage:

../../.dub/packages/experimental_allocator-2.70.0-b1/src/std/experimental/allocator/package.d(576,34):
 Error: variable 
std.experimental.allocator.uninitializedFillDefault!(Foo).uninitializedFillDefault.t
 default construction is disabled for type immutable(Foo)
../../.dub/packages/experimental_allocator-2.70.0-b1/src/std/experimental/allocator/package.d(612,36):
 Error: template instance 
std.experimental.allocator.uninitializedFillDefault!(Foo) error instantiating
source/breeze/util/algebraic.d(91,43):instantiated from 
here: makeArray!(Foo, IAllocator)





std.experimental.alloctor does not work with non default constructible types

2016-06-03 Thread maik klein via Digitalmars-d
I rely a lot on std.experimental.alloctor for my "game engine". I 
have just finished creating my own version for "Algebraic" and I 
want to disable to default construction as it would make no sense.


I have also created my own containers, the problem is that I can 
not use my version of "Algebraic" in any of my containers because 
all of them are using std.experimental.alloctor.makeArray which 
can not be used with non default constructible types.


While I don't want to have any default constructed type of 
Algebraic, I really don't care for uninitialized values that I 
will never use anyway.


I am sure there is a workaround with unions but it would be nice 
if makeArray/expandArray would just support non default 
constructible types.


Thoughts?


Re: A ready to use Vulkan triangle example for D

2016-05-30 Thread maik klein via Digitalmars-d-announce

On Monday, 30 May 2016 at 11:30:24 UTC, Manuel König wrote:

On Fri, 27 May 2016 18:40:24 +, maik klein wrote:


[...]


Nice, runs without errors for me. I have a triangle example 
project too, but weird stuff happens when I resize my window. I 
see your window has fixed size, maybe I have more luck adding 
window resizing to your example. Will tell you when I get it to 
work.


Does anyone here have a working vulkan window with a resizable 
window?

I think its more of an xcb issue than a vulkan issue in my code,
because even when I do
- create xcb window with dimensions (w1, h1)
- resize it to dimensions (w2, h2) (no vulkan interaction yet)
- create a vulkan surface from that window
- render
the rendered image still has the original size (w1, h1), and I 
loose my
vulkan device when (w2, h2) deviates too much from the original 
size.


You probably have to update a lot of code

https://github.com/MaikKlein/VulkanTriangleD/blob/master/source/app.d

Do a ctrl+f vkcontext.width and you will see all the code that 
needs to be updated.


Re: A ready to use Vulkan triangle example for D

2016-05-28 Thread maik klein via Digitalmars-d-announce

On Sunday, 29 May 2016 at 00:37:54 UTC, Alex Parrill wrote:

On Saturday, 28 May 2016 at 19:32:58 UTC, maik klein wrote:
Btw does this even work? I think the struct initializers have 
to be


Foo foo = { someVar: 1 };

`:` instead of a `=`

I didn't do this because I actually got autocompletion for  
`vertexInputStateCreateInfo.` and that meant less typing for 
me.


No, its equals. In C it's a colon, which is a tad confusing.


https://dpaste.dzfl.pl/bd29c970050a


Re: A ready to use Vulkan triangle example for D

2016-05-28 Thread maik klein via Digitalmars-d-announce

On Saturday, 28 May 2016 at 17:50:30 UTC, Alex Parrill wrote:

On Saturday, 28 May 2016 at 10:58:05 UTC, maik klein wrote:


derelict-vulcan only works on windows, dvulkan doesn't have 
the platform dependend surface extensions for xlib, xcb, w32 
and wayland. Without them Vulkan is unusable for me.


I really don't care what I use, I just wanted something that 
works.


Platform extension support will be in the next release of 
d-vulkan. It doesn't include platform extensions now because I 
wanted to find a way to implement it without tying d-vulkan to 
a specific set of bindings, though I can't seem to find a good 
solution unfortunately... I personally use the git version of 
GLFW, which handles the platform-dependent surface handling for 
me.


As for the demo itself... It might help explain things more if 
the separate stages (instance creation, device creation, 
setting up shaders, etc) were split into their own functions, 
instead of stuffing everything into `main`.


Struct initializers are also useful when dealing with Vulkan 
info structs, since you don't have to repeat the variable name 
each time. Ex this:


VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo 
= {};
vertexInputStateCreateInfo.sType = 
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;

vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = 


vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexAttributeDescriptions = 



Can become:

VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo 
= {
sType = 
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // 
also sType is pre-set with erupted or d-derelict

vertexBindingDescriptionCount = 1,
pVertexBindingDescriptions = ,
vertexAttributeDescriptionCount = 1,
pVertexAttributeDescriptions = ,
};


I think its personal preference, I like tutorials more if 
everything I just in the main instead of creating their own 
"architecture". Though I could probably group  with comments.


I saw that sType was a default value after a few hours and that 
is when I started using it. But at the end I was so annoyed by 
typing all the enums by hand that I mostly copied stuff from 
other people and translated it to D.


This was mostly caused by my current vim D setup with vim-dutyl 
and dcd, it is really unreliable and I didn't get any sane 
autocompletion. (I have to investigate that at some point).


Btw does this even work? I think the struct initializers have to 
be


Foo foo = { someVar: 1 };

`:` instead of a `=`

I didn't do this because I actually got autocompletion for  
`vertexInputStateCreateInfo.` and that meant less typing for me.


We need to talk about error messages of functions that are passed into other functions at compile time

2016-05-28 Thread maik klein via Digitalmars-d
I really like D's syntax for lambdas and I usually write code 
like this


  auto v = validationLayers[].all!((layerName){
return layerProps[].count!((layer){
  return strcmp(cast(const(char*))layer.layerName, layerName) 
== 0;

}) > 0;
  });

But this gives you basically 0 helpful error messages:


"Error: template 
breeze.graphics.context.createContext.all!((layerName)

{
return layerProps[].count!((layer)
{
return strcmp(cast(const(char*))layer.layerName, layerName) == 0;
}
) > 0;
}
).all cannot deduce function from argument types 
!()(const(char*)[]), candidates are:
/usr/include/dmd/phobos/std/algorithm/searching.d(113,10):
breeze.graphics.context.createContext.all!((layerName)

{
return layerProps[].count!((layer)
{
return strcmp(cast(const(char*))layer.layerName, layerName) == 0;
}
) > 0;
}
).all(Range)(Range range) if (isInputRange!Range && 
is(typeof(unaryFun!pred(range.front

dmd failed with exit code 1"

For example I simply forgot to import `count`, nothing in the 
error message is really helpful and the only way to know for sure 
is to rip the function apart, which is not a very fun thing to do.


You can't also rip it apart easily because in the case above I 
implicitly capture `layerName` in the closure for `count`.


What are you thoughts on this?





Re: A ready to use Vulkan triangle example for D

2016-05-28 Thread maik klein via Digitalmars-d-announce

On Saturday, 28 May 2016 at 03:02:23 UTC, WhatMeWorry wrote:

On Friday, 27 May 2016 at 18:40:24 UTC, maik klein wrote:

https://github.com/MaikKlein/VulkanTriangleD





Another dependency is ErupteD which I have forked myself 
because there is currently an issue with xlib-d and xcb-d with 
their versioning.




Nice work. As a person still trying to understand modern 
OpenGL, I admire your jump into Vulkan. Just a quick question 
if I may; Why did you use ErupteD over say d-vulkan or 
derelict-vulcan?  From my brief perusal of all three, they all 
seem kind of the same.


Thanks.


derelict-vulcan only works on windows, dvulkan doesn't have the 
platform dependend surface extensions for xlib, xcb, w32 and 
wayland. Without them Vulkan is unusable for me.


I really don't care what I use, I just wanted something that 
works.


A ready to use Vulkan triangle example for D

2016-05-27 Thread maik klein via Digitalmars-d-announce

https://github.com/MaikKlein/VulkanTriangleD

Currently only Linux is supported but it should be fairly easy to 
also add Windows support. Only the surface extensions have to be 
changed.


The example requires Vulkan ready hardware + driver + LunarG sdk 
with validation layer + sdl2.


Another dependency is ErupteD which I have forked myself because 
there is currently an issue with xlib-d and xcb-d with their 
versioning.


The example is also not currently completely 100% correct but it 
should run on most hardware.


I don't get any validation errors but I am sure I have made a few 
mistakes along the way.


It took me around 15 hours to get to a working triangle and I 
hope this might help someone who is interested in Vulkan.


Re: Discuss vulkan erupted, the other auto-generated vulkan binding

2016-05-20 Thread maik klein via Digitalmars-d

On Thursday, 19 May 2016 at 15:44:27 UTC, ParticlePeter wrote:

On Wednesday, 18 May 2016 at 20:28:09 UTC, Manuel König wrote:

[...]


As far as I understand Mike it is still possible. Suppose you 
build an engine based on (d-)vulkan/erupted, lets call it 
Turtle-Engine, you would also specify sub-configurations for 
xcb, xlib, win, ... and you could support any of 
(d-)vulkans/erupted sub-configs in your corresponding configs. 
When some dude (no sexual prejudice meant) wants to write a 
Turtle-App, which is based on your Turtle-Engine he decides how 
many of your configs representing platforms he would like to 
support. Now you see, as the language architect pointed out, 
its turtles all the way down.


I am a bit slow, how do I add xcb as a dependency?

/source/erupted/types.d(3335,16): Error: module xcb is in file 
'xcb/xcb.d' which cannot be read


Can I add dependencies for dependencies in dub?


Re: Battle-plan for CTFE

2016-05-11 Thread maik klein via Digitalmars-d-announce

On Monday, 9 May 2016 at 16:57:39 UTC, Stefan Koch wrote:

Hi Guys,

I have been looking into the DMD now to see what I can do about 
CTFE.

Unfortunately It is a pretty big mess to untangle.
Code responsible for CTFE is in at least 3 files.
[dinterpret.d, ctfeexpr.d, constfold.d]
I was shocked to discover that the PowExpression actually 
depends on phobos! (depending on the exact codePath it may or 
may not compile...)
which let to me prematurely stating that it worked at ctfe 
[http://forum.dlang.org/thread/ukcoibejffinknrbz...@forum.dlang.org]


My Plan is as follows.

Add a new file for my ctfe-interpreter and update it gradually 
to take more and more of the cases the code in the files 
mentioned above was used for.


Do Dataflow analysis on the code that is to be ctfe'd so we can 
tell beforehand if we need to store state in the ctfe stack or 
not.


Or baring proper data-flow analysis: RefCouting the variables 
on the ctfe-stack could also be a solution.


I will post more details as soon as I dive deeper into the code.


What is the current problem with ctfe?

Before I switched from C++ to D a few months ago I was heavily 
using boost hana in C++. I tried to emulate hana in D which 
worked quite well but the compile time performance was absolutely 
horrific


https://maikklein.github.io/2016/03/01/metaprogramming-typeobject/

After that I tried a few other things and I compared the compile 
times with


https://github.com/boostorg/hana/tree/master/benchmark

which I could never beat. The fastest thing, if I remember 
correctly, was string mixins but they used up too much memory.


But I have to say that I don't know much about the D internals 
and therefore don't know how I would optimize ct code execution.




Re: C#7 features

2016-05-09 Thread maik klein via Digitalmars-d-announce

On Monday, 9 May 2016 at 13:09:24 UTC, Jacob Carlborg wrote:

On 2016-05-09 14:46, John wrote:

C# 7's tuples are something different though. They don't even 
map to

System.Tuple. The syntax is:

   (int x, int y) GetPoint() {
 return (500, 400);
   }

   var p = GetPoint();
   Console.WriteLine($"{p.x}, {p.y}");


Would be nice to have in D. Both with and without named fields.


I mean it is not much shorter than in D

alias Point = Tuple!(int, "x", int, "y");
Point getPoint(){
return Point(500, 400);
}

What would be nice though if tuples would be implicitly 
convertible to named tuples, if the types matches.


Tuple!(int, "x", int, "y") getPoint(){
return tuple(500, 400);
}


Re: So, About That Official Blog...

2016-05-06 Thread maik klein via Digitalmars-d

On Friday, 6 May 2016 at 03:01:07 UTC, Dicebot wrote:

On 05/06/2016 04:26 AM, Jack Stouffer wrote:
Also, I can just include a simple JS library for the same 
auto-highlighting functionality.


Please prefer static generators and pygment-like highlighters 
to JS whenever possible. Demanding JS enabled for simple 
programming blog to be rendered decently it simply outrageous.


I would also recommend a static site generator, I currently use 
Hugo https://gohugo.io/ though it is written it Go haha. Jekyll 
got really slow after 30 blog entries, especially if you want to 
do the syntax highlighting offline.


Re: Lets talk about fibers

2016-04-16 Thread maik klein via Digitalmars-d

Here is an interesting talk from Naughty Dog

http://www.gdcvault.com/play/1022186/Parallelizing-the-Naughty-Dog-Engine

They move Fibers between threads.

A rough overview:

You create task A that depends on task B. The task is submitted 
as a fiber and executed by a thread. Now task A has to wait for 
task B to finish so you hold the fiber and put it into a queue, 
you also create an atomic counter that tracks all dependencies, 
once the counter reaches 0 you know that all dependencies have 
finished.


Now you put task A into a queue and execute a different task. 
Once a thread completes a task it looks into the queue and checks 
if there is one task that has a counter of 0, which means it can 
continue to execute that task.


Now move that fiber/task onto a free thread and you can continue 
to execute that fiber.


What is the current state of fibers in D? I have asked this 
question on SO 
https://stackoverflow.com/questions/36663720/how-to-pass-a-fiber-to-a-thread




Re: Linking a shared library in dub

2016-03-30 Thread maik klein via Digitalmars-d-learn

On Thursday, 31 March 2016 at 00:06:19 UTC, maik klein wrote:

On Wednesday, 30 March 2016 at 17:38:15 UTC, maik klein wrote:
On Wednesday, 30 March 2016 at 12:46:08 UTC, Vadim Lopatin 
wrote:

On Wednesday, 30 March 2016 at 12:19:34 UTC, maik klein wrote:
I want to finally convert my project to windows. That means 
that I want to build it on windows and linux.


The problem is that I have one external c library 'glfw'. I 
thought that I would just link with it explicitly but 
actually I am not completely sure how.


Try using Derelict based binding

http://code.dlang.org/packages/derelict-glfw3


I am already using the derelict binding but I want to 
explicitly link with the .a or .so c lib because I don't have 
a package manager on windows.


Okay I think I understand know what you mean, I think you meant 
I should use dynamic loading like this right?


DerelictGLFW3.load("deps/glfw/build/src/libglfw.so");

This works but I am not sure yet that I want to load it at the 
application level.


I was able to link with a static lib like this

dependency "derelict-glfw3" version="~>2.0.0"
subConfiguration "derelict-glfw3" "derelict-glfw3-static"
sourceFiles "deps/glfw/build/src/libglfw3.a"
libs "Xi" "pthread" "X11" "Xxf86vm" "Xrandr" "pthread" "GL" "GLU" 
"Xinerama" "Xcursor"




Re: Linking a shared library in dub

2016-03-30 Thread maik klein via Digitalmars-d-learn

On Wednesday, 30 March 2016 at 17:38:15 UTC, maik klein wrote:
On Wednesday, 30 March 2016 at 12:46:08 UTC, Vadim Lopatin 
wrote:

On Wednesday, 30 March 2016 at 12:19:34 UTC, maik klein wrote:
I want to finally convert my project to windows. That means 
that I want to build it on windows and linux.


The problem is that I have one external c library 'glfw'. I 
thought that I would just link with it explicitly but 
actually I am not completely sure how.


Try using Derelict based binding

http://code.dlang.org/packages/derelict-glfw3


I am already using the derelict binding but I want to 
explicitly link with the .a or .so c lib because I don't have a 
package manager on windows.


Okay I think I understand know what you mean, I think you meant I 
should use dynamic loading like this right?


DerelictGLFW3.load("deps/glfw/build/src/libglfw.so");

This works but I am not sure yet that I want to load it at the 
application level.


Re: Linking a shared library in dub

2016-03-30 Thread maik klein via Digitalmars-d-learn

On Wednesday, 30 March 2016 at 12:46:08 UTC, Vadim Lopatin wrote:

On Wednesday, 30 March 2016 at 12:19:34 UTC, maik klein wrote:
I want to finally convert my project to windows. That means 
that I want to build it on windows and linux.


The problem is that I have one external c library 'glfw'. I 
thought that I would just link with it explicitly but actually 
I am not completely sure how.


Try using Derelict based binding

http://code.dlang.org/packages/derelict-glfw3


I am already using the derelict binding but I want to explicitly 
link with the .a or .so c lib because I don't have a package 
manager on windows.


Linking a shared library in dub

2016-03-30 Thread maik klein via Digitalmars-d-learn
I want to finally convert my project to windows. That means that 
I want to build it on windows and linux.


The problem is that I have one external c library 'glfw'. I 
thought that I would just link with it explicitly but actually I 
am not completely sure how.



So I just added a submodule, cloned glfw and build it as a shared 
library


lflags "deps/glfw/build/src/libglfw.so"


This is the eps/glfw/build/src folder:

total 196K
drwxr-xr-x 3 maik users 4.0K Mar 30 14:07 .
drwxr-xr-x 6 maik users 4.0K Mar 30 14:07 ..
drwxr-xr-x 3 maik users 4.0K Mar 30 14:07 CMakeFiles
-rw-r--r-- 1 maik users 2.1K Mar 30 14:07 cmake_install.cmake
-rw-r--r-- 1 maik users   56 Mar 30 14:07 glfw3Config.cmake
-rw-r--r-- 1 maik users 1.6K Mar 30 14:07 glfw3ConfigVersion.cmake
-rw-r--r-- 1 maik users  348 Mar 30 14:07 glfw3.pc
-rw-r--r-- 1 maik users 3.1K Mar 30 14:07 glfw_config.h
lrwxrwxrwx 1 maik users   12 Mar 30 14:07 libglfw.so -> 
libglfw.so.3
lrwxrwxrwx 1 maik users   14 Mar 30 14:07 libglfw.so.3 -> 
libglfw.so.3.2

-rwxr-xr-x 1 maik users 142K Mar 30 14:07 libglfw.so.3.2
-rw-r--r-- 1 maik users  18K Mar 30 14:07 Makefile


But If I try to build it with dub, i'll get "./bin/breeze_opengl: 
error while loading shared libraries: libglfw.so.3: cannot open 
shared object file: No such file or directory"


But as you can see it is in there. I get the same error with

lflags "deps/glfw/build/src/libglfw.so.3"
lflags "deps/glfw/build/src/libglfw.so.3.2"

Also the path seems to be correct because if I try to add a file 
that not exisit I get a different error

lflags "deps/glfw/build/src/doesnotexist.so"

/usr/bin/ld: cannot find deps/glfw/build/src/doesnotexist.so: No 
such file or directory

collect2: error: ld returned 1 exit status

Am I doing something wrong?


Re: I need some help benchmarking SoA vs AoS

2016-03-29 Thread maik klein via Digitalmars-d-learn

On Tuesday, 29 March 2016 at 21:27:15 UTC, ZombineDev wrote:

On Saturday, 26 March 2016 at 17:43:48 UTC, maik klein wrote:

On Saturday, 26 March 2016 at 17:06:39 UTC, ag0aep6g wrote:

On 26.03.2016 18:04, ag0aep6g wrote:

https://gist.github.com/aG0aep6G/a1b87df1ac5930870ffe/revisions


PS: Those enforces are for a size of 100_000 not 1_000_000, 
because I'm impatient.


Thanks, okay that gives me more more reliable results.
for 1_000_000

benchmarking complete access
AoS: 1 sec, 87 ms, 266 μs, and 4 hnsecs
SoA: 1 sec, 491 ms, 186 μs, and 6 hnsecs
benchmarking partial access
AoS: 7 secs, 167 ms, 635 μs, and 8 hnsecs
SoA: 1 sec, 20 ms, 573 μs, and 1 hnsec

This is sort of what I expected. I will do a few more 
benchmarks now. I probably also randomize the inputs.


Can you benchmark my implementation 
(http://dpaste.dzfl.pl/3de1e18756f8) against yours? It should 
have roughly the same API, except that mine doesn't support 
pre-allocation (reserving capacity) - I wanted to keep it 
minimalistic.
During access it should have the same performance, however the 
insertion behavior should be noticeably different. I'm 
interested to see if one larger allocation on insertion would 
be faster than a number of small ones (or vice-versa). Though, 
AoS should be the fastest in this regard (growth performance).


Yes I'll do it tomorrow, though I am not sure how much you can 
rely on the data. I think it really depends on how fragmented the 
heap currently is.


I will also benchmark memory access, just to see if there is any 
difference. I recently asked a question about it on SO 
https://stackoverflow.com/questions/36296960/pros-and-cons-of-one-big-buffer-vs-many-smaller-buffer?


Doesn't seem to be well received though.


Re: [Blog post] Why and when you should use SoA

2016-03-27 Thread maik klein via Digitalmars-d-announce

On Sunday, 27 March 2016 at 16:18:18 UTC, ZombineDev wrote:

On Saturday, 26 March 2016 at 20:55:17 UTC, maik klein wrote:

[snip]

Thanks, yes that is simpler.

But I am not sure that I want to have pluggable containers in 
SOA, mostly because every field would have overhead from the 
container.


For example array has size, length etc as overhead, but it is 
also not that much and probably won't matter anyway.


But I also thought about it, maybe sometimes I want to use a 
map instead of an array for some fields. So I need to have a 
way of telling which field should get which container.


Maybe something like this:

SOA!(Foo, Array, HashMap, DList);

The current implementation is mostly for experimentation.


Never mind. Anything with memory representation different from 
an array would ruin cache locality. My thinking was that using 
a container defined somewhere else would simplify the code.


I tried a couple approaches and came up with the following, 
which I think this is the most efficient in terms of space 
overhead and number of allocations (but still generic), 
implementation that is possible:

http://dpaste.dzfl.pl/3de1e18756f8

It took me a couple of tries, but overall I'm satisfied my 
code, although is it's more low-level and more meta-heavy than 
yours.


I also thought about doing it this way but I wasn't sure that it 
would be better overall.


I am not sure that one big buffer is better than several smaller 
ones overall.


I mean it is definitely more space efficient because you only 
have one pointer and reallocation is one big reallocation instead 
of smaller ones.


But it seems to me that smaller reallocations might be cheaper 
because you should have a higher chance of growing without 
reallocating.


Then again your approach will have no fragmented memory at all 
which might also be a good thing.


I just have not enough knowledge to know exactly what is better. 
Maybe we could maintain our implementations side by side and 
benchmark them for certain scenarios.


A lot of functionality is still missing in my implementation.


Re: futures and related asynchronous combinators

2016-03-27 Thread maik klein via Digitalmars-d-announce

On Sunday, 27 March 2016 at 07:16:53 UTC, Vlad Levenfeld wrote:

https://github.com/evenex/future/

I've been having to do a lot of complicated async work lately 
(sometimes multithreaded, sometimes not), and I decided to 
abstract a some patterns out and unify them with a little bit 
of formalism borrowed from functional languages. I've aimed to 
keep things as simple as possible while providing a full spread 
of functionality. This has worked well for me under a variety 
of use-cases, but YMMV of course.


[...]


What happens when you spawn a future inside a future and call 
await? Will the 'outer' future be rescheduled?




Re: [Blog post] Why and when you should use SoA

2016-03-26 Thread maik klein via Digitalmars-d-announce

On Sunday, 27 March 2016 at 02:20:09 UTC, Alex Parrill wrote:
Also I forgot to mention: Your "Isn’t SoA premature 
optimization?" section is a textbook YAGNI violation. I might 
have to refactor my web app to support running across multiple 
servers and internationalization when it becomes the Next Big 
Thing, but it more than likely will not become the Next Big 
Thing, so it's not productive for me to add additional 
complexity to "make sure my code scales" (and yes, SoA does add 
complexity, even if you hide it with templates and methods).


Personally I don't think it adds any complexity but everyone has 
to decide that for him or herself. But it is quite annoying to 
refactor from AoS to SoA (at least with my implementation).


And you are right for webdev that probably doesn't matter as much 
but for games you hit that level pretty fast.


It is just too easy for game developers to push the limits. "Oh 
hey lets see how many AI's I can spawn". Maybe you can have 10 
AI's or 100 AI's running around. Or maybe you have a gameserver 
for a completive game that runs at 100 updates per seconds, 
wouldn't it be nice to actually have it run at 500 on the same 
hardware?


Basically as a gamedev you are always resource bound.


Re: [Blog post] Why and when you should use SoA

2016-03-26 Thread maik klein via Digitalmars-d-announce

On Sunday, 27 March 2016 at 01:39:44 UTC, Simen Kjaeraas wrote:

On Friday, 25 March 2016 at 01:07:16 UTC, maik klein wrote:

Link to the blog post: https://maikklein.github.io/post/soa-d/
Link to the reddit discussion: 
https://www.reddit.com/r/programming/comments/4buivf/why_and_when_you_should_use_soa/


Neat. I've actually thought about writing exactly this kind of 
template for the fun of it. Thank you for showing how it'd work.


Btw, your use of Tuple!ArrayTypes for the 'containers' field 
strikes me as unnecessary, as ArrayTypes on its own would cover 
all your use cases.


--
  Simen


Yeah you are right, initially I thought I would use the a "named" 
tuple, like tuple(5, "field1", 1.0f, "field2"); but it was just 
unnecessary.




Re: [Blog post] Why and when you should use SoA

2016-03-26 Thread maik klein via Digitalmars-d-announce

On Saturday, 26 March 2016 at 23:31:23 UTC, Alex Parrill wrote:

On Friday, 25 March 2016 at 01:07:16 UTC, maik klein wrote:

Link to the blog post: https://maikklein.github.io/post/soa-d/
Link to the reddit discussion: 
https://www.reddit.com/r/programming/comments/4buivf/why_and_when_you_should_use_soa/


I think structs-of-arrays are a lot more situational than you 
make them out to be.


You say, at the end of your article, that "SoA scales much 
better because you can partially access your data without 
needlessly loading unrelevant data into your cache". But most 
of the time, programs access struct fields close together in 
time (i.e. accessing one field of a struct usually means that 
you will access another field shortly). In that case, you've 
now split your data across multiple cache lines; not good.


Your ENetPeer example works against you here; the the 
packetThrottle* variables would be split up into different 
arrays, but they will likely be checked together when 
throttling packets. Though admittedly, it's easy to fix; put 
fields likely to be accessed together in their own struct.


The SoA approach also makes random access more inefficient and 
makes it harder for objects to have identity. Again, your 
ENetPeer example works against you; it's common for servers to 
need to send packets to individual clients rather than 
broadcasting them. With the SoA approach, you end up accessing 
a tiny part of multiple arrays, and load several cache lines 
containing data for ENetPeers that you don't care about (i.e. 
loading irrelevant data).


I think SoA can be faster if you are commonly iterating over a 
section of a dataset, but I don't think that's a common 
occurrence. I definitely think it's unwarranted to conclude 
that SoAs "scale much better" without noting when they scale 
better, especially without benchmarks.


I will admit, though, that the template for making the 
struct-of-arrays is a nice demonstration of D's templates.


The next blog post that I am writing will contain a few 
benchmarks for SoA vs AoS.



But most of the time, programs access struct fields close 
together in time (i.e. accessing one field of a struct usually 
means that you will access another field shortly). In that 
case, you've now split your data across multiple cache lines; 
not good.


You can still group the data together if you always access it 
together.  What you wrote is actually not true for arrays, at 
least the way you wrote it.


Array!Foo arr

Iterating over 'arr', you will always load the complete Foo 
struct into memory, unless you hide stuff behind pointers.


The SoA approach also makes random access more inefficient and 
makes it harder for objects to have identity.


No it actually makes it much better because you only have to load 
the relevant stuff into memory.


But you usually don't look at your objects in isolation.

AoS makes sense if you always care about all fields like for 
example Array!Vector3. You usually access all components of a 
vector.


What you lose is the general feel of oop.

Vector add(Vector a, Vector b);

Array!Vector vectors;

add(vectors[index1], vectors[index2]);

This really just won't work with SoA, especially if you want to 
mutate the data behind with a reference. For this you would just 
use AoS.


Btw I have done a lot of benchmarks and SoA in the worst case was 
always as fast as SoA.


But once you actually only access partial data, SoA can 
potentially be much faster.


This is what I mean with scaling

You start with

struct Test{
  int i;
  int j;
}
Array!Test tests;

and you have absolutely no performance problem for 'tests' 
because it is just so small.


But after a few years Test will have grown much bigger.

struct Test{
  int i;
  int j;
  int[100] junk;
}

If you use SoA you can always add stuff without any performance 
penalty, that is why I said that it "scales" better.


But as I have said in the blog post, you will not always replace 
AoS with SoA, but you should replace AoS with SoA where it makes 
sense.


I think SoA can be faster if you are commonly iterating over a 
section of a dataset, but I don't think that's a common 
occurrence.


This happens in games very often when you use inheritance, your 
objects just will grow really big the more functionality you add.


Like for example you just want to move all objects based on 
velocity, so you just care about Position, Velocity. You don't 
have to load anything else into memory.


An entity component system really is just SoA at its core.


Re: I need some help benchmarking SoA vs AoS

2016-03-26 Thread maik klein via Digitalmars-d-learn

On Saturday, 26 March 2016 at 17:06:39 UTC, ag0aep6g wrote:

On 26.03.2016 18:04, ag0aep6g wrote:

https://gist.github.com/aG0aep6G/a1b87df1ac5930870ffe/revisions


PS: Those enforces are for a size of 100_000 not 1_000_000, 
because I'm impatient.


Thanks, okay that gives me more more reliable results.
for 1_000_000

benchmarking complete access
AoS: 1 sec, 87 ms, 266 μs, and 4 hnsecs
SoA: 1 sec, 491 ms, 186 μs, and 6 hnsecs
benchmarking partial access
AoS: 7 secs, 167 ms, 635 μs, and 8 hnsecs
SoA: 1 sec, 20 ms, 573 μs, and 1 hnsec

This is sort of what I expected. I will do a few more benchmarks 
now. I probably also randomize the inputs.


I need some help benchmarking SoA vs AoS

2016-03-26 Thread maik klein via Digitalmars-d-learn
I recently wrote an article an SoA 
https://maikklein.github.io/post/soa-d/


But now I wanted to actually benchmark SoA vs AoS and it is so 
much harder than I thought.


In DMD SoA basically always beats AoS by a huge chuck. SoA is 
always at least twice as fast compared to AoS.


But with LDC it is just really hard to get reliable results.

I have created a example without any dependencies

http://dpaste.dzfl.pl/877a925e0a33

dub run -b release --compiler=dmd

benchmarking complete access
AoS: 419 ms, 938 μs, and 2 hnsecs
SoA: 11 μs and 8 hnsecs
benchmarking partial access
AoS: 521 ms, 381 μs, and 3 hnsecs
SoA: 5 μs


dub run -b release --compiler=ldc

benchmarking complete access
AoS: 1 μs and 6 hnsecs
SoA: 1 hnsec
benchmarking partial access
AoS: 1 hnsec
SoA: 1 hnsec


The problem I have is that LDC always seems to optimize the 
functions too much. At least one function executes always in "1 
hnsec".


When I do manage do create an testcase where AoS and SoA have a 
reasonable time, then they are equally fast, no matter what I do.


What I wanted to see:

If I iterate over a collection and I always access all members, I 
would assume that AoS vs SoA should be equally fast.


If I iterate over a collection where the elements have a big size 
and I only access some members I would assume SoA to be much 
faster.


Any help tips are greatly appreciated.


[Blog post] Why and when you should use SoA

2016-03-24 Thread maik klein via Digitalmars-d-announce

Link to the blog post: https://maikklein.github.io/post/soa-d/
Link to the reddit discussion: 
https://www.reddit.com/r/programming/comments/4buivf/why_and_when_you_should_use_soa/


Implementing virtual dispatch in D

2016-03-19 Thread maik klein via Digitalmars-d-learn
So this is mostly curiosity and not completely related to D but I 
would like to know how a vtable is actually implemented. All the 
explanations that I have seen so far are a bit vague and it would 
be nice to actually see some code.


I tried to implement the following myself

interface Something{
   void print();
   int getNumber();
}

This is how I would do it:

struct VDispatch(Types...){
void* vptr;
char typeId;

void print(){
foreach(index, type; Types){
if(index == typeId){
(cast(type*)vptr).print();
}
}
}

int getNumber(){
foreach(index, type; Types){
if(index == typeId){
return (cast(type*)vptr).getNumber();
}
}
throw new Error("Unknown Type");
}

this(T)(T* ptr){
import std.meta: staticIndexOf;
vptr = cast(void*)ptr;
typeId = staticIndexOf!(T, Types);
}
}


struct Foo{
int number;
void print(){
import std.stdio;
writeln("Foo: ", number);
}
int getNumber(){
return number;
}
}

struct Bar{
int number;
void print(){
import std.stdio;
writeln("Bar: ", number);
}
int getNumber(){
return number;
}
}

unittest{
import std.stdio;
alias VFooBar = VDispatch!(Foo, Bar);
auto t = VFooBar(new Foo(42));
auto t1 = VFooBar(new Bar(24));
t.print();
t1.print();
writeln(t.getNumber());
writeln(t1.getNumber());
}

Is this how it works internally? I assume the compiler would 
generate which types actually supported at runtime? I have 
modeled this as a variadic template "Types..." and it has to be 
managed by the user.




Bikeshed: Implementing a command queue.

2016-03-12 Thread maik klein via Digitalmars-d-learn
I wanted to implement a simple command queue in D. To give a bit 
of context, I want to create a command queue for opengl. Instead 
of interacting directly with opengl, you will create commands, 
put them in a queue and then the renderer will read those 
commands and execute the correct OpenGl calls.



I have a few options:

I could use an ADT to create commands but then all commands would 
have the size of the biggest command, also Algebraic is not nice 
nicest thing in D.


I could use runtime polymorphism `class SomeCommand: Command{}` 
but then I would end up with a lot of pointers in the queue, also 
I would need to worry about the allocations.


I have also seen this, but it is a bit more low level and is 
similar to assembly.


Queue:
Command1
int
int
Command2
float
Command3
Command4
int
float double

The first entry would always be the command which is followed by 
the arguments. So you would pop the command out and with the 
command you know how far you need to go into the queue


//pseudo code
auto c = queue.pop!Command;

if(c == Command1){
   int arg1 = queue.pop!int;
   int arg2 = queue.pop!int;
}
if(c == Command2){
   int arg1 = queue.pop!float;

}

How would you implement a simple command queue?







Iterating over thread local storage variables

2016-03-11 Thread maik klein via Digitalmars-d-learn
I want to create a logger in a multithreaded system. I wanted to 
expose a global variable like


logger.log("something");

I also wanted to reuse D's thread local global variables because 
that would make it easy to log in a multithreaded system.


This is really easy to do, but the problem is that at one point I 
need to collect all `loggers` and merge them.


So I thought about writing something like this:

import std.stdio;
class Singleton(T)
{
import std.container: Array;
private this() {}

// Cache instantiation flag in thread-local bool
// Thread local
private static bool instantiated_;

// Thread global
private __gshared Singleton!T instance_;

static Singleton!T get()
{
if (!instantiated_)
{
synchronized(Singleton!T.classinfo){
if (!instance_){
instance_ = new Singleton!T();
}
instantiated_ = true;
instance_.tls.insertBack(_.value);
}
}

return instance_;
}
__gshared Array!(T*) tls;
static T value;
}
unittest{
import std.concurrency;
import core.thread;
auto s = Singleton!int.get();
foreach(index; 0..10){
spawn((int a){
auto s = Singleton!int.get();
s.value = a;
}, index);
}
Thread.sleep( dur!("seconds")( 1 ) );
writeln("--");
foreach(p; s.tls){
writeln(*p);
}
}

Basically every time `instantiated_` is false, I know that I am 
on a new thread and then I push the reference of `value` into a 
global array.


But how do I access `tls` in a thread safe manner?

Is there another way of doing this?



Re: A comparison between C++ and D

2016-03-09 Thread maik klein via Digitalmars-d

On Wednesday, 9 March 2016 at 18:26:01 UTC, bigsandwich wrote:

On Wednesday, 9 March 2016 at 01:18:26 UTC, maik klein wrote:

[...]


C++ as well as D have anonymous functions. C++: [](auto a, auto 
b){ return a + b;} , D: (a, b) => a + b or (a, b){return a + 
b;}. As far as I know capturing other variables requires the GC 
in D. In C++ you can explicitly capture variables by copy, ref 
or move. Lambda functions in D can not return references. C++17 
will also make lambda functions available with constexpr. 
Lambda functions can also be used at compile time in D.


Is this really true?  Couldn't the closure be stored internally 
somewhere like std::function<> does in C++?


I think this is actually not true, but I wrote it because of this

http://dpaste.dzfl.pl/dd6b935df5ce

I run into this problem a couple of times.


Re: A comparison between C++ and D

2016-03-08 Thread maik klein via Digitalmars-d

On Wednesday, 9 March 2016 at 04:15:39 UTC, Walter Bright wrote:

On 3/8/2016 6:14 PM, Chris Wright wrote:

D does not let you downcast without a runtime check.


You can by casting to void* first, then the downcast.


Thanks I'll update the post later. Does this mean I could do any 
cast at compile time?


In encountered the problem here to give some context 
https://stackoverflow.com/questions/35694701/is-it-possible-to-cast-foo-to-ubytesize-at-compile-time


Basically I wanted to cast some T to ubyte[size] at compile time.

It seems that casting to void* is not a problem, but then 
upcasting from void* to ubyte[size] is still not allowed at 
compile time.


If that is not possible maybe I can just use a union instead.




Re: A comparison between C++ and D

2016-03-08 Thread maik klein via Digitalmars-d

On Wednesday, 9 March 2016 at 03:04:31 UTC, Jack Stouffer wrote:

On Wednesday, 9 March 2016 at 01:18:26 UTC, maik klein wrote:

Direct link: https://maikklein.github.io/post/CppAndD/
Reddit link: 
https://www.reddit.com/r/programming/comments/49lna6/a_comparison_between_c_and_d/


If you spot any mistakes, please let me know.


D moves objects with a bitwise copy, this means you should not 
have internal pointers.


Unless you define this(this) right
I don't think so. You can read more about it here 
https://dlang.org/phobos/std_algorithm_mutation.html#move





version(YourKeywork){...}.


Should be "Keyword".

Thanks not sure why this wasn't highlighted as an error.




Re: A comparison between C++ and D

2016-03-08 Thread maik klein via Digitalmars-d

On Wednesday, 9 March 2016 at 02:14:34 UTC, Chris Wright wrote:

On Wed, 09 Mar 2016 01:18:26 +, maik klein wrote:

[...]



[...]


Rather, declaring a variable should never throw an exception. 
Declaring a variable shouldn't create any nontrivial work.


It's trivial to create a type in D that doesn't have exception 
free default construction:


class A {
  this() { throw new Exception(); }
}
That is why I have limited it to `structs`, but I see that I have 
used `every type` before which is just wrong. Not sure why I even 
wrote it.



[...]


D has one explicit cast operator. It can do much of what 
static_cast does, though D does not let you downcast without a 
runtime check.

I should probably be more clear that this is about compile time.

[...]


You don't need the GC; you just need storage that's not on a 
stack frame below where you're catching the exception.


You can malloc an exception and throw it.

You can allocate space for an exception in the static data 
region and throw it from there, like with OutOfMemoryError.


You can allocate space for an exception on the stack in main() 
and pass it down the call chain.

Thanks, I did not know this. Will fix it asap.

[...]


That's the canonical way of doing it, but with dub, I'm seeing 
people generally adding the project name before that. So, for 
instance, I have module "roguelike.levelgen" in source file 
"source/levelgen.d". It works.



[...]


stringof evaluates an expression or type and produces a string 
representation for that value. That string representation is a 
compile- time constant. It doesn't print it at compile time or 
runtime.


Does writeln print values at compile time? That would be kind 
of strange. Maybe useful in the context of CTFE, but still a 
little unexpected.


I should be more clear. I meant writeln for runtime printing and 
pragma(msg) for compile time printing.




A comparison between C++ and D

2016-03-08 Thread maik klein via Digitalmars-d

Direct link: https://maikklein.github.io/post/CppAndD/
Reddit link: 
https://www.reddit.com/r/programming/comments/49lna6/a_comparison_between_c_and_d/


If you spot any mistakes, please let me know.


[r/cpp] Why I am not happy with C++17

2016-03-08 Thread maik klein via Digitalmars-d

Not my post but I think it is an interesting discussion.

https://www.reddit.com/r/cpp/comments/49dgdb/why_i_am_not_happy_with_c17_c_17_outlook_march/


Re: Compile time performance for metaprogramming is somewhat inconsistent

2016-03-03 Thread maik klein via Digitalmars-d

On Thursday, 3 March 2016 at 11:40:29 UTC, John Colvin wrote:

On Thursday, 3 March 2016 at 02:03:01 UTC, maik klein wrote:

Consider the following code

void main()
{
import std.stdio;
import std.range: iota, join;
import std.algorithm.iteration: map;
import std.conv: to;
import std.meta: aliasSeqOf, staticMap, AliasSeq;
enum types = "AliasSeq!(" ~ iota(0,1).map!(i => 
to!string(i)).join(",") ~ ")";

alias t = AliasSeq! (mixin(types));
//alias t1 = aliasSeqOf!(iota(0, 1));
}

't' compiles on my machine in ~3.5 seconds while 't1' needs ~1 
minute to compile. It seems that mixins are just way more 
performant than template instantiations. Any ideas why? What 
causes the slowdown and what can I improve?


What happens if you add a few extra branches to 
std.meta.aliasSeqOf, e.g. 
https://github.com/D-Programming-Language/phobos/commit/5d2cdf103bd697b8ff1a939c204dd2ed0eec0b59


Only a linear improvement but maybe worth a try?


I have tried the same thing in general and stuff like this is 
always a huge improvement.


In this case it goes down from ~60 seconds to ~3.8 seconds. I 
have done the same thing with my compile time map function, which 
gave me a drastic improvement.


I think recursion is just really bad in general for compile time 
stuff, for example your version


alias t1 = aliasSeqOf!(iota(0, 1));

compiles in 3.8 seconds and uses roughly 600mb of ram while

alias t1 = aliasSeqOf!(iota(0, 2));

compiles in 10.2 seconds and uses 1.9gb ram.

The mixin version is always the fastest but it also consumes way 
more memory and explodes before 20k elements





Re: Compile time performance for metaprogramming is somewhat inconsistent

2016-03-02 Thread maik klein via Digitalmars-d

On Thursday, 3 March 2016 at 02:26:09 UTC, cym13 wrote:

On Thursday, 3 March 2016 at 02:03:01 UTC, maik klein wrote:

Consider the following code

void main()
{
import std.stdio;
import std.range: iota, join;
import std.algorithm.iteration: map;
import std.conv: to;
import std.meta: aliasSeqOf, staticMap, AliasSeq;
enum types = "AliasSeq!(" ~ iota(0,1).map!(i => 
to!string(i)).join(",") ~ ")";

alias t = AliasSeq! (mixin(types));
//alias t1 = aliasSeqOf!(iota(0, 1));
}

[...]


As often, compiler-version-flags please?


default dub.sdl and `dub build` with dmd v2.070


Compile time performance for metaprogramming is somewhat inconsistent

2016-03-02 Thread maik klein via Digitalmars-d

Consider the following code

void main()
{
import std.stdio;
import std.range: iota, join;
import std.algorithm.iteration: map;
import std.conv: to;
import std.meta: aliasSeqOf, staticMap, AliasSeq;
enum types = "AliasSeq!(" ~ iota(0,1).map!(i => 
to!string(i)).join(",") ~ ")";

alias t = AliasSeq! (mixin(types));
//alias t1 = aliasSeqOf!(iota(0, 1));
}

't' compiles on my machine in ~3.5 seconds while 't1' needs ~1 
minute to compile. It seems that mixins are just way more 
performant than template instantiations. Any ideas why? What 
causes the slowdown and what can I improve?


Also I compared some meta stuff in C++ and D.

For example filtering

enum isEven(alias i) = i % 2 is 0;
void main()
{
import std.stdio;
import std.range: iota, join;
import std.algorithm.iteration: map;
import std.conv: to;
import std.meta: AliasSeq, Filter;
enum types = "AliasSeq!(" ~ iota(0,1).map!(i => 
to!string(i)).join(",") ~ ")";


alias t = AliasSeq!(mixin(types));
alias evenTypes = Filter!(isEven,t);
}

Someone was also so kind to create this in C++ though it looks a 
bit more crazy because he wanted to do roughly the same thing.


https://gist.github.com/ricejasonf/8c2b54c182e6038fd0ce

The D version compiles in ~14.5 seconds while the C++ version 
compiles in ~4.2 seconds. This was very surprising to me.


The more Hana like code is here 
https://github.com/boostorg/hana/blob/master/benchmark/filter/compile.hana.tuple.erb.cpp


*I wasn't yet able to run the Hana benchmarks yet because the 
build script doesn't detect my ruby executable.










Metaprogramming with type objects in D

2016-02-29 Thread maik klein via Digitalmars-d-announce

Discussion:
https://www.reddit.com/r/programming/comments/48dssq/metaprogramming_with_type_objects_in_d/

Direct link:
https://maikklein.github.io/2016/03/01/metaprogramming-typeobject/



Re: Again about benchmarks: vibe.d and other web frameworks

2016-02-26 Thread maik klein via Digitalmars-d

On Friday, 26 February 2016 at 12:14:03 UTC, Ozan wrote:

Hi
I found a benchmark page for web frameworks.
http://www.techempower.com/benchmarks/#section=data-r12=peak=query

Here, vibe.d was lost somewhere in bottom of slowest 
frameworks, what surprise me.
I tried some test out, compared jetty, servlets, grails, php 
and vibe.d with completely different result.
Running on my laptop and measured by Chrome's network time 
function vibe.d was in ms area, jetty close to seconds and php 
between. Servlets and grails are the slowest on my machine 
(Linux Mint 17.3 / 64bit / 16 GB RAM / i7)


And from the technical point of view, I'm sure some results 
must be wrong.
So I shake my head in surprise and ask the community what they 
think about techempower's benchmarks.


Regards, Ozan


It seems to be at the bottom because of "vibe.d — Did not 
complete"




Re: Neovim autocompletion using deoplete

2016-02-21 Thread maik klein via Digitalmars-d

On Saturday, 20 February 2016 at 22:04:57 UTC, landaire wrote:
I wanted to drop by with a link to something I've been working 
on for a few days: deoplete-d [1]. If anyone uses Neovim with 
deoplete [2] this plugin will add asynchronous autocompletion 
for D utilizing DCD. It's pretty basic right now but I've found 
it better than using dutyl.


Issues are expected but as long as dcd-client and dcd-server 
are in your $PATH nothing should break terribly (there are 
options to set these manually but I haven't bothered to 
actually test them).


Some notes since I'm missing docs:

- By default it'll auto-start dcd-server and kill the process 
when nvim exits
- If your buffer has a parent directory `src` or `source` then 
that directory will be added to DCD's import paths, otherwise 
the buffer's parent dir is added


Demo: https://gfycat.com/ImprobableSecondhandAmericanwarmblood

[1] https://github.com/landaire/deoplete-d
[2] https://github.com/Shougo/deoplete.nvim


Good job, but could you also explain why do you think its better 
than in dutyl? I currently also use nvim with dutyl(dcd, 
dscanner, fmt) and youcompleteme and I haven't run into any 
issues.


Is it possible to filter autocompletions based on the type? Like 
modules, struct alias, enum etc?




Re: Transposing a static array

2016-02-20 Thread maik klein via Digitalmars-d-learn

On Saturday, 20 February 2016 at 03:02:11 UTC, cym13 wrote:

On Saturday, 20 February 2016 at 02:26:56 UTC, maik klein wrote:
On Saturday, 20 February 2016 at 02:22:12 UTC, Ali Çehreli 
wrote:

[...]


Your "Method B" is how I did it too but how do I convert it 
back to a static array of float[2][3]?


I don't see the point of using transposed which gives a range 
out if you want to put it back into a float[2][3] right away, 
just do a double foreach:


void main(string[] args) {
float[3][2] src = [[1, 2, 3], [2, 3, 4]];

float[2][3] dst;

foreach (i ; 0..src.length)
foreach (j ; 0..src[0].length)
dst[j][i] = src[i][j];

assert(dst == [[1, 2], [2, 3], [3, 4]]);
}


You are right. I restricted myself from using indices because I 
wanted to learn ranges but I think that working with matrices is 
actually much simpler by just using good old for loops.


Re: Transposing a static array

2016-02-19 Thread maik klein via Digitalmars-d-learn

On Saturday, 20 February 2016 at 02:22:12 UTC, Ali Çehreli wrote:

On 02/19/2016 06:00 PM, maik klein wrote:

How would I transpose

float[3][2]

to

float[2][3]

with http://dlang.org/phobos/std_range.html#.transposed




Because static arrays are not ranges, they must be used as 
slices with the help of []. The following code does the same 
thing in two different ways:


import std.stdio;
import std.range;
import std.algorithm;

void main() {
float[3][2] arr = [ [1, 2, 3],
[4, 5, 6] ];

// Method A
{
float[][] arr2;

foreach (ref a; arr) {
arr2 ~= a[];
}

writeln(arr2.transposed);
}

// Method B
{
auto r = arr[].map!((ref a) => a[]).array.transposed;
writeln(r);
}
}

Ali


Your "Method B" is how I did it too but how do I convert it back 
to a static array of float[2][3]?


Transposing a static array

2016-02-19 Thread maik klein via Digitalmars-d-learn

How would I transpose

float[3][2]

to

float[2][3]

with http://dlang.org/phobos/std_range.html#.transposed




Re: Confusion regarding struct lifecycle

2016-02-15 Thread maik klein via Digitalmars-d-learn

On Tuesday, 16 February 2016 at 02:09:15 UTC, Matt Elkins wrote:
I've been bitten again by my lack of understanding of the D 
struct lifecycle :-/. I managed to reduce my buggy program to 
the following example:


[...]


In D you can always call Foo.init even with @disable this(), The 
first 3 destructor calls are from the 3 Foo.inits in your static 
array. I guess because you disabled the copy constructor, the 
Foo's will be moved and then they also need to call the 
destructor of the Foo.inits. Just like std::move does.


Re: @nogc for structs, blocks or modules?

2016-02-15 Thread maik klein via Digitalmars-d

On Tuesday, 16 February 2016 at 02:47:38 UTC, WebFreak001 wrote:

On Tuesday, 16 February 2016 at 02:42:06 UTC, maik klein wrote:

I just seems very annoying to add @nogc to every function.


you can mark everything as nogc with

// gc functions here

@nogc:

// nogc functions here
void foo() {}


Thanks, this should probably added to 
https://dlang.org/spec/attribute.html#nogc


I just realized that I can't even use @nogc because pretty much 
nothing in phobos uses @nogc


@nogc for structs, blocks or modules?

2016-02-15 Thread maik klein via Digitalmars-d
I am probably the minority but I almost never use the GC in D. 
Because I never use the GC I could mark 99% of my functions with 
@nogc.


I just seems very annoying to add @nogc to every function.

For people like me it seems that it could be a nice addition to 
also allow @nogc for structs like


@nocgc struct Foo{..}

or blocks

@nogc{
   void foo(){}
   void foo1(){}
}

or even modules

@nogc module Foo

What do you think?






[Discussion] Usefulness of Algebraic?

2016-02-13 Thread maik klein via Digitalmars-d

struct Some(T){
T value;
}
struct None{}

struct Option(T){
alias OptionAdt(T) = Algebraic!(Some!T, None);
OptionAdt!T value; //Should default to none
//OptionAdt!T value = OptionAdt!T(None());
/*
  Error: memcpy cannot be interpreted at compile time, 
because it has no

  available source code
*/
}

It is a bit unfortunate that the default value of Option!T.init 
is neither Some!T nor None.


Also Algebraic probably has to be wrapped in a struct because D 
can not infer the type of T for the following code.


alias Option(T) = Algebraic!(Some!T, None);

bool test(T)(auto ref Option!T o){
return true;
}

I really love ADT's but I think that they can not be used as a 
default value limits their usefulness.


/discuss





Re: D's equivalent to C++'s std::move?

2016-02-03 Thread maik klein via Digitalmars-d
On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu 
wrote:

On 02/03/2016 07:48 PM, Matt Elkins wrote:

This [apparent] lack of clean move semantics


I very much wish there was a quick summary. I figure you've 
seen std.algorithm.move. What's missing? -- Andrei


I am in a similar boat as Matt Elkins. The problem is not D's 
move semantics, but that Phobos does not support them at all.


I have already several things that are not copyable, one of them 
is "Unique". It feels incredibly restrictive to use those in D. 
You can not put them in Arrays, you can not put them in Tuples, 
you can not use writeln on them, you can basically not use them 
at all in Phobos because pretty much everything relies on copying.


I have currently written tons of stuff from scratch just to 
support a few non copyable types. This is probably my biggest 
complain about D so far.


It might still be the case that I am missing something obvious 
here.


Re: D's equivalent to C++'s std::move?

2016-02-03 Thread maik klein via Digitalmars-d

On Thursday, 4 February 2016 at 03:52:23 UTC, rsw0x wrote:

On Thursday, 4 February 2016 at 03:45:57 UTC, maik klein wrote:
On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei 
Alexandrescu wrote:

[...]


I am in a similar boat as Matt Elkins. The problem is not D's 
move semantics, but that Phobos does not support them at all.


I have already several things that are not copyable, one of 
them is "Unique". It feels incredibly restrictive to use those 
in D. You can not put them in Arrays, you can not put them in 
Tuples, you can not use writeln on them, you can basically not 
use them at all in Phobos because pretty much everything 
relies on copying.


I have currently written tons of stuff from scratch just to 
support a few non copyable types. This is probably my biggest 
complain about D so far.


It might still be the case that I am missing something obvious 
here.


Those are intended not to be copied, they must be explicitly 
moved with std.algorithm's move


I don't understand what you are saying. Are you saying that I can 
use them with Arrays, Tuples etc and I just have to use move 
somehow? If that is the case please show me because I have 
already wasted a lot of time into recreating Array, Tuple etc.


Or are you saying that I they are not compatible with Phobos?


Re: D's equivalent to C++'s std::move?

2016-02-02 Thread maik klein via Digitalmars-d
On Monday, 1 February 2016 at 13:52:49 UTC, Ola Fosheim Grøstad 
wrote:
On Monday, 1 February 2016 at 13:21:02 UTC, Shachar Shemesh 
wrote:

q = std::move(p);

I am unsure what is the correct way to do this under D.


Note that C++ std::move(...) doesn't do anything related to 
state, it is only a type cast, so it is zero-overhead.


What I have done to get semantics close to C++ is to define 
"moving" type and a "pointer" type that use it.


(I dislike how D deals with this.)


Could you share this? I would be very interested in how you have 
approached it.





Containers with non copyable types

2016-02-01 Thread maik klein via Digitalmars-d-learn

For example it is no problem in C++ to have

std::vector vuf;

But how can this be expressed in D?

For example

Array!(Unique!int) ua;

doesn't compile because it requires this(this) which is obviously 
disabled for "Unique".





Re: Ownership semantics

2016-01-31 Thread maik klein via Digitalmars-d-learn
On Sunday, 31 January 2016 at 20:20:52 UTC, Steven Schveighoffer 
wrote:

On 1/31/16 3:15 PM, Matt Elkins wrote:

On Sunday, 31 January 2016 at 20:11:07 UTC, Matt Elkins wrote:

On Sunday, 31 January 2016 at 20:10:03 UTC, Matt Elkins wrote:
On Sunday, 31 January 2016 at 20:07:26 UTC, Steven 
Schveighoffer wrote:
What is likely happening is that ptr is already collected, 
and you

are invalidly attempting to re-free it.


The GC can collect this memory even though there is still an
outstanding root-reachable pointer to it?


Or maybe it isn't root-reachable?


No, it is still present even if root-reachable:

[code]
unittest
{
 import std.algorithm;

 int* x;
 {
 auto map = new UniquePtr!int[1];
 auto uniqueX = UniquePtr!int(5);
 x = uniqueX.get();
 map[0] = move(uniqueX);
 }
}
[/code]

[output]
core.exception.InvalidMemoryOperationError@src\core\exception.d(679):
Invalid memory operation

Program exited with code 1
Made 632560 for this 18FD90
Disposing null for this 18FD70
Disposed null for this 18FD70
Disposing null for this 18FD90
Disposed null for this 18FD90
All unit tests have been run successfully.
Disposing 632560 for this 632550
[/output]


Oh, nevermind. This is actually simpler.

You can't do memory operations inside a destructor during 
collection. I forgot about that.


But the rule I stated is still in force.

-Steve
Honestly I don't quite understand why it would refree the ptr, 
but switching to malloc does seem to solve the problem.


struct UniquePtr(T) {
import std.experimental.allocator;
private T* ptr = null;
IAllocator alloc;
@disable this(this); // This disables both copy construction 
and opAssign


this(Args...)(auto ref Args args){
import std.experimental.allocator.mallocator;
alloc = allocatorObject(Mallocator.instance);
ptr = alloc.make!T(args);
}

~this() {
alloc.dispose(ptr);
}

inout(T)* get() inout {
return ptr;
}

// Move operations
this(UniquePtr!T that) {
this.ptr = that.ptr;
that.ptr = null;
}

ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no 
"ref" on "that"

import std.algorithm.mutation;
swap(this.ptr, that.ptr); // We change it anyways, 
because it's a temporary

return this;
}
}



Re: Declaring rvalue function arguments

2016-01-31 Thread maik klein via Digitalmars-d-learn

On Sunday, 31 January 2016 at 17:42:19 UTC, anonymous wrote:

On 31.01.2016 18:21, Matt Elkins wrote:
I know I can mark an argument ref to require lvalues, so I'm 
wondering
whether there is an equivalent for rvalues; that is, is there 
a way to

specify that an argument to a function MUST be an rvalue?

For example, in C++ I can do this:
[code]
void foo(int && x) {...}

foo(5); // Works fine
int y = 5;
foo(y); // Compile error; y is not an rvalue
[/code]

This functionality turns out to be really useful when dealing 
with

transferring ownership of resources.


I don't know if this works in all cases, but it passes that 
simple test:



@disable void foo(ref int x);
void foo(int x) {}

void main()
{
foo(5); /* works */
int y = 5;
foo(y); /* error */
}



The problem is that x will be copied afaik which is not what you 
want if you want to deal with ownership.


Re: Declaring rvalue function arguments

2016-01-31 Thread maik klein via Digitalmars-d-learn

On Sunday, 31 January 2016 at 17:21:54 UTC, Matt Elkins wrote:
I know I can mark an argument ref to require lvalues, so I'm 
wondering whether there is an equivalent for rvalues; that is, 
is there a way to specify that an argument to a function MUST 
be an rvalue?


For example, in C++ I can do this:
[code]
void foo(int && x) {...}

foo(5); // Works fine
int y = 5;
foo(y); // Compile error; y is not an rvalue
[/code]

This functionality turns out to be really useful when dealing 
with transferring ownership of resources.


I am also very interested in this. I just asked this question 
today on SO 
https://stackoverflow.com/questions/35115702/how-do-i-express-ownership-semantics-in-d





Re: Declaring rvalue function arguments

2016-01-31 Thread maik klein via Digitalmars-d-learn

On Sunday, 31 January 2016 at 17:55:53 UTC, Matt Elkins wrote:
Errr, ignore the makeFoo() line. Left that in by accident, has 
no bearing on the issue.


I have found an interesting SO answer 
http://stackoverflow.com/a/35114945/944430


This would explain everything that we would need. I am just not 
100% sure if everything he says is actually true.


Ownership semantics

2016-01-31 Thread maik klein via Digitalmars-d-learn
I recently asked a question about ownership semantics in D 
https://stackoverflow.com/questions/35115702/how-do-i-express-ownership-semantics-in-d


But a few minutes ago I found an answer on SO that could 
potentially explain a lot.


http://stackoverflow.com/a/35114945/944430

Sadly it has some pseudo code in it so I implemented it with 
std.experimental.allocator


struct UniquePtr(T) {
import std.experimental.allocator;
private T* ptr = null;

@disable this(this); // This disables both copy construction 
and opAssign


this(Args...)(auto ref Args args){
ptr = theAllocator.make!T(args);
}

~this() {
theAllocator.dispose(ptr);
}

inout(T)* get() inout {
return ptr;
}

// Move operations
this(UniquePtr!T that) {
this.ptr = that.ptr;
that.ptr = null;
}

ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no 
"ref" on "that"

import std.algorithm.mutation;
swap(this.ptr, that.ptr); // We change it anyways, 
because it's a temporary

return this;
}
}

Is this code correct? One problem that I have is

UniquePtr!int[int] map;

will result in a memory exception and I have no idea why.


Re: Vision for the first semester of 2016

2016-01-25 Thread maik klein via Digitalmars-d-announce

On Monday, 25 January 2016 at 13:08:18 UTC, Rory McGuire wrote:
On Mon, Jan 25, 2016 at 2:46 PM, Andrei Alexandrescu via 
Digitalmars-d-announce  
wrote:


On 01/25/2016 04:17 AM, Rory McGuire via 
Digitalmars-d-announce wrote:




Looking at the way we have things now, it would actually be 
quite simple to make two downloads, one with everything and 
one with the bare minimum.


If we changed phobos to compile like the recent vibe.d 
version does then we can even pick and choose sections of 
phobos. I suppose "he who has the vision" can do either type 
of release with our current tools.




What would be the benefits of this? My knee-jerk reaction is 
this is a large and disruptive project with no palpable 
benefits. -- Andrei



Yep, thats kind of what I was saying in the end. If someone 
wanted to they could make such a release independently.


I'm trying to hack on the compiler, personally I wish all those 
with the know how would put their efforts into documenting how 
the compiler works and what the different parts do, that way we 
could have more contributors.


+1 On lifetime management and tooling. I would like to see a lot 
of improvements for DCD also tools for refactoring would also be 
extremely useful.


As for splitting up everything into small packages, I don't think 
D is there yet. I am still new but I already found several 
libraries that I wanted to use that not follow the "official" D 
Style guide.


I would not want to include N different libraries that use N 
different coding styles. Look at Rust for example, you will find 
that pretty much every library uses the "official" style guide.


I think that is because it is mostly "enforced" by the compiler 
as a warning.


I really don't care how I write my code, but I care deeply about 
consistency.


Another point is that I couldn't find any metaprogramming library 
for D yet. Yes there is std.meta but it is extremely lacking, 
this is quite obvious if you look into the std.


For example in "zip"

return mixin (q{ElementType(%(.moveAt(ranges[%s], n)%|, 
%))}.format(iota(0, R.length)));


This could be easily expressed as a general metafunction. Also 
std.meta mostly focusses on compile time stuff but I don't think 
there is anything for a "Tuple".


Some inspiration could be found here 
https://github.com/boostorg/hana





Re: GDC Explorer Site Update

2016-01-25 Thread maik klein via Digitalmars-d-announce

On Monday, 25 January 2016 at 23:08:32 UTC, Iain Buclaw wrote:

Hi,

After a much needed rebuild of the server running various 
GDC-related hosted services 
[http://forum.dlang.org/post/zrnqcfhvyhlfjajtq...@forum.dlang.org] - I've gotten round to updating the compiler disassembler.


http://explore.dgnu.org/

Now supports 12 different architectures from ARM to SystemZ! 
(not including -m32 or any -march options)


Enjoy.
Iain.


This is awesome, I think I am going to use this to finally learn 
some assembly. But I am not quite sure though what the output is, 
is it x86 or x64?


Re: nogc Array

2016-01-25 Thread maik klein via Digitalmars-d-learn

On Tuesday, 26 January 2016 at 03:03:40 UTC, Igor wrote:
Is there a GC-less array that we can use out of the box or do I 
have to create my own?


https://dlang.org/phobos/std_container_array.html


Re: Choosing D over C++, Go, Rust, Swift

2016-01-24 Thread maik klein via Digitalmars-d
On Sunday, 24 January 2016 at 12:04:58 UTC, Dibyendu Majumdar 
wrote:
On Thursday, 14 January 2016 at 13:47:39 UTC, Dibyendu Majumdar 
wrote:
I wrote recently that I am looking at an alternative to C++ 
for a project currently being coded in C++. I am pleased to 
say based on preliminary investigations I have chosen D over 
Go, Rust, and Swift.


1. D appears to give me all the power of C++ - and in 
particular even greater power with templates.


2. D code is cleaner, more traditional (Java and C like), and 
easier to read and understand than some of the alternatives. 
Go is simpler of course and also easy to follow - but that is 
because it is a small language. I dislike the new syntax of 
Rust as it seems gratuitously different and (in my view) hard 
to read.


3. D gives me all the low level control while at the same time 
giving me the ability to write code at a higher level. C++ is 
similar but the other languages are all restrictive in some 
way or other.




Hi - just to give you an update. After trying to get some 
simple tests working for the past few days I have concluded 
that while D is the best choice for my project (after C++) - 
D's implementation and tooling is not mature enough yet for me 
to spend effort on a port. So I will defer the move to D to a 
future time - but my intention is to do other work in D related 
to my OpenSource projects around Lua.


I really want to use D as a better C / C++ so am looking 
forward to library developments that better support a style of 
programming that relies less on GC. Its not that I don't like 
GC - but I feel that the reasons for my using a language like D 
or C++ is control - else I would use Java or Swift or Go.


Regards
Dibyendu


I am in a similar boat, I don't need the GC at all and there is 
not much stuff in the std to support a programming style like in 
C++. Also I already run into a couple of bugs in the std which I 
am currently trying to fix or work around. It is quite annoying.


But it is still the best bet if you want to do any 
metaprogramming, I think I have tried all statically compiled 
languages so far and nothing really comes close to what C++ can 
do. But D even improves on C++'s metaprogramming and it compiles 
so much faster.


Actually I personally came to the conclusion that C++ is kinda 
useless for metaprogramming because the compile times will 
explode very quickly.


A small entity component system with compile time filtering that 
I have written in C++ takes around 15 seconds for a toy example. 
In D it is ~1sec and the number doesn't seem go go up at all.





Re: D's metaprogramming could be flawed

2016-01-23 Thread maik klein via Digitalmars-d

On Friday, 22 January 2016 at 14:19:30 UTC, rsw0x wrote:

On Friday, 22 January 2016 at 13:28:00 UTC, maik klein wrote:

On Friday, 22 January 2016 at 13:21:11 UTC, rsw0x wrote:

On Friday, 22 January 2016 at 12:57:54 UTC, maik klein wrote:

...


You're looking for AliasSeq in std.meta, it's a tup—er, 
finite ordered list of types :)


I am already aware of AliasSeq as I have written above. But I 
could have misused it, would you mind showing an example with 
TupleRef?


Sorry, I must have skipped that.

Is there a reason you're explicitly using tuples?
Unless I'm misunderstanding you, you're looking for something 
like...


struct Baz(V...) {
  V vals;
}

which can be used like...

void foo(int, int, int) {

}

void main(){
  auto i = Baz!(int, int, int)();
  foo(i.vals);
}

or am I way off base?

If so, is this similar to what you're looking for?
http://dpaste.dzfl.pl/cbae4c4ed7af

Sorry if I'm nowhere near what you meant.


I think that should work but it only works because you do an 
implicit conversion with get which is quite nice.


But I was also looking for a more general solution.

I think the mixin solution could be quite nice.

static template unpack(alias f){
  pragma(inline)
  auto into(alias target, Args...)(ref Args args){
import std.conv;
enum s = 
`target(`~iota(Args.length).map!(i=>text(`f(args[`,i,`])`)).join(",")~`)`;

return mixin(s);
  }
}

and use it like:

auto r = unpack!(i => i * 2).into!((a, b) => a + b)(1,2);


The only semi weird thing is that I can use this directly with my 
version of TupleRef like this:


void foo(ref int, ref int){
}

unpack!((r)=> r.get()).into!(foo)(tref.refTs.expand);


I think that is because "lambda/delegates" can not express ref 
return types?


So I think I need to do this:

ref auto get(R)(R r){
  return r.get();
}

unpack!(get).into!(foo)(tref.refTs.expand);



Re: D's metaprogramming could be flawed

2016-01-23 Thread maik klein via Digitalmars-d

On Saturday, 23 January 2016 at 12:13:16 UTC, maik klein wrote:

On Friday, 22 January 2016 at 14:19:30 UTC, rsw0x wrote:

[...]


I think that should work but it only works because you do an 
implicit conversion with get which is quite nice.


[...]


I forgot to show what `tref` was in my last comment.

int i  = 1;
int i2 = 2
auto tref = TupleRef!(int,int)(i, i2);


D's metaprogramming could be flawed

2016-01-22 Thread maik klein via Digitalmars-d
This will be a small rant that might be completely unjustified 
and it is not meant to talk ill about D.


I am new to D and I run into a road blocking issue 
https://issues.dlang.org/show_bug.cgi?id=10541


So I set myself to fixing it. Asking around the irc, it seems 
that the biggest problem was that tuples always copy and we need 
something that can hold references.


I was going to create a TupleRef but I run into some issues.

At first I created something similar to an std::reference_wrapper 
which I am also not sure was needed in the first place but here 
it is.



struct RefWrapper(T){
  T* value;

  this(ref T v){
value = 
  }
  ref T get(){
return *value;
  }
}
auto refWrapper(T)(ref T t){
  return RefWrapper!(T)(t);
}

RefWrapper is probably flawed, but let's pretend it works.


The general idea was to have a tuple of type 
Tuple!(RefWrapper(T1), RefWrapper(T2), ... , RefWrapper(TN));


It would probably work that way, but D has its own reference 
semantics with `ref`. I thought it would be nicer if you can 
reuse `ref` notation. For example:



foreach(t; something){
  t.get();
}

//vs

foreach(ref t; something){
}

That meant I needed to create a wrapper that would automatically 
unbox every RefWrapper.


struct TupleRef(Ts...){
  import std.meta;
  alias RefTs = staticMap!(RefWrapper, Ts);
  Tuple!RefTs refTs;
  this(ref Ts ts){
refTs = 
  }
}

Now we are at the problem that I constantly run into since I 
started with D.


It seems that D doesn't have a way to express C++'s fold 
expression/template expansions.



For example in C++ I could write

std::make_tuple(std::ref(ts)...);

and it would expand like

std::make_tuple(std::ref(t1), std::ref(t2), ... , std::ref(tn));

I would love to use staticMap! but it seems to only work for 
types, it could be altered slightly so that it would also work 
with normal functions but the values would still have to be read 
at compile time.



For this case I used my little helper function:

auto mapToTuple(alias f,T...)(){
  import std.typecons;
  static if(T.length == 0)  {
return tuple();
  }
  else{
return tuple(f(T[0]), mapToTuple!(f, T[1..$]).expand);
  }
}


TupleRef then became

struct TupleRef(Ts...){
  import std.meta;
  alias RefTs = staticMap!(RefWrapper, Ts);
  Tuple!RefTs refTs;
  this(Ts ts){
refTs = mapToTuple!(refWrapper, ts);
  }
}


In this case everything seems to work nicely but the problem 
still exists.


For example I need to be able to expand TupleRef like this

f(someTupleRef.expand);
f(t[0].get(), t[1].get(), ... , t[n].get());
//f takes the arguments by ref

This time I can not use a tuple because it would copy the value. 
I also can not use `AliasSeq` because it needs it values at 
compile time.




Another small problem for TupleRef is opIndex. It seems that the 
[index] notation with opIndex doesn't allow me to express the use 
of compile time values.


It seems that tuple somehow manages this with

struct Tuple{
  ...
  alias expand this;
  ...
}

But I don't think I can use the same technique here.

I thought I would write a bigger post that explains my thoughts 
instead of asking in the irc. I hope it didn't sound too harsh 
which was not my intent.


Re: D's metaprogramming could be flawed

2016-01-22 Thread maik klein via Digitalmars-d

On Friday, 22 January 2016 at 13:21:11 UTC, rsw0x wrote:

On Friday, 22 January 2016 at 12:57:54 UTC, maik klein wrote:

...


You're looking for AliasSeq in std.meta, it's a tup—er, finite 
ordered list of types :)


I am already aware of AliasSeq as I have written above. But I 
could have misused it, would you mind showing an example with 
TupleRef?


Deleting an object

2016-01-18 Thread Maik Klein via Digitalmars-d-learn
I have also asked this question here 
https://stackoverflow.com/questions/34838742/weak-references-or-pointers


But I try to word it differently.

I have a game with GameObjects, a system manages those 
GameObjects. GameObjects can hold a pointer/reference to each 
other.


But at one point a GameObject dies and when it does it shouldn't 
be able to be accessed by other GameObjects nor should it be kept 
alive in memory.


How do I express this in D?

I have also looked at core.memory.GC

  auto foo = new Foo!int();
  auto foo2 = foo;
  GC.free(foo);

  if(foo != null)
writeln(*foo);
  if(foo2 != null)
writeln(*foo2);

But it seems that `GC.free` behaves like C++'s `delete` and 
doesn't actually null all the pointers.


Re: Unable to call each on a lockstep range containing 2 or more ranges

2015-11-18 Thread maik klein via Digitalmars-d-learn

On Wednesday, 18 November 2015 at 17:22:52 UTC, Meta wrote:
On Wednesday, 18 November 2015 at 12:20:42 UTC, maik klein 
wrote:

[...]


Which version of the compiler are you using?

Linux - DMD64 D Compiler v2.069.0




Unable to call each on a lockstep range containing 2 or more ranges

2015-11-18 Thread maik klein via Digitalmars-d-learn

https://stackoverflow.com/questions/33779822/unable-to-call-each-on-a-lockstep-range-containing-2-or-more-ranges

http://dpaste.dzfl.pl/76c79f1f12ab

void main(){
  import std.container;
  import std.stdio;
  import std.algorithm.iteration;
  import std.range;
  Array!int ai = [1,2,3,4];
  Array!int ai1 = [1,2,3,4];
  Array!int ai2 = [1,2,3,4];

  auto arange = lockstep(ai[],ai1[]);
  arange.each!((a,b) => writeln(a, b));

  auto arange2 = lockstep(ai[],ai1[],ai2[]);
  arange2.each!((a,b,c) => writeln(a, b, c));
}

Error: template std.algorithm.iteration.each cannot deduce 
function from argument types !((a, b, c) => writeln(a, b, 
c))(Lockstep!(RangeT!(Array!int), RangeT!(Array!int), 
RangeT!(Array!int))), candidates are: 
/opt/compilers/dmd2/include/std/algorithm/iteration.d(820):

std.algorithm.iteration.each(alias pred = "a")


"arange" works but "arange2" doesn't because the compiler is 
unable to deduce the the function. The error even appears if I 
explicitly add the argument types.


Re: Unable to call each on a lockstep range containing 2 or more ranges

2015-11-18 Thread maik klein via Digitalmars-d-learn

On Wednesday, 18 November 2015 at 13:51:59 UTC, John Colvin wrote:
On Wednesday, 18 November 2015 at 12:20:42 UTC, maik klein 
wrote:

[...]


I think this is a bug, please report it at issues.dlang.org and 
perhaps there will be an explanation or it will be fixed.

In the mean time, something like this should work:

  auto arange2 = zip(ai[],ai1[],ai2[]);

  arange2.each!((t) => writeln(t[0], t[1], t[2]));
  // or if you really must have the names:
  arange2.each!((t) => (a,b,c){ writeln(a, b, c); }(t.expand));


Thanks, but the problem I have with zip is that it doesn't work 
with "ref".



for example

auto arange3 = zip(ai[],ai1[],ai2[]);
foreach(ref a; arange3){
  a[0] = 42;
}
Won't change anything. Is this another bug?




Filtering a tuple of containers with indices

2015-11-17 Thread maik klein via Digitalmars-d-learn

The question is also posted on

https://stackoverflow.com/questions/33757981/filtering-a-tuple-of-containers-with-indicies


template tupIndexToRange(alias Tup, Indices...){
  import std.meta;
  static if(Indicies.length == 0){
alias tupIndexToRange = AliasSeq!();
  }
  else{
alias tupIndexToRange = AliasSeq!(Tup[ Indices[0] ][], 
tupIndexToRange!(Tup,Indices[1..$]));

  }
}

void main{
  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;

  alias IntegralRange = tupIndexToRange!(integrals,0,1);
}

void main{
  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;

  alias IntegralRange = tupIndexToRange!(integrals,0,1);
}

I want to achieve something like this

auto range = zip(tupIndexToRange!(integrals,0,1));

I think the main problem is that Tup[ Indicies[0] ] doesn't work, 
to me it should have expanded to this 
AliasSeq!(itegrals[0][],integrals[1][]);



This is roughly what I want to achieve

  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;
  integrals[0].insertBack(1);
  integrals[1].insertBack(2);
  integrals[2].insertBack(3);

  auto range = zip(tuple(integrals[0][],integrals[1][]).expand);
  writeln(range);
  foreach(e;range){
writeln("element: ",e);
  }
But instead of "auto range = 
zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to 
be generic "auto range = zip(tupIndexToRange!(integrals, 
AliasSeq!(0, 1)).expand);"


Maybe I need use mixins?


Re: Filtering a tuple of containers with indices

2015-11-17 Thread maik klein via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 15:48:10 UTC, anonymous wrote:

On 17.11.2015 15:32, maik klein wrote:

[...]

[snip]

I don't quite understand how that code is supposed to work. 
Maybe there's just some detail missing, but it could also be 
that your approach can't work.


[...]


Thanks but I have one question.

.selectFromTuple!(0, 1).expand

Does this result in a copy? I avoided doing it like this because 
I was worried that I would copy every array. But I also don't 
fully understand when D will copy.



Also doing

  foreach(e;range){
e[0] = 10;
e[1] = 10.0f;
writeln("element: ",e);
  }
  foreach(e;range){
writeln("element: ",e);
  }

doesn't mutate the range at all.



Re: Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
On Monday, 16 November 2015 at 14:26:41 UTC, Jonathan M Davis 
wrote:

On Monday, 16 November 2015 at 14:09:45 UTC, maik klein wrote:

[...]


Per the style guide,

=
Eponymous Templates

[...]


Okay thanks, but I am still not sure about my example.

I am pretty sure that at least "any" should be camel case because 
it's a value, but what about "Contains"? It's neither a type nor 
a eponymous template. My guess is that it should also be camel 
case?


So it would be contains!C.any!T ?



Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
I am a very new D user and I almost always try to mirror the 
"official" style guide if one is available.


http://dlang.org/dstyle.html

I have written the following function

template Contains(C...){
  template Any(T...){
import std.meta: anySatisfy;
static if(T.length == 0){
  enum Any = false;
}
else{
  enum Any = ContainsImpl!T;
}
template ContainsImpl(T...){
  enum bool isSameComponent(Comp) = is(Comp == T[0]);
  static if(T.length == 1){
enum ContainsImpl = anySatisfy!(isSameComponent,C);
  }
  else{
enum ContainsImpl = anySatisfy!(isSameComponent,C) && 
ContainsImpl!(T[1..$]);

  }
}
  }
}


No idea how I should type it contains!c.any!T or contains!c.Any!T

Which lead me to have a look at phobos

For example

template Filter(alias pred, TList...)

vs

template anySatisfy(alias F, T...)

Are aliases now written in upper or lower camelCase? Should I use 
T... or TList... for variadics if I can't name them better?


or

private template GenericReplace(args...)

Why are the variadics written in lower case?



Re: Style guide is very inconsistent

2015-11-16 Thread maik klein via Digitalmars-d
On Monday, 16 November 2015 at 17:47:10 UTC, Jonathan M Davis 
wrote:

[...]


Thanks for going into so much detail.



Will std.allocator make it easy to bypass the GC?

2015-11-14 Thread maik klein via Digitalmars-d

http://dlang.org/phobos/std_experimental_allocator.html

I am not sure what the plan is but it seems to me that the 
standard library could make use of the "theAllocator" for 
allocation and also allow you to swap in different allocators.


So could it then be possible to completely bypass the GC once 
"allocators" are used by the std?


I imagine that we could set "theAllocator = Malloc" and every 
allocation will use malloc? Or maybe some function allocates by 
default but you know that the allocation is small enough to be 
allocated on the stack which would allow us to call the function 
like this "someFunction!(StackAlloactor)(foo);" ?


Metaprogramming in D - From a beginner's perspective

2015-11-08 Thread maik klein via Digitalmars-d
Here is the blog post 
https://maikklein.github.io/2015/08/11/Metaprogramming-D/


And the discussion on reddit: 
https://www.reddit.com/r/programming/comments/3s1qrt/metaprogramming_in_d_from_a_beginners_perspective/


Cannot use local 'i' as parameter to non-global template

2015-11-07 Thread maik klein via Digitalmars-d-learn

template IsSame(T){
  template As(alias t){
enum As = is(T : typeof(t));
  }
}
void main()
{
  int i;
  enum b = IsSame!int.As!(i);
}

Err:

Error: template instance As!(i) cannot use local 'i' as parameter 
to non-global template As(alias t) dmd failed with exit code 1

I don't understand the error message.

I also tried

template IsSame(T){
  enum As(alias t) = is(T : typeof(t));
}

Which results in

Error: template app.IsSame!int.As cannot deduce function from 
argument types !()(int), candidates are: source/app.d(50,8):

app.IsSame!int.As(alias t)

What am I doing wrong?

Ps: Also posted on SO 
https://stackoverflow.com/questions/33584130/cannot-use-local-i-as-parameter-to-non-global-template not sure where people usually ask questions about D.


Re: Is it possible to filter variadics?

2015-11-04 Thread maik klein via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 06:20:30 UTC, Jakob Ovrum wrote:

On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote:

[...]


import std.algorithm.iteration : sum;
import std.meta : allSatisfy, Filter;
import std.traits;
import std.typecons : tuple;
import std.range : only;

// These two are necessary since the ones in std.traits
// don't accept non-types
enum isIntegral(alias i) = std.traits.isIntegral!(typeof(i));
enum isFloatingPoint(alias f) = 
std.traits.isFloatingPoint!(typeof(f));


auto separateSum(T...)(T args)
if(allSatisfy!(isNumeric, T))
{
	return tuple(only(Filter!(isIntegral, args)).sum(), 
only(Filter!(isFloatingPoint, args)).sum());

}

pure nothrow @safe unittest
{
assert(separateSum(2, 2.0) == tuple(2, 2.0));
assert(separateSum(3, 2.0, 5, 1.0, 1.0) == tuple(8, 4.0));
}


Thanks, that is exactly what I wanted to achieve. What is the 
performance implication of 'only' in this context? Will it copy 
all arguments?


Is it possible to filter variadics?

2015-11-03 Thread maik klein via Digitalmars-d-learn

Is it possible to filter variadics for example if I would call

void printSumIntFloats(Ts...)(Ts ts){...}

printSumIntFloats(1,1.0f,2,2.0f);

I want to print the sum of all integers and the sum of all floats.


//Pseudo code
void printSumIntFloats(Ts...)(Ts ts){
auto sumOfInts = ts
  .filter!(isInteger)
  .reduce(a => a + b);
writeln(sumOfInts);
...
}

Is something like this possible?



Re: Does anyone want to work on bindings for Unreal Engine 4?

2015-05-03 Thread maik klein via Digitalmars-d

On Sunday, 3 May 2015 at 10:31:53 UTC, Jacob Carlborg wrote:

On 2015-05-02 15:00, maik klein wrote:


and there was a reddit post somewhere
about an automatic binding generator? I just can't seem to 
find it anymore.


There's DStep [1] but that is only for C, not for C++. Is there 
a C interface available?


[1] https://github.com/jacob-carlborg/dstep

This is what I meant https://github.com/Syniurge/Calypso/


Does anyone want to work on bindings for Unreal Engine 4?

2015-05-02 Thread maik klein via Digitalmars-d
Follow up for 
http://forum.dlang.org/thread/hdabrcwmycsacmduj...@forum.dlang.org


I am currently working on a medium sized project in Ue4 and the 
compile times are not so great anymore.


I am currently thinking about maintaining bindings for D even 
though I am not a D user.


I haven't really integrated any language anywhere yet so this is 
completely new to me. Also the build system is largely 
undocumented but there is mono-ue.github.io which could be used 
as an example.


How well can D interface with C++ at this moment? I think I have 
seen some bindings for std::vector and there was a reddit post 
somewhere about an automatic binding generator? I just can't seem 
to find it anymore.


Does anyone here wants to team up?


Re: Are there any exercises/challenges for D?

2014-08-24 Thread maik klein via Digitalmars-d-learn

On Sunday, 24 August 2014 at 21:51:39 UTC, Weaseldog wrote:

On Sunday, 24 August 2014 at 20:32:02 UTC, maik klein wrote:

Are there any exercises/challenges for D?

Something like this? 
http://www.haskell.org/haskellwiki/99_questions/1_to_10


Well, you could port 99 lisp problems to D - D can be written 
in a fairly functional style ;)


I am just trying to learn D by writing code. Of course I could 
just do them in D but I would like to compare my version with 
idiomatic D.


It's actually quite strange that no one has done something like 
this in D, it's usually the first thing people do.




Why does D rely on a GC?

2014-08-18 Thread maik klein via Digitalmars-d
First of all I don't want to insult anyone on language design, I 
just want to know the reason behind the always on GC.
I know that the GC as several advantages over reference counting, 
especially when it comes to immutable data structures.
What I don't (correct me if i am wrong) understand is why every 
heap allocation has to be garbage collected, like classes, 
dynamic arrays etc.
Does a GC still have advantages over heap allocations that do not 
need to be reference counted such as the unique_ptr in c++?

The dlang homepage stats:

Destructors are used to deallocate resources acquired by an 
object. For most classes, this resource is allocated memory. With 
garbage collection, most destructors then become empty and can be 
discarded entirely.


If I understand it correctly it means that D has a GC, so most 
classes don't need a destructor anymore because they don't need 
to do any cleanup. I am not totally convinced that this would be 
a good trade off in general. Maybe someone could shine some light 
on this statement?


  1   2   >