Re: getTid wrapper

2014-03-03 Thread Bienlein

On Tuesday, 4 March 2014 at 06:31:24 UTC, Timothee Cour wrote:


that gives tid of spawned thread, not 'self'.


The link you mentioned says it is stored in the special variable
thisTid.


Re: Reading a string in binary mode

2014-03-03 Thread Christof Schardt

"bearophile"  schrieb im Newsbeitrag 
news:qqcdemwimcylaizjy...@forum.dlang.org...
> Christof Schardt:
>
>> By "trickery" I meant having to know about things like
>> "import std.exception : assumeUnique" for this basic kind of task.
>
> Your function has signature (you use "ref" instead of "in" or "out" 
> because it performs read/write):
>
> void rw(ref string x)
>
> A string is a immutable(char)[], that is a dynamic array of immutable 
> (UTF-8) chars. In D a dynamic array is a struct (so it's a value) that 
> contains a length of the string (here in multiple of char.sizeof, that are 
> bytes) and a pointer to the actual string data. Your function gets a 
> string by reference, so it's a pointer to a mutable struct that points to 
> immutable chars.
>
> The else branch suggested by John Colvin was:
>
>> else
>> {
>> size_t size;
>> _f.rawRead((&size)[0..1]);
>> auto tmp = new char[size];
>> _f.rawRead(tmp);
>> import std.exception : assumeUnique;
>> x = tmp.assumeUnique;
>> }
>
> This allocated a GC-managed dymamic array of chars (the buffer tmp), and 
> loads the data into them:
>
> auto tmp = new char[size];
> _f.rawRead(tmp);
>
> Now you can't just perform:
>
> x = tmp;
>
> D manages the pointer to the dynamic array x automatically, so x can be 
> seen as a dynamic array array. But their type is different, x refers to 
> immutable(char)[] while tmp is a char[]. In general you can't implicitly 
> convert immutable data with indirections to mutable data with 
> indirections, because this breaks the assumptions immutability is based on 
> (while in D you can assign a char[] to a const(char)[] variable. It's the 
> difference between const an immutable). So the "trickery" comes from 
> satisfying the strong typing of D. It's the price you have to pay for 
> safety and (in theory) a bit of improvements in concurrent code.
>
> assumeUnique is essentially a better documented cast, that converts 
> mutable to immutable. It's similar to cast(immutable). D doesn't have 
> uniqueness typing so in many cases the D compiler is not able to infer the 
> uniqueness of data for you (and unique data can be implicitly converted to 
> immutable). But the situation on this is improving (this is already 
> partially implemented and merged, and will be present in D 2.066: 
> http://wiki.dlang.org/DIP29 ).
>
> when the function you are calling is pure (unlike rawRead) you don't need 
> assumeUnique:
>
> import std.exception: assumeUnique;
>
> void foo(out char[] s) pure {
> foreach (immutable i, ref c; s)
> c = cast(char)i;
> }
>
> // Using assumeUnique:
> void bar1(ref string s) {
> auto tmp = new char[10];
> foo(tmp);
> s = tmp.assumeUnique;
> }
>
> // Using the D type system:
> void bar2(ref string s) {
> static string local() pure {
> auto tmp = new char[10];
> foo(tmp);
> return tmp;
> }
> s = local;
> }
>
> void main() {}
>
> Bye,
> bearophile

Great, thanks for this insight.
Christof 




Re: How to build DMD on windows ?

2014-03-03 Thread Benjamin Thaut

Am 03.03.2014 21:49, schrieb Remo:

On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote:

Am 28.02.2014 21:14, schrieb Remo:

How to build DMD on windows ?
And then run all the test for it?
README.md is pretty empty at the moment.

Of course it is possible to wait for some Fixes in DMD compiler may be
it could be faster just to fix them by my self and then hope that the
fix will be accepted...



Easiest way (but you need visual studio):
1) checkout the latest version (or a tag) from
https://github.com/D-Programming-Language/dmd
2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build
using the release target. Benefit from a compiler which is 3 times
faster compared to a dmd build with dmc.

Kind Regards
Benjamin Thaut


Thanks,  I already found Visual Studio solution.
By the way it compiles with VS2012 but not with VS2013.


I think no one tried with 2013 yet. Whats the problem?


Re: runtime loading D shared library as a standalone (with it's own GC etc)

2014-03-03 Thread Timothee Cour
On Fri, Feb 28, 2014 at 10:27 AM, Martin Nowak  wrote:

> On 02/26/2014 10:16 PM, Timothee Cour wrote:
>
>> Currently (on OSX) I can runtime load a D dll from a C program, but not
>> from a D program, which seems silly.
>>
>> Is it possible to runtime load a D shared library as a standalone (ie
>> without sharing GC, runtime or any other data), treating it as if we
>> were loading from a C program (making no attempt at sharing druntime or
>> otherwise).
>>
>> What do I need to change in druntime to make this possible?
>>
>>  Depends on why it doesn't work.
>


Here's an example.
If it works from inside C++ there should be a way to make it work from
inside D isn't there?  (eg by isolating the GC of the shared library from
the GC of the main program, etc).

main.d:
call a D shared library via dlopen/dlsym
foo.d:
extern(C) void foo(){
  printf("inside_foo\n"); //ok
  import core.runtime;
  bool ret=Runtime.initialize();//will segfault below with or without that
  assert(ret);//ok
  int[]a;
  a.length=2;//segfault
}


dmd -g -oflibfoo.dylib -shared foo.d
dmd -g -oftest main.d
./test
#Loading shared libraries isn't yet supported on OSX.
#inside_foo
#segfault at first occurence of gc (a.length=2 above)

under lldb:

* thread #1: test D2rt12sections_osx9tlsOffsetFPvZm + 109, stop reason =
EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: test D2rt12sections_osx9tlsOffsetFPvZm + 109
frame #1:  test __tls_get_addr + 20
frame #2:  libfoo.dylib _d_arraysetlengthT + 3701
 ...


Re: Final class and interface

2014-03-03 Thread Steven Schveighoffer
On Mon, 03 Mar 2014 21:48:16 -0500, Casper Færgemand   
wrote:


Is there any loss in performance instantiating an interface variable as  
a final class implementing only that interface, as opposed to a class  
variable?


You mean the difference between:

final class C : I {...}

// this
I i = new C;

// and this
C c = new C;

???

The difference in performance is huge. As a final class, no virtual calls  
are needed. In itself, this is not a huge deal, as a virtual call is not  
too much worse than a standard call.


However, method calls on the concrete class can be inlined, and an inline  
call is generally very quick when compared to any kind of other call.


-Steve


Final class and interface

2014-03-03 Thread Casper Færgemand
Is there any loss in performance instantiating an interface 
variable as a final class implementing only that interface, as 
opposed to a class variable?


Re: Disabling the Garbage Collector

2014-03-03 Thread Adam D. Ruppe

On Monday, 3 March 2014 at 12:23:49 UTC, Jeroen Bollen wrote:
If I were to compile without linking to the garbage collector, 
what would and what wouldn't work in D?


You can get almost everything to work, though some built-in 
features will need to be replaced/supplemented by library things 
and some care will be needed to avoid memory leaks.


Specifically:

* the a ~ b operator is a bad idea without the GC. (and with the 
GC in performance critical code)


* delegate closures are a bad idea without the GC (though you can 
make them work)


* Your classes will be written pretty differently

* ~=, .dup and .length on built in arrays will need to be 
replaced by a library thing



I think the rest can be made to work off the top of my head. 
Though, I think the cases where you want to go without the GC 
entirely are pretty rare. Normally, I'd just be careful about 
where you trigger it instead.


Issus with DMD 2.065

2014-03-03 Thread Hertz
 Ever since I installed the latest DMD 2.065 I cant seem to 
compile and run .d files anymore. I'm installing dmd using the 
.deb file on Ubuntu. When it is installed and I try to compile a 
.d file the console gives me this.


 cannot find source code for runtime library file 'object.d'
   dmd might not be correctly installed.

Any suggestions?


Re: adding static return?

2014-03-03 Thread Stanislav Blinov
I don't get it. That should be a static assert, not static if. 
Why would you even add into your build order a module that will 
never be actually compiled?


If anything, static assert will prevent dead imports while such 
"static return" will silently swallow them.


How would you propose handling module constructors and 
module-scope variables in presence of such return?


Re: GC.BlkAttr.FINALIZE

2014-03-03 Thread Namespace
It sounds suspicious. Clearly, you are not accessing a1 there, 
and clearly a1 is set before being used.


Any chance to reduce it?

-Steve


I don't know. But I know that my little trick doesn't work in 
lifetime.d although it works locally. Here what I tried:



import std.stdio;

struct Foo {
int id;
}

void main() {
Foo[] fs;
fs ~= Foo(45);
fs ~= Foo(46);
fs ~= Foo(47);
fs ~= Foo(48);

auto ti = typeid(fs);
writeln("&ti = ", &ti);

void* p = fs.ptr;

void[] arr = *cast(void[]*) p;

void* tp = cast(void*)((&arr) - cast(void*) 8);

TypeInfo ti2 = *cast(TypeInfo*) tp;
writeln(ti, " versus ", ti2);
}


Since rt_finalize and the GC have the same pointer as 'fs.ptr' I 
cast it to an array struct. From the pointer of this struct I 
subtract 8 (8 because of try and error until the pointer was 
equal the real TypeInfo pointer). This I can cast to the 
TypeInfo: it works. But not in lifetime.d. Was a try, but I have 
no idea why it doesn't work (the pointers aren't equal). An idea 
or alternative?


Re: std.algorithm.find and array of needles?

2014-03-03 Thread captaindet

On 2014-03-03 16:19, John Colvin wrote:

On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote:

On 2014-03-03 14:58, John Colvin wrote:

On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:

std.algorithm.find has an overload that works with several needles:

// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic arguments serving as 
needles. unfortunately, i failed trying to make find work with the needles 
provided in an array:

int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any function template 
declaration. Candidates are:

any ideas how this can be achieved?

thanks
/det


You can use a variadic template function instead of variadic slice construction:

void foo(A, T ...)(A[] a, T ns)
{
//use find as follows. For example:
return a.find(ns);
}

assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));


thanks, john.

i was afraid that this is the hoop i might have to jump through ;)

which is fine for the simple case i asked for. in another case, i would need to 
construct a needle proper from each pre-needle that is one the variadic 
arguments. this seems impossible now.

so i probably have to make the pre-needles template parameters and enter the 
dreadful realm of std.typetuple... guess staticMap is my friend here.


cheers
/det


Luckily, you don't have to. foreach over tuples is awesome:

import std.typecons;
import std.algorithm;

auto makeProperNeedle(T)(T needle)
{
//do something to needle
return needle;
}

auto foo(A, T ...)(A[] a, T preNeedles)
{
Tuple!T needles;
foreach(i, preNeedle; preNeedles)
{
needles[i] = makeProperNeedle(preNeedle);
}
//use find as follows. For example:
return a.find(needles.expand);
}

unittest
{
assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3));
}


awesome indeed - works like a charm!

many thanks
/det  


Re: Reading a string in binary mode

2014-03-03 Thread bearophile

Christof Schardt:


By "trickery" I meant having to know about things like
"import std.exception : assumeUnique" for this basic kind of 
task.


Your function has signature (you use "ref" instead of "in" or 
"out" because it performs read/write):


void rw(ref string x)

A string is a immutable(char)[], that is a dynamic array of 
immutable (UTF-8) chars. In D a dynamic array is a struct (so 
it's a value) that contains a length of the string (here in 
multiple of char.sizeof, that are bytes) and a pointer to the 
actual string data. Your function gets a string by reference, so 
it's a pointer to a mutable struct that points to immutable chars.


The else branch suggested by John Colvin was:


else
{
size_t size;
_f.rawRead((&size)[0..1]);
auto tmp = new char[size];
_f.rawRead(tmp);
import std.exception : assumeUnique;
x = tmp.assumeUnique;
}


This allocated a GC-managed dymamic array of chars (the buffer 
tmp), and loads the data into them:


auto tmp = new char[size];
_f.rawRead(tmp);

Now you can't just perform:

x = tmp;

D manages the pointer to the dynamic array x automatically, so x 
can be seen as a dynamic array array. But their type is 
different, x refers to immutable(char)[] while tmp is a char[]. 
In general you can't implicitly convert immutable data with 
indirections to mutable data with indirections, because this 
breaks the assumptions immutability is based on (while in D you 
can assign a char[] to a const(char)[] variable. It's the 
difference between const an immutable). So the "trickery" comes 
from satisfying the strong typing of D. It's the price you have 
to pay for safety and (in theory) a bit of improvements in 
concurrent code.


assumeUnique is essentially a better documented cast, that 
converts mutable to immutable. It's similar to cast(immutable). D 
doesn't have uniqueness typing so in many cases the D compiler is 
not able to infer the uniqueness of data for you (and unique data 
can be implicitly converted to immutable). But the situation on 
this is improving (this is already partially implemented and 
merged, and will be present in D 2.066: 
http://wiki.dlang.org/DIP29 ).


when the function you are calling is pure (unlike rawRead) you 
don't need assumeUnique:


import std.exception: assumeUnique;

void foo(out char[] s) pure {
foreach (immutable i, ref c; s)
c = cast(char)i;
}

// Using assumeUnique:
void bar1(ref string s) {
auto tmp = new char[10];
foo(tmp);
s = tmp.assumeUnique;
}

// Using the D type system:
void bar2(ref string s) {
static string local() pure {
auto tmp = new char[10];
foo(tmp);
return tmp;
}
s = local;
}

void main() {}

Bye,
bearophile


adding static return?

2014-03-03 Thread Xavier Bigand

I thought it could be nice to have a static return.

My Idea is to remove unnecessary bracket encapsulation made with some 
static if statements.


It will works like this :

module xxx.opengl;

import buildSettings; // contains some global constants

static if (renderMode == directX)
  return;

...


So there will no more need to scope the module code and indent it.

Is it a good idea?


Re: Reading a string in binary mode

2014-03-03 Thread Christof Schardt
"John Colvin"  schrieb im Newsbeitrag 
news:zjsykclxreagfhqsq...@forum.dlang.org...
> On Monday, 3 March 2014 at 22:22:06 UTC, Christof Schardt wrote:
>> "John Colvin"  schrieb im Newsbeitrag
>> news:dyfkblqonigrtmkwt...@forum.dlang.org...
>>> On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote:
 I'm evaluating D and try to write a binary io class.
 I got stuck with strings:

 void rw(ref string x)
 {
 if(_isWriting)
 {
 int size = x.length;
 _f.rawWrite((&size)[0..1]);
 _f.rawWrite(x);
 }
 else
 {
 int size;
 _f.rawRead((&size)[0..1]);

 ... what now?
 }
 }

 Writing is ok, but how do I read the bytes to the
 string x after having its size?
>>>
>>>
>>> Assuming you're not expecting pre-allocation (which I infer from your 
>>> choice of "ref string" instead of "char[]"), you could do this:
>>>
 void rw(ref string x)
 {
 if(_isWriting)
 {
 size_t size = x.length;
 _f.rawWrite((&size)[0..1]);
 _f.rawWrite(x);
 }
 else
 {
 size_t size;
 _f.rawRead((&size)[0..1]);
 auto tmp = new char[size];
 _f.rawRead(tmp);
 import std.exception : assumeUnique;
 x = tmp.assumeUnique;
 }
 }
>>
>> Thanks, John, this works.
>>
>> Though it feels a bit strange, that one has to do such trickery in order 
>> to
>> perform basic things like binary io of strings.
>
> Doesn't seem like trickery to me; you just make a new array of the correct 
> size and then fill it from the file. Is that not what you expected to do?
>
> The only thing that is unusual is assumeUnique, but if you understand that 
> string is an alias to immutable(char)[] then it should be apparent why 
> it's there. You could just write "x = cast(string)tmp;" instead, it's the 
> same.

By "trickery" I meant having to know about things like
"import std.exception : assumeUnique" for this basic kind of task.

Anyway, since D has an incredible community, which answers questions
like mine within minutes, this is not really an obstacle.














Re: Nobody understands templates?

2014-03-03 Thread Frustrated

On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:

On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:

On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:

On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:



There is nothing wrong about not using templates. Almost any 
compile-time design can be moved to run-time and expressed 
in more common OOP form. And using tool you have mastery of 
is usually more beneficial in practice than following the 
hype.


Yes DB, we can soldier on happily, but it would not do any 
harm to understand templates.


The documentation examples quickly make your eyes glaze over, 
looking at the code in Phobos is doubtless instructive, but 
you can wade through a lot of that without finding what you 
want. Also I discovered an interesting fact today. the word 
'mixin' does not appear in the language reference Templates 
section of dlang.org.


It should be used in at least one example. I just discovered 
by trial and error that I could use 'mixin' in Templates (as 
opposed to Template Mixins), and when you know that it seems 
likely that you can accomplish lots of stuff you couldn't 
before.


While I'm here, has anyone discovered a way to fudge a 
constructor super(..) call in a mixin template that's 
included in a class constructor. Since the mixin template is 
evaluated in the scope of the constructor, it seems like it 
should be OK.


I'm sure I'll get there in time ;=)

Steve


You've got to learn to think a bit more abstractly. Templates 
are generalizations of things.


I think the problem is not that people don't understand 
templates in the sense that they are abstractions. The question 
is whether there are loads and loads of use cases for them.


It is irrelevant if there are loads and loads of use cases for 
them. Just because people don't use something doesn't mean it is 
useless.



Suppose I want to add two numbers using a function.

int add(int, int)?
double add(double, int)?
float add(float, int)?
char add(char, double)?
etc

which one? Do you want to have to create a function every time 
for every time?


This is a typical use case and always mentioned in tutorials. 
The question is how many of these "typical" cases one 
encounters while writing software.


Look at the STL library if you do't believe templates are 
useful...


I think another problem with templates is that it is not always 
clear what is abstracted. The type or the logic? Both? In the 
above example the logic remains the same and is reproduced by 
the compiler for each type. Sometimes the logic can be 
abstracted for which type independence is important. But I'm 
not sure if that can be called a template in the purest sense. 
E.g. an algorithm that finds the first instance of something 
might be different for each type (string, char, int) and the 
"abstract" implementation has to differentiate internally (if 
string > else if int > else if ...). But this is no longer a 
template, or is it?




Both logic and types are abtracted. Even though the template 
might use the same operator, the compiler must determine which 
concrete operator to use.


The addition between the two abstract objects also requires an 
abstract operator.


The great thing is, because the abstract logic is 
identical("adding two things") makes the template actually 
useful. If it wasn't we would have to specialize the template for 
all the different possible binary combinations and then it would 
defeat the simplification that abstract is suppose to offer.


The the logical process is used when one looks at procedural code 
and realizes that one can "simplify" it by using oop.


Templates give you the same power over oop that oop gives over 
non-oop. But just because templates[oop] are available doesn't 
mean you have to use it or it is always the best solution.


I use templates all the time. I create them to simplify some task 
then put them in a library. For me, templates allow me to 
streamline things that I couldn't otherwise do. Any time I feel 
like something is being repeated a lot I automatically think that 
a templates will help. I hate "copying and pasting" and so I tend 
to use templates a lot.


One of the main uses of templates is compile time type safety. 
This is necessary with oop because oop allows one to create types 
at compile time. Hence, the need to be able to make your oop 
"safe" is a natural step and templates help you accomplish that.


e.g., Array's of objects vs Array's of a Type. One is much safer, 
informs the about what your intentions are so it can make better 
informed decisions.


e.g., Array!Type allows the Array to determine if the Type 
supports certain things at **compile time**. Array!Object can't 
do this at compile time.


If you can't see the benefit of Array!Type vs Array!Object then 
you are beyond help. (this is not to say Array!Object is always 
useless, but it is the most generic you can get and the compiler 
can do little to help the situation)



Re: GC.BlkAttr.FINALIZE

2014-03-03 Thread Steven Schveighoffer
On Mon, 03 Mar 2014 15:34:18 -0500, Namespace   
wrote:



On Monday, 3 March 2014 at 18:36:56 UTC, Steven Schveighoffer wrote:
On Mon, 03 Mar 2014 12:03:12 -0500, Namespace   
wrote:



On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote:

It's working now, I get all my debug infos I need.
But: I have absolutly no idea how to get the correct TypeInfo in  
rt_finalize2. The ClassInfo is identified by casting the void*  
pointer to a void** and then cast this void** to ClassInfo*. But for  
other TypeInfos this weird trick doesn't work. How can I extract the  
correct TypeInfo from this void**? :P


I get the real TypeInfo (not sure if this was intended this way) and  
in my test base it works! But in druntime I get the weird error:

src\rt\lifetime.d(1256): Error: variable a1 used before set


if (gc_getAttr(p) & BlkAttr.APPENDABLE)
{
void[] a1 = *cast(void[]*) ppv;
//printf("len = %d\n", a1.length);

void* p_a1 = &a1;
void* tp = p_a1 + 12;

TypeInfo* ti = cast(TypeInfo*) tp;

import std.string : toStringz;
string s = ti.toString(); // line 1256
printf("Type = %s\n", toStringz(s));

return;
}


Any call to ti will invoke the error. Any idea why?


Not really any clue.

But if this is in druntime, it should not be importing anything from  
std.


Even without I get this weird error. Is this a bug?


It sounds suspicious. Clearly, you are not accessing a1 there, and clearly  
a1 is set before being used.


Any chance to reduce it?

-Steve


Re: Nobody understands templates?

2014-03-03 Thread Chris

On Monday, 3 March 2014 at 19:32:51 UTC, Dicebot wrote:

On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
E.g. an algorithm that finds the first instance of something 
might be different for each type (string, char, int) and the 
"abstract" implementation has to differentiate internally (if 
string > else if int > else if ...). But this is no longer a 
template, or is it?


What makes you think so? Template with specializations is still 
a template.


Maybe I'm a bit too philosophical about this. But consider the 
following (made up) case:


struct MyTemp(T) {
// ...
T add(T a, T b) {
if (a is string && b is string) {
  return a~b;  // or return a~"+"~b; or whatever
} else if (a is integer && a is integer) {
  return a+b;
}
}
}

I don't know if this can be considered a "pure" template. It is a 
template of sorts, but the type specialization in the function 
add makes it a watered-down template, imo. You could have a 
version of MyTemp that handles only strings (and dchars, wchars) 
and one that handles only numbers. But this you also have in OO 
where this is achieved by inheritance and interfaces.


I think the confusion about templates often arises from the fact 
that it is mainly about types, i.e. that the compiler fills in 
the template with the appropriate type. But it is not an 
abstraction of the logic behind a function. The logic in a+b is 
the same for


int + int; float + float; float + int ... and thus not an 
abstraction of adding one thing to another.


It is different for string + string. Of course, we can have 
separate templates, one for numbers, one for strings, one for 
arrays etc. But then it is less general. I am not against 
templates, far from it, I like them, and std.algorithm is a 
brilliant example of how useful they are. However, I wonder to 
what extent they can be useful when writing a specialized program 
as opposed to a general library. Walter mentioned that he uses 
them a lot these days. How? I want to learn.


Re: Reading a string in binary mode

2014-03-03 Thread John Colvin

On Monday, 3 March 2014 at 22:22:06 UTC, Christof Schardt wrote:
"John Colvin"  schrieb im 
Newsbeitrag

news:dyfkblqonigrtmkwt...@forum.dlang.org...
On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt 
wrote:

I'm evaluating D and try to write a binary io class.
I got stuck with strings:

void rw(ref string x)
{
if(_isWriting)
{
int size = x.length;
_f.rawWrite((&size)[0..1]);
_f.rawWrite(x);
}
else
{
int size;
_f.rawRead((&size)[0..1]);

... what now?
}
}

Writing is ok, but how do I read the bytes to the
string x after having its size?



Assuming you're not expecting pre-allocation (which I infer 
from your choice of "ref string" instead of "char[]"), you 
could do this:



void rw(ref string x)
{
if(_isWriting)
{
size_t size = x.length;
_f.rawWrite((&size)[0..1]);
_f.rawWrite(x);
}
else
{
size_t size;
_f.rawRead((&size)[0..1]);
auto tmp = new char[size];
_f.rawRead(tmp);
import std.exception : assumeUnique;
x = tmp.assumeUnique;
}
}


Thanks, John, this works.

Though it feels a bit strange, that one has to do such trickery 
in order to

perform basic things like binary io of strings.


Doesn't seem like trickery to me; you just make a new array of 
the correct size and then fill it from the file. Is that not what 
you expected to do?


The only thing that is unusual is assumeUnique, but if you 
understand that string is an alias to immutable(char)[] then it 
should be apparent why it's there. You could just write "x = 
cast(string)tmp;" instead, it's the same.


Re: Reading a string in binary mode

2014-03-03 Thread Ali Çehreli

On 03/03/2014 02:25 PM, Christof Schardt wrote:

> Thanks, Ali, this works.

Yay! :)

> book be equipped with a TOC and an index?

Yes, all of that will happen after I get back to working on the book and 
its ever increasing list of to-dos. :)


Ali



Re: Reading a string in binary mode

2014-03-03 Thread Christof Schardt
"Ali Çehreli"  schrieb im Newsbeitrag 
news:lf2ude$1njf$1...@digitalmars.com...
> On 03/03/2014 01:44 PM, Christof Schardt wrote:> I'm evaluating D and try 
> to write a binary io class.
> > I got stuck with strings:
> >
> >  void rw(ref string x)
> >  {
> >  if(_isWriting)
> >  {
> >  int size = x.length;
> >  _f.rawWrite((&size)[0..1]);
> >  _f.rawWrite(x);
> >  }
> >  else
> >  {
> >  int size;
> >  _f.rawRead((&size)[0..1]);
> >
> >  ... what now?
>
> You need to have a buffer of 'size'. Not tested:
>
> auto s = new char[size];
> s = _f.rawRead(s);
> x = s;
>
> However, the last line will not compile due to difference in mutability. 
> So will need to do something like this:
>
> import std.exception : assumeUnique;
>
> x = assumeUnique(s);
>
> >  }
> >  }
> >
> > Writing is ok, but how do I read the bytes to the
> > string x after having its size?
>
> Ali

Thanks, Ali, this works.

BTW: will your excellent book be equipped with a TOC and an index?

I find it hard to look for answers to questions like above in all
the D docs I have (dpl.org, TDPL, your book)









Re: Reading a string in binary mode

2014-03-03 Thread Christof Schardt
"John Colvin"  schrieb im Newsbeitrag 
news:dyfkblqonigrtmkwt...@forum.dlang.org...
> On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote:
>> I'm evaluating D and try to write a binary io class.
>> I got stuck with strings:
>>
>> void rw(ref string x)
>> {
>> if(_isWriting)
>> {
>> int size = x.length;
>> _f.rawWrite((&size)[0..1]);
>> _f.rawWrite(x);
>> }
>> else
>> {
>> int size;
>> _f.rawRead((&size)[0..1]);
>>
>> ... what now?
>> }
>> }
>>
>> Writing is ok, but how do I read the bytes to the
>> string x after having its size?
>
>
> Assuming you're not expecting pre-allocation (which I infer from your 
> choice of "ref string" instead of "char[]"), you could do this:
>
>> void rw(ref string x)
>> {
>> if(_isWriting)
>> {
>> size_t size = x.length;
>> _f.rawWrite((&size)[0..1]);
>> _f.rawWrite(x);
>> }
>> else
>> {
>> size_t size;
>> _f.rawRead((&size)[0..1]);
>> auto tmp = new char[size];
>> _f.rawRead(tmp);
>> import std.exception : assumeUnique;
>> x = tmp.assumeUnique;
>> }
>> }

Thanks, John, this works.

Though it feels a bit strange, that one has to do such trickery in order to
perform basic things like binary io of strings.





Re: std.algorithm.find and array of needles?

2014-03-03 Thread John Colvin

On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote:

On 2014-03-03 14:58, John Colvin wrote:

On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
std.algorithm.find has an overload that works with several 
needles:


// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic 
arguments serving as needles. unfortunately, i failed trying 
to make find work with the needles provided in an array:


int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any 
function template declaration. Candidates are:


any ideas how this can be achieved?

thanks
/det


You can use a variadic template function instead of variadic 
slice construction:


void foo(A, T ...)(A[] a, T ns)
{
//use find as follows. For example:
return a.find(ns);
}

assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));


thanks, john.

i was afraid that this is the hoop i might have to jump through 
;)


which is fine for the simple case i asked for. in another case, 
i would need to construct a needle proper from each pre-needle 
that is one the variadic arguments. this seems impossible now.


so i probably have to make the pre-needles template parameters 
and enter the dreadful realm of std.typetuple... guess 
staticMap is my friend here.



cheers
/det


Luckily, you don't have to. foreach over tuples is awesome:

import std.typecons;
import std.algorithm;

auto makeProperNeedle(T)(T needle)
{
//do something to needle
return needle;  
}

auto foo(A, T ...)(A[] a, T preNeedles)
{
Tuple!T needles;
foreach(i, preNeedle; preNeedles)
{
needles[i] = makeProperNeedle(preNeedle);
}
//use find as follows. For example:
return a.find(needles.expand);
}

unittest
{
assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3));
}


Re: Reading a string in binary mode

2014-03-03 Thread Ali Çehreli
On 03/03/2014 01:44 PM, Christof Schardt wrote:> I'm evaluating D and 
try to write a binary io class.

> I got stuck with strings:
>
>  void rw(ref string x)
>  {
>  if(_isWriting)
>  {
>  int size = x.length;
>  _f.rawWrite((&size)[0..1]);
>  _f.rawWrite(x);
>  }
>  else
>  {
>  int size;
>  _f.rawRead((&size)[0..1]);
>
>  ... what now?

You need to have a buffer of 'size'. Not tested:

auto s = new char[size];
s = _f.rawRead(s);
x = s;

However, the last line will not compile due to difference in mutability. 
So will need to do something like this:


import std.exception : assumeUnique;

x = assumeUnique(s);

>  }
>  }
>
> Writing is ok, but how do I read the bytes to the
> string x after having its size?

Ali



Re: Reading a string in binary mode

2014-03-03 Thread John Colvin

On Monday, 3 March 2014 at 21:44:16 UTC, Christof Schardt wrote:

I'm evaluating D and try to write a binary io class.
I got stuck with strings:

void rw(ref string x)
{
if(_isWriting)
{
int size = x.length;
_f.rawWrite((&size)[0..1]);
_f.rawWrite(x);
}
else
{
int size;
_f.rawRead((&size)[0..1]);

... what now?
}
}

Writing is ok, but how do I read the bytes to the
string x after having its size?



Assuming you're not expecting pre-allocation (which I infer from 
your choice of "ref string" instead of "char[]"), you could do 
this:



void rw(ref string x)
{
if(_isWriting)
{
size_t size = x.length;
_f.rawWrite((&size)[0..1]);
_f.rawWrite(x);
}
else
{
size_t size;
_f.rawRead((&size)[0..1]);
auto tmp = new char[size];
_f.rawRead(tmp);
import std.exception : assumeUnique;
x = tmp.assumeUnique;
}
}


Re: std.algorithm.find and array of needles?

2014-03-03 Thread captaindet

On 2014-03-03 14:58, John Colvin wrote:

On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:

std.algorithm.find has an overload that works with several needles:

// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic arguments serving as 
needles. unfortunately, i failed trying to make find work with the needles 
provided in an array:

int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any function template 
declaration. Candidates are:

any ideas how this can be achieved?

thanks
/det


You can use a variadic template function instead of variadic slice construction:

void foo(A, T ...)(A[] a, T ns)
{
//use find as follows. For example:
return a.find(ns);
}

assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));


thanks, john.

i was afraid that this is the hoop i might have to jump through ;)

which is fine for the simple case i asked for. in another case, i would need to 
construct a needle proper from each pre-needle that is one the variadic 
arguments. this seems impossible now.

so i probably have to make the pre-needles template parameters and enter the 
dreadful realm of std.typetuple... guess staticMap is my friend here.


cheers
/det


Reading a string in binary mode

2014-03-03 Thread Christof Schardt
I'm evaluating D and try to write a binary io class.
I got stuck with strings:

void rw(ref string x)
{
if(_isWriting)
{
int size = x.length;
_f.rawWrite((&size)[0..1]);
_f.rawWrite(x);
}
else
{
int size;
_f.rawRead((&size)[0..1]);

... what now?
}
}

Writing is ok, but how do I read the bytes to the
string x after having its size?





Re: std.algorithm.find and array of needles?

2014-03-03 Thread John Colvin

On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
std.algorithm.find has an overload that works with several 
needles:


// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic 
arguments serving as needles. unfortunately, i failed trying to 
make find work with the needles provided in an array:


int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [  [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any 
function template declaration. Candidates are:


any ideas how this can be achieved?

thanks
/det


You can use a variadic template function instead of variadic 
slice construction:


void foo(A, T ...)(A[] a, T ns)
{
//use find as follows. For example:
return a.find(ns);
}

assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));


Re: How to build DMD on windows ?

2014-03-03 Thread Remo

On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote:

Am 28.02.2014 21:14, schrieb Remo:

How to build DMD on windows ?
And then run all the test for it?
README.md is pretty empty at the moment.

Of course it is possible to wait for some Fixes in DMD 
compiler may be
it could be faster just to fix them by my self and then hope 
that the

fix will be accepted...



Easiest way (but you need visual studio):
1) checkout the latest version (or a tag) from 
https://github.com/D-Programming-Language/dmd
2) Open the Visual Studio solution src/dmd_msc_vs10.sln and 
build using the release target. Benefit from a compiler which 
is 3 times faster compared to a dmd build with dmc.


Kind Regards
Benjamin Thaut


Thanks,  I already found Visual Studio solution.
By the way it compiles with VS2012 but not with VS2013.


Re: How to build DMD on windows ?

2014-03-03 Thread Namespace

On Monday, 3 March 2014 at 19:51:45 UTC, Benjamin Thaut wrote:

Am 28.02.2014 21:14, schrieb Remo:

How to build DMD on windows ?
And then run all the test for it?
README.md is pretty empty at the moment.

Of course it is possible to wait for some Fixes in DMD 
compiler may be
it could be faster just to fix them by my self and then hope 
that the

fix will be accepted...



Easiest way (but you need visual studio):
1) checkout the latest version (or a tag) from 
https://github.com/D-Programming-Language/dmd
2) Open the Visual Studio solution src/dmd_msc_vs10.sln and 
build using the release target. Benefit from a compiler which 
is 3 times faster compared to a dmd build with dmc.


Kind Regards
Benjamin Thaut


Thanks, good to know! :)


Re: GC.BlkAttr.FINALIZE

2014-03-03 Thread Namespace
On Monday, 3 March 2014 at 18:36:56 UTC, Steven Schveighoffer 
wrote:
On Mon, 03 Mar 2014 12:03:12 -0500, Namespace 
 wrote:



On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote:

It's working now, I get all my debug infos I need.
But: I have absolutly no idea how to get the correct TypeInfo 
in rt_finalize2. The ClassInfo is identified by casting the 
void* pointer to a void** and then cast this void** to 
ClassInfo*. But for other TypeInfos this weird trick doesn't 
work. How can I extract the correct TypeInfo from this 
void**? :P


I get the real TypeInfo (not sure if this was intended this 
way) and in my test base it works! But in druntime I get the 
weird error:

src\rt\lifetime.d(1256): Error: variable a1 used before set


if (gc_getAttr(p) & BlkAttr.APPENDABLE)
{
void[] a1 = *cast(void[]*) ppv;
//printf("len = %d\n", a1.length);

void* p_a1 = &a1;
void* tp = p_a1 + 12;

TypeInfo* ti = cast(TypeInfo*) tp;

import std.string : toStringz;
string s = ti.toString(); // line 1256
printf("Type = %s\n", toStringz(s));

return;
}


Any call to ti will invoke the error. Any idea why?


Not really any clue.

But if this is in druntime, it should not be importing anything 
from std.


-Steve


Even without I get this weird error. Is this a bug?


Re: How to build DMD on windows ?

2014-03-03 Thread Benjamin Thaut

Am 28.02.2014 21:14, schrieb Remo:

How to build DMD on windows ?
And then run all the test for it?
README.md is pretty empty at the moment.

Of course it is possible to wait for some Fixes in DMD compiler may be
it could be faster just to fix them by my self and then hope that the
fix will be accepted...



Easiest way (but you need visual studio):
1) checkout the latest version (or a tag) from 
https://github.com/D-Programming-Language/dmd
2) Open the Visual Studio solution src/dmd_msc_vs10.sln and build using 
the release target. Benefit from a compiler which is 3 times faster 
compared to a dmd build with dmc.


Kind Regards
Benjamin Thaut


std.algorithm.find and array of needles?

2014-03-03 Thread captaindet

std.algorithm.find has an overload that works with several needles:

// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic arguments serving as 
needles. unfortunately, i failed trying to make find work with the needles 
provided in an array:

int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [  [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any function template 
declaration. Candidates are:

any ideas how this can be achieved?

thanks
/det


Re: Nobody understands templates?

2014-03-03 Thread Dicebot

On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
E.g. an algorithm that finds the first instance of something 
might be different for each type (string, char, int) and the 
"abstract" implementation has to differentiate internally (if 
string > else if int > else if ...). But this is no longer a 
template, or is it?


What makes you think so? Template with specializations is still a 
template.


Re: Nobody understands templates?

2014-03-03 Thread Chris
On Monday, 3 March 2014 at 17:24:08 UTC, Dominikus Dittes Scherkl 
wrote:

On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote:
I'm always willing to use templates, but maybe in fact the use 
cases are limited. I have a class for html elements (that 
implements DOM functionality), and a class for building trees 
with the tags. Of course, for html tags only string as a type 
makes sense.

Really?
Did you consider that there are three different flavors of 
"string"?

Does your function really only deal with string?
Or would someone need wstring or dstring?


Good point. Of course! I was thinking in an abstract way of 
"string".



class HTMLElement(T) if (is (T == string))

}

[...] I don't know [...] if I won't have to modify the 
template to adapt to new data types (which kinda defeats the 
purpose).

Not much if the different types have common features.
Most times it is still a big save of code to implement, even
if the types need to be handled different in some places.


But it's no longer a template then, is it?


Re: Nobody understands templates?

2014-03-03 Thread Chris

On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:

On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:

On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:



There is nothing wrong about not using templates. Almost any 
compile-time design can be moved to run-time and expressed in 
more common OOP form. And using tool you have mastery of is 
usually more beneficial in practice than following the hype.


Yes DB, we can soldier on happily, but it would not do any 
harm to understand templates.


The documentation examples quickly make your eyes glaze over, 
looking at the code in Phobos is doubtless instructive, but 
you can wade through a lot of that without finding what you 
want. Also I discovered an interesting fact today. the word 
'mixin' does not appear in the language reference Templates 
section of dlang.org.


It should be used in at least one example. I just discovered 
by trial and error that I could use 'mixin' in Templates (as 
opposed to Template Mixins), and when you know that it seems 
likely that you can accomplish lots of stuff you couldn't 
before.


While I'm here, has anyone discovered a way to fudge a 
constructor super(..) call in a mixin template that's included 
in a class constructor. Since the mixin template is evaluated 
in the scope of the constructor, it seems like it should be OK.


I'm sure I'll get there in time ;=)

Steve


You've got to learn to think a bit more abstractly. Templates 
are generalizations of things.


I think the problem is not that people don't understand templates 
in the sense that they are abstractions. The question is whether 
there are loads and loads of use cases for them.



Suppose I want to add two numbers using a function.

int add(int, int)?
double add(double, int)?
float add(float, int)?
char add(char, double)?
etc

which one? Do you want to have to create a function every time 
for every time?


This is a typical use case and always mentioned in tutorials. The 
question is how many of these "typical" cases one encounters 
while writing software.


I think another problem with templates is that it is not always 
clear what is abstracted. The type or the logic? Both? In the 
above example the logic remains the same and is reproduced by the 
compiler for each type. Sometimes the logic can be abstracted for 
which type independence is important. But I'm not sure if that 
can be called a template in the purest sense. E.g. an algorithm 
that finds the first instance of something might be different for 
each type (string, char, int) and the "abstract" implementation 
has to differentiate internally (if string > else if int > else 
if ...). But this is no longer a template, or is it?


[snip]


Re: GC.BlkAttr.FINALIZE

2014-03-03 Thread Steven Schveighoffer
On Mon, 03 Mar 2014 12:03:12 -0500, Namespace   
wrote:



On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote:

It's working now, I get all my debug infos I need.
But: I have absolutly no idea how to get the correct TypeInfo in  
rt_finalize2. The ClassInfo is identified by casting the void* pointer  
to a void** and then cast this void** to ClassInfo*. But for other  
TypeInfos this weird trick doesn't work. How can I extract the correct  
TypeInfo from this void**? :P


I get the real TypeInfo (not sure if this was intended this way) and in  
my test base it works! But in druntime I get the weird error:

src\rt\lifetime.d(1256): Error: variable a1 used before set


 if (gc_getAttr(p) & BlkAttr.APPENDABLE)
 {
 void[] a1 = *cast(void[]*) ppv;
 //printf("len = %d\n", a1.length);

 void* p_a1 = &a1;
 void* tp = p_a1 + 12;

 TypeInfo* ti = cast(TypeInfo*) tp;

 import std.string : toStringz;
 string s = ti.toString(); // line 1256
 printf("Type = %s\n", toStringz(s));

 return;
 }


Any call to ti will invoke the error. Any idea why?


Not really any clue.

But if this is in druntime, it should not be importing anything from std.

-Steve


Re: Nobody understands templates?

2014-03-03 Thread Tobias Pankrath

On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:


If you don't attempt to use templates, even in example code, 
you won't get it.


What I don't get in this discussion is that all those fine phobos 
examples are neglected. Yes, it is library code, but 
writef/formattedWrite/std.conv.to, std.container, std.range, 
std.algorithm are only possible with meta-programming and are 
fine examples of the usefulness of templates.


This thread looks like this to me: I bought a new hammer, but not 
everything is a nail. Give me back my money!


Re: Mutexes and locking

2014-03-03 Thread yazd

On Monday, 3 March 2014 at 08:18:04 UTC, alexhairyman wrote:

On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:

On 03/02/2014 10:38 PM, alexhairyman wrote:

> I think I'm missing something big, but I'm having troubles
with mutexes
> (using in a parallel foreach loop somewhere else); Why do the
trylocks
> return true shouldn't they return false because the mutex is
already
> locked?

The documentation says that Mutex is a recursive lock, meaning 
that the holder of the lock can lock it even further. :) There 
is an internal reference count so that the lock must be 
unlocked the equal number of times that it has been locked.


Oh okay, that makes sense.



> I don't think this is a phobos bug, I'm on OSX using dmd 
> 2.065

>
> import core.sync.mutex;
> import std.stdio;
>
> void main()
> {
>   Mutex m = new Mutex;
>   m.lock();
>   writefln("%s", m.tryLock());
>   writefln("%s", m.tryLock());

The lock count is now 3. You must unlock it 3 times so that 
another thread can lock it.


>   return;
> }
>
> produces:
> true
> true
>
> Thanks!
>   Alex

Ali


Okay, so when doing something like this

Mutex hashlock;
void tdigest(string path)
{
  MD5Digest thasher = new MD5Digest;
  thasher.put(read(path)); //read the path in to the MD5 API
  hashlock.lock();
  hashkey[path] = thasher.finish();
  hashlock.unlock();
}
void main()
{
  hashlock = new Mutex();
... other stuff
  foreach(string s ; tp.parallel(array of strings))
  {
tdigest(s);
  }
... even more stuff
}

it will fail because the parallel foreach uses the main thread 
is being used which does some funky stuff? I'm trying to figure 
out how to implement this (for reference I'm just trying to 
create a big hash map of files and their md5's)


You have to remember that global scope variables are thread-local 
by default. So your hashlock mutex is actually only initialized 
in the main thread. Try adding __gshared before declaring 
hashlock and see if it works.


Re: Nobody understands templates?

2014-03-03 Thread Frustrated

On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:

On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:



There is nothing wrong about not using templates. Almost any 
compile-time design can be moved to run-time and expressed in 
more common OOP form. And using tool you have mastery of is 
usually more beneficial in practice than following the hype.


Yes DB, we can soldier on happily, but it would not do any harm 
to understand templates.


The documentation examples quickly make your eyes glaze over, 
looking at the code in Phobos is doubtless instructive, but you 
can wade through a lot of that without finding what you want. 
Also I discovered an interesting fact today. the word 'mixin' 
does not appear in the language reference Templates section of 
dlang.org.


It should be used in at least one example. I just discovered by 
trial and error that I could use 'mixin' in Templates (as 
opposed to Template Mixins), and when you know that it seems 
likely that you can accomplish lots of stuff you couldn't 
before.


While I'm here, has anyone discovered a way to fudge a 
constructor super(..) call in a mixin template that's included 
in a class constructor. Since the mixin template is evaluated 
in the scope of the constructor, it seems like it should be OK.


I'm sure I'll get there in time ;=)

Steve


You've got to learn to think a bit more abstractly. Templates are 
generalizations of things.


Suppose I want to add two numbers using a function.

int add(int, int)?
double add(double, int)?
float add(float, int)?
char add(char, double)?
etc

which one? Do you want to have to create a function every time 
for every time?


Whats the only significant difference between all of them? If you 
can't answer this then you can't abstract and which is the reason 
you don't understand templates.



I could use one template function to handle all those cases 
above. That's what makes it powerful. I can basically write one 
function when you have to write 8, 10, 20 or whatever.


S add(S, T)(S a, T b) { return cast(S)(a + b); }

The compiler then generates all the concrete use cases for me. 
(and using oop can make it more powerful, S and T could be 
vectors) As long as the first type has an binary addition 
operator on it that takes the second type it will work and the 
template will work without change.


But you want to continue using the hold way. It is analogous to 
those that want to continue to write procedural code because they 
don't see the what oop has to offer.


BTW, how did you learn oop? Did you understand it all perfectly 
by reading a book or did you learn best by writing code that used 
it?


If you don't attempt to use templates, even in example code, you 
won't get it.






Re: Disabling the Garbage Collector

2014-03-03 Thread bearophile

Anonymouse:

To write tidy code? Much like const correctness, avoiding magic 
numbers and globals, not polluting namespace overly, only 
import what you need etc etc.


In general avoiding the self initialization of the GC doesn't 
make your code more tidy. Totally not activating the GC is only 
for special situations and special D code.


Bye,
bearophile


Re: Nobody understands templates?

2014-03-03 Thread Dominikus Dittes Scherkl

On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote:
I'm always willing to use templates, but maybe in fact the use 
cases are limited. I have a class for html elements (that 
implements DOM functionality), and a class for building trees 
with the tags. Of course, for html tags only string as a type 
makes sense.

Really?
Did you consider that there are three different flavors of 
"string"?

Does your function really only deal with string?
Or would someone need wstring or dstring?


class HTMLElement(T) if (is (T == string)) {

}

[...] I don't know [...] if I won't have to modify the template 
to adapt to new data types (which kinda defeats the purpose).

Not much if the different types have common features.
Most times it is still a big save of code to implement, even
if the types need to be handled different in some places.


Re: Is it possible to elegantly craft a class that can be used as shared and as normal?

2014-03-03 Thread Stanislav Blinov

On Monday, 3 March 2014 at 16:42:10 UTC, Gary Willoughby wrote:


class Test
{
private int number;

public void setNumber(int newValue)
{
number = newValue;
}

public int getNumber()
{
return number;
}
}

I need to instantiate that class twice like this:

auto a = new Test();
auto b = new shared Test();

And be able to use the methods of 'a' and 'b' without an error. 
How can i do this without overloading the methods is the big 
question. Casting the object is not an option in my particular 
use case.


You can't and you shouldn't be able to. Why are you so inclined 
on subverting the type system? If you're sharing an instance that 
doesn't support 'shared', then you're providing thread-safety 
mechanisms (i.e. synchronization) and cast away shared. If you're 
sharing an instance that does support 'shared', it should provide 
its own thread-safety mechanisms (that you shouldn't care about 
beyond documentation).


Note that even using plain operators on shared *scalars* is 
disallowed (though not yet implemented, 
https://d.puremagic.com/issues/show_bug.cgi?id=3672). Because 
implementation of those operators on shared variables is supposed 
to be different (i.e. atomicOp). The same goes for classes and 
structs too: 'void method()' and 'void method() shared' can't be 
expected to have the same implementation (and wouldn't).


Were it different, there would be no sense in explicit sharing.


Re: GC.BlkAttr.FINALIZE

2014-03-03 Thread Namespace

On Monday, 3 March 2014 at 02:44:09 UTC, Namespace wrote:

It's working now, I get all my debug infos I need.
But: I have absolutly no idea how to get the correct TypeInfo 
in rt_finalize2. The ClassInfo is identified by casting the 
void* pointer to a void** and then cast this void** to 
ClassInfo*. But for other TypeInfos this weird trick doesn't 
work. How can I extract the correct TypeInfo from this void**? 
:P


I get the real TypeInfo (not sure if this was intended this way) 
and in my test base it works! But in druntime I get the weird 
error:

src\rt\lifetime.d(1256): Error: variable a1 used before set


if (gc_getAttr(p) & BlkAttr.APPENDABLE)
{
void[] a1 = *cast(void[]*) ppv;
//printf("len = %d\n", a1.length);

void* p_a1 = &a1;
void* tp = p_a1 + 12;

TypeInfo* ti = cast(TypeInfo*) tp;

import std.string : toStringz;
string s = ti.toString(); // line 1256
printf("Type = %s\n", toStringz(s));

return;
}


Any call to ti will invoke the error. Any idea why?


Re: Is it possible to elegantly craft a class that can be used as shared and as normal?

2014-03-03 Thread Gary Willoughby

On Monday, 3 March 2014 at 12:07:15 UTC, Tolga Cakiroglu wrote:

Have you got a small example?


import std.stdio;

class Test{
private int number;

	public void setNumber( int newValue ) shared{ number = 
newValue; }


public int getNumber() shared{ return number; }
}

void main(){
auto test = new Test();

(cast(shared)test).setNumber( 5 );

writeln("Value = ", (cast(shared)test).getNumber() );
}

But do not forget the fact that because of the object `test` is 
not shared, therefore the attribute `number` is not shared. 
Thus, this will not be working multi-threded.


I still don't understand this example. To be more clear lets take 
the following class:


class Test
{
private int number;

public void setNumber(int newValue)
{
number = newValue;
}

public int getNumber()
{
return number;
}
}

I need to instantiate that class twice like this:

auto a = new Test();
auto b = new shared Test();

And be able to use the methods of 'a' and 'b' without an error. 
How can i do this without overloading the methods is the big 
question. Casting the object is not an option in my particular 
use case.


Re: Nobody understands templates?

2014-03-03 Thread Chris

On Sunday, 2 March 2014 at 18:59:23 UTC, Steve Teale wrote:

On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote:

This is a pretty good primer to templates:

https://semitwist.com/articles/article/view/template-primer-in-d



The trouble is with most of these tutorials that they offer 
examples that are things you would probably never want to do. I 
can already add an int to an int, or a double to a double, or 
an int to a double.


Perhaps the examples should pick on something like vector 
operations, but then who would be doing those with int, or some 
class? It would be doubles or pairs of, as in struct Coord.


I believe readers would study documentation and examples much 
more carefully if they were things they might realistically 
want to do. And that won't be type conversion - std.conv 
already does a pretty good job on that. So what?


We could really do with a place where template savvy open 
source contributors could publish interesting examples of 
template use.


Otherwise, Joe Soap, like me, can spend a great deal of time 
and effort in:


a) Determining when the use of a template might be advantageous,
b) Hacking at test programs to determine what the documentation 
means, and what works, and what doesn't.
c) After that, deciding whether it would be just as effective 
to use two or three separate methods.


Steve


Steve


I'm always willing to use templates, but maybe in fact the use 
cases are limited. I have a class for html elements (that 
implements DOM functionality), and a class for building trees 
with the tags. Of course, for html tags only string as a type 
makes sense.


class Element(T) {

}

or

class HTMLElement(T) if (is (T == string)) {

}

Tree(T) {

}

I implemented it as a template, because I thought it might be 
useful for other types as well, if I want to build a hierarchical 
tree of extracted data, be it integers, floating point numbers or 
whatever at a later point. However, I don't know a) if this will 
ever be the case and b) if I won't have to modify the template to 
adapt to new data types (which kinda defeats the purpose). I'm 
not against templates, I'm just not sure, if there are so many 
general or generalizable cases in programming for which templates 
are  _the_ solution.


Re: Disabling the Garbage Collector

2014-03-03 Thread Anonymouse

On Monday, 3 March 2014 at 01:48:23 UTC, bearophile wrote:

Jeroen Bollen:

Is there maybe a way to disable the garbage collector from 
running unless you explicitly call it?


I often seem to ask silly questions, but why do you need that?

Bye,
bearophile


To write tidy code? Much like const correctness, avoiding magic 
numbers and globals, not polluting namespace overly, only import 
what you need etc etc.


2.065 and MacPorts

2014-03-03 Thread Russel Winder
MacPorts DMD is still 2.064.

There appears to be a notice that the maintainer position for this port
is "vacant". I have no knowledge of creating or updating ports so cannot
really volunteer to do this myself, but it would be good if some people
did. I would be happy to be involved if others were as well.
-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



Re: Disabling the Garbage Collector

2014-03-03 Thread Jeroen Bollen

On Monday, 3 March 2014 at 02:33:49 UTC, Adam D. Ruppe wrote:

On Sunday, 2 March 2014 at 23:21:49 UTC, Jeroen Bollen wrote:
Is there maybe a way to disable the garbage collector from 
running unless you explicitly call it?


That's really the default. The GC in D runs if and only if you 
do a GC allocation and there isn't enough memory in its 
existing pool. Then it tries to do a collection to make room 
(and if that fails, it asks the operating system for more 
memory to grow its arena, and if that fails, it throws 
OutOfMemoryError).


If you call GC.disable, it just sets a flag to skip the try 
collection step.



But, in any case, the GC doesn't sit around in the background 
constantly running at random times. It only runs when you call 
on it to allocate.


If I were to compile without linking to the garbage collector, 
what would and what wouldn't work in D?


Re: Is it possible to elegantly craft a class that can be used as shared and as normal?

2014-03-03 Thread Tolga Cakiroglu

Have you got a small example?


import std.stdio;

class Test{
private int number;

	public void setNumber( int newValue ) shared{ number = newValue; 
}


public int getNumber() shared{ return number; }
}

void main(){
auto test = new Test();

(cast(shared)test).setNumber( 5 );

writeln("Value = ", (cast(shared)test).getNumber() );
}

But do not forget the fact that because of the object `test` is 
not shared, therefore the attribute `number` is not shared. Thus, 
this will not be working multi-threded.


Re: Mutexes and locking

2014-03-03 Thread alexhairyman

On Monday, 3 March 2014 at 07:38:05 UTC, Ali Çehreli wrote:

On 03/02/2014 10:38 PM, alexhairyman wrote:

> I think I'm missing something big, but I'm having troubles
with mutexes
> (using in a parallel foreach loop somewhere else); Why do the
trylocks
> return true shouldn't they return false because the mutex is
already
> locked?

The documentation says that Mutex is a recursive lock, meaning 
that the holder of the lock can lock it even further. :) There 
is an internal reference count so that the lock must be 
unlocked the equal number of times that it has been locked.


Oh okay, that makes sense.



> I don't think this is a phobos bug, I'm on OSX using dmd 2.065
>
> import core.sync.mutex;
> import std.stdio;
>
> void main()
> {
>Mutex m = new Mutex;
>m.lock();
>writefln("%s", m.tryLock());
>writefln("%s", m.tryLock());

The lock count is now 3. You must unlock it 3 times so that 
another thread can lock it.


>return;
> }
>
> produces:
> true
> true
>
> Thanks!
>Alex

Ali


Okay, so when doing something like this

Mutex hashlock;
void tdigest(string path)
{
  MD5Digest thasher = new MD5Digest;
  thasher.put(read(path)); //read the path in to the MD5 API
  hashlock.lock();
  hashkey[path] = thasher.finish();
  hashlock.unlock();
}
void main()
{
  hashlock = new Mutex();
... other stuff
  foreach(string s ; tp.parallel(array of strings))
  {
tdigest(s);
  }
... even more stuff
}

it will fail because the parallel foreach uses the main thread is 
being used which does some funky stuff? I'm trying to figure out 
how to implement this (for reference I'm just trying to create a 
big hash map of files and their md5's)