Re: Scope of temporaries as function arguments

2013-06-28 Thread Nick Sabalausky
On Fri, 28 Jun 2013 07:11:05 +0200
Maxim Fomin ma...@maxim-fomin.ru wrote:

 On Friday, 28 June 2013 at 04:54:56 UTC, Nick Sabalausky wrote:
  Probably a silly question, but I wanted to double-check...
 
  If you have this:
 
  struct Foo {...}
  bar(Foo());
 
  Then regardless of optimizations (aside from any optimizer 
  bugs, of
  course) the Foo temporary can't go out of scope or have its 
  dtor called
  until bar finishes executing, right?
 
 Struct dtor is always called in the end of the caller (bar in 
 example).
 
 This will be OK, but in general case no. Currently object is 
 copied in caller side but destroyed in callee side, and if one of 
 the arguments next to struct is passed by invoking function which 
 throws, callee and respectively dtor will never be called.
 

Interesting.

BTW, for anyone else reading, I just searched bugzilla and it looks
like the relevant issue is #9704.

Kinda ugly as it means refcounted RAII structs can leek under this
condition:

func(refCountedStruct, thisThrows());

Ouch.

  Or I guess more accurately, is there any guarantee that the 
  assert in
  func() below should always pass?:
 
  class Foo {
  int i = 1;
  //...etc...
  }
 
  struct Bar {
  Foo foo;
  ~this() {
  foo.i = 2;
  }
  //...etc...
  }
 
  void func(Bar bar)
  {
  //...anything here that *doesn't* change bar.foo.i...
 
  assert(bar.foo.i == 1);  // Guaranteed to pass?
  }
 
  void main() {
  Foo f = new Foo();
  func(Bar(f));
  }
 
 Here yes, but in general case if there are other arguments, and 
 one if them passed by lambda invocation which touches f and 
 modifies, then no.

Cool, thanks.



Re: Scope of temporaries as function arguments

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 06:15:26 UTC, Nick Sabalausky wrote:

On Fri, 28 Jun 2013 07:11:05 +0200
Maxim Fomin ma...@maxim-fomin.ru wrote:


On Friday, 28 June 2013 at 04:54:56 UTC, Nick Sabalausky wrote:
 Probably a silly question, but I wanted to double-check...

 If you have this:

 struct Foo {...}
 bar(Foo());

 Then regardless of optimizations (aside from any optimizer 
 bugs, of
 course) the Foo temporary can't go out of scope or have its 
 dtor called

 until bar finishes executing, right?

Struct dtor is always called in the end of the caller (bar in 
example).


This will be OK, but in general case no. Currently object is 
copied in caller side but destroyed in callee side, and if one 
of the arguments next to struct is passed by invoking function 
which throws, callee and respectively dtor will never be 
called.




Interesting.

BTW, for anyone else reading, I just searched bugzilla and it 
looks

like the relevant issue is #9704.

Kinda ugly as it means refcounted RAII structs can leek under 
this

condition:

func(refCountedStruct, thisThrows());

Ouch.


Just in case it wasn't clear from the original explanation, this 
is a bug, it *should* be perfectly safe to pass as many temps as 
you want, and expect the right amount of destructor called in 
case of a throw.


Re: Opaque structs

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 02:17:06 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 01:40:44 UTC, Andrej Mitrovic wrote:
Note that if we implement Issue 8728[1], we could even create 
a better

error message via:

-
struct S
{
   @disable(S is an opaque C type and must only be used as a 
pointer)

   this();

   @disable(S is an opaque C type and must only be used as a 
pointer)

   this(this);
}

void main()
{
   S* s1;  // ok
   S s2;  // user error
}
-

[1] : http://d.puremagic.com/issues/show_bug.cgi?id=8728


+1.  Anything that makes error messages clearer is a win in my 
book and there is precedents for it in @deprecate(msg) which 
was a clear win.


+1 also. I was going to say deprecated does it that way, so 
should disable, but that's already in the ticket ^^


Get body of a function as string

2013-06-28 Thread John Colvin
Is there any way of getting the body of a function as a string? 
(Obviously only when the source code is available to the compiler)


Re: Scope of temporaries as function arguments

2013-06-28 Thread Marco Leise
Am Fri, 28 Jun 2013 02:15:19 -0400
schrieb Nick Sabalausky seewebsitetocontac...@semitwist.com:

 BTW, for anyone else reading, I just searched bugzilla and it looks
 like the relevant issue is #9704.

Reminds me of an issue I reported later:
http://d.puremagic.com/issues/show_bug.cgi?id=10409

-- 
Marco



zip vs. lockstep -- problem when setting values

2013-06-28 Thread Joseph Rushton Wakeling
Consider the following equivalent code using zip and lockstep respectively to
iterate over the entries in an array and set their values:

auto arr1 = new double[10];
foreach(i, ref x; zip(iota(10), arr1))
{
x = i;
}
writeln(arr1);

auto arr2 = new double[10];
foreach(i, ref x; lockstep(iota(10), arr2))
{
x = i;
}
writeln(arr2);

The first array will still be full of nan's when it is output, while the second
will have values set correctly.  Can anyone offer a reasonable explanation why
this should be so?  It looks like a bug to me, or at best an unreasonable
difference in functionality. :-(


Re: Get body of a function as string

2013-06-28 Thread bearophile

John Colvin:

Is there any way of getting the body of a function as a string? 
(Obviously only when the source code is available to the 
compiler)


I think that currently there isn't a simple way to do it. What is 
your use case?


Bye,
bearophile


Re: Get body of a function as string

2013-06-28 Thread John Colvin

On Friday, 28 June 2013 at 13:18:39 UTC, bearophile wrote:

John Colvin:

Is there any way of getting the body of a function as a 
string? (Obviously only when the source code is available to 
the compiler)


I think that currently there isn't a simple way to do it. What 
is your use case?


Bye,
bearophile


I want to create a function with an identical body but different 
parameters: e.g. given a function


int foo(int a){ return a+1; }

automatically create a new function

int foo(int a)(){ return a+1; }


I'm trying to implement a sort of automatic compile-time currying.


Re: Get body of a function as string

2013-06-28 Thread Namespace

And why don't you call the function from your clone function?

Maybe this could help you: http://dpaste.1azy.net/fork/597affd2
I used it to generate my own rvalue functions because of the lack 
of rvalue references.


sort error

2013-06-28 Thread snow

Hello there,
Ive got the following code

http://dpaste.dzfl.pl/e391a268

This code throws me a Range Exception in Algorithm.d.

If I use a lower number of random vectors, like 100, the code 
terminates. Also, if I delete the template instruction like this :


sort(individuals);

I also don't get an exception. Does anybody know, why this is the 
case?


Re: Scope of temporaries as function arguments

2013-06-28 Thread Maxim Fomin

On Friday, 28 June 2013 at 08:08:17 UTC, monarch_dodra wrote:


Just in case it wasn't clear from the original explanation, 
this is a bug, it *should* be perfectly safe to pass as many 
temps as you want, and expect the right amount of destructor 
called in case of a throw.


Original explanation lacks the word bug deliberately because 
this is not a bug (in a sense that dmd generates wrong code), but 
a language design problem. How could you do this:


struct S
{
   int i = 1;
}

void foo(S s)
{
   s.i = 2;
}

void main()
{
   S s;
   foo(s);
}

Currently there are two dtors, one which gets S(2) at the end of 
foo and second at the end of main, which gets S(1). If you move 
dtor from callee to caller, it would get S(1) object (struct is 
passed by value), but it doesn't make sense to destruct S(1) 
where you have S(2). One possible solution is to pass by pointer 
in low level, which would probably increase magnitude of problems.


Re: Scope of temporaries as function arguments

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 14:26:04 UTC, Maxim Fomin wrote:

On Friday, 28 June 2013 at 08:08:17 UTC, monarch_dodra wrote:


Just in case it wasn't clear from the original explanation, 
this is a bug, it *should* be perfectly safe to pass as many 
temps as you want, and expect the right amount of destructor 
called in case of a throw.


Original explanation lacks the word bug deliberately because 
this is not a bug (in a sense that dmd generates wrong code), 
but a language design problem. How could you do this:


struct S
{
   int i = 1;
}

void foo(S s)
{
   s.i = 2;
}

void main()
{
   S s;
   foo(s);
}

Currently there are two dtors, one which gets S(2) at the end 
of foo and second at the end of main, which gets S(1). If you 
move dtor from callee to caller, it would get S(1) object 
(struct is passed by value), but it doesn't make sense to 
destruct S(1) where you have S(2). One possible solution is to 
pass by pointer in low level, which would probably increase 
magnitude of problems.


I don't understand the problem... There *should* be two 
destroyers... main.s is postblitted into foo.s, and then foo 
destroys foo.s at the end of its scope...


Where is the problem here?


Re: sort error

2013-06-28 Thread bearophile

snow:


http://dpaste.dzfl.pl/e391a268

This code throws me a Range Exception in Algorithm.d.

If I use a lower number of random vectors, like 100, the code 
terminates. Also, if I delete the template instruction like 
this :


sort(individuals);

I also don't get an exception. Does anybody know, why this is 
the case?


If I replace your vector with a tuple (that defines automatically 
a lexicographic opCmp) the problem seems to disappear:



import std.stdio, std.random, std.array,
   std.algorithm, std.range, std.typecons;

alias Vector3D = Tuple!(double,x, double,y, double,z);
alias Individual = Vector3D[];

Vector3D getFitness(in ref Individual individual) pure nothrow {
return individual[0];
}

bool myComp(in Individual x, in Individual y)  {
return x.getFitness  y.getFitness;
}

Vector3D[] initializeRandomVectors(in uint count) {
Vector3D[] result;
foreach (immutable i; 0 .. count)
result ~= Vector3D(uniform(0.0, 11.0),
   uniform(0.0, 11.0),
   uniform(0.0, 11.0));
return result;
}

Individual[] initializeRandomIndividuals()  {
return 1000.iota.map!(_ = 10.initializeRandomVectors).array;
}

void main() {
auto individuals =  initializeRandomIndividuals;
individuals.sort!(myComp, SwapStrategy.stable);
finished.writeln;
}


Bye,
bearophile


Re: Scope of temporaries as function arguments

2013-06-28 Thread Maxim Fomin

On Friday, 28 June 2013 at 15:17:12 UTC, monarch_dodra wrote:


Should I have expected a different behavior?


import std.stdio;

int callme()
{
   throw new Exception();
}

struct S
{
   int i = 0;
this(int i){this.i = i; writeln(constructing: , i);}
this(this){writeln(postbliting: , i);}
~this(){writeln(destroying: , i);}
}

void foo(S s, int i)
{
   s.i = 2;
}

void main()
{
   S s = S(1);
   foo(s, callme());
}

Destructor for copied object is not called because it is placed 
in foo(). Before calling foo(), dmd makes a copy of main.s, calls 
postblit, then puts code to invoke callme() and code to invoke 
foo(). Since callme() throws, foo() is not called and destructor 
placed in foo() is also not called. A struct copy escapes 
destructor.


Now, if you try fix this by putting dtor for copy not in foo(), 
but in main immediately after foo() invocation, you will have a 
problem because destructor would get S(1) object while it should 
destroy S(2). Any modification made in foo() is lost. This can be 
possible fixed by passing copy by reference which would probably 
create new ABI problems.


counting words

2013-06-28 Thread Benjamin Thaut

I'm currently making a few tests with std.algorithm, std.range, etc

I have a arry of words. Is it possible to count how often each word is 
contained in the array and then sort the array by the count of the 
individual words by chaining ranges? (e.g. without using a foreach loop 
+ hashmap)?


--
Kind Regards
Benjamin Thaut


Re: Scope of temporaries as function arguments

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 15:33:40 UTC, Maxim Fomin wrote:

On Friday, 28 June 2013 at 15:17:12 UTC, monarch_dodra wrote:


Should I have expected a different behavior?


import std.stdio;

int callme()
{
   throw new Exception();
}

struct S
{
   int i = 0;
this(int i){this.i = i; writeln(constructing: , i);}
this(this){writeln(postbliting: , i);}
~this(){writeln(destroying: , i);}
}

void foo(S s, int i)
{
   s.i = 2;
}

void main()
{
   S s = S(1);
   foo(s, callme());
}

Destructor for copied object is not called because it is placed 
in foo(). Before calling foo(), dmd makes a copy of main.s, 
calls postblit, then puts code to invoke callme() and code to 
invoke foo(). Since callme() throws, foo() is not called and 
destructor placed in foo() is also not called. A struct copy 
escapes destructor.


Now, if you try fix this by putting dtor for copy not in foo(), 
but in main immediately after foo() invocation, you will have a 
problem because destructor would get S(1) object while it 
should destroy S(2). Any modification made in foo() is lost. 
This can be possible fixed by passing copy by reference which 
would probably create new ABI problems.


I thought that was where you were getting to. Couldn't this 
simply be solved by having the *caller*, destroy the object that 
was postblitted into foo? Since foo ends up not being called 
(because of the exception), then I see no problem having the 
caller destroy the to-be-passed-but-ends-up-not object?


Basically, it would mean creating a argument scope into which 
each arg is constructed. If something throws, then the up to now 
built args are deconstruted just like with standard scope. If 
you reach the end of the scope, then call is made, but passing 
the resposability of destruction to foo.


EG, pseudo code:

memcpy_all_args;
try
{
foreach arg in args:
arg.postblit;
exit(failure) arg.destroy;
}
call_foo;

Isn't that how C++ does it? In terms of passing args by value, I 
see no difference between CC and postblit... And I'm 99% sure C++ 
doesn't have this problem...


Re: counting words

2013-06-28 Thread Brad Anderson

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:
I'm currently making a few tests with std.algorithm, std.range, 
etc


I have a arry of words. Is it possible to count how often each 
word is contained in the array and then sort the array by the 
count of the individual words by chaining ranges? (e.g. without 
using a foreach loop + hashmap)?


If you don't mind sorting twice:

words.sort()
 .group()
 .array()
 .sort!((a, b)= a[1]  b[1])
 .map!(a = a[0])
 .copy(words);

You could also do it with a hashmap to keep the count.


Re: counting words

2013-06-28 Thread Brad Anderson

On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:
I'm currently making a few tests with std.algorithm, 
std.range, etc


I have a arry of words. Is it possible to count how often each 
word is contained in the array and then sort the array by the 
count of the individual words by chaining ranges? (e.g. 
without using a foreach loop + hashmap)?


If you don't mind sorting twice:

words.sort()
 .group()
 .array()
 .sort!((a, b)= a[1]  b[1])
 .map!(a = a[0])
 .copy(words);

You could also do it with a hashmap to keep the count.


Like so:

size_t[string] dic;
words.map!((w) { ++dic[w.idup]; return w; })
 .array // eager (so dic is filled first), sortable
 .sort!((a, b) { bool less = dic[a]  dic[b]; return less 
|| less  a  b; })

 .uniq
 .copy(words);

It's a bit ugly and abuses side effects with the hash map.  The 
order will differ from the other program when words have 
identical counts.


Re: Scope of temporaries as function arguments

2013-06-28 Thread Ali Çehreli

On 06/28/2013 09:01 AM, monarch_dodra wrote:

 And I'm 99% sure C++ doesn't have this problem...

+1%. :)

I just finished checking. No, C++ does not have this problem. But there 
is the following related issue, which every real C++ programmer should 
know. ;)



http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices

Ali

P.S. The C++ program that I have just used for testing:

#include iostream
#include stdexcept

using namespace std;

int callme()
{
throw runtime_error();
return 0;
}

struct S
{
int i_;

S(int i)
:
i_(i)
{
cout  constructing:   i_   at   this  '\n';
}

S(const S  that)
{
cout  copying:   that.i_   to   this  '\n';
i_ = that.i_;
}

~S()
{
cout  destroying:   i_   at   this  '\n';
}
};

void foo(int i, S s)
{
   s.i_ = 2;
}

int main()
{
S s = S(1);

try {
foo(callme(), s);

} catch (...) {
cout  caught\n;
}
}



Re: counting words

2013-06-28 Thread Benjamin Thaut

Am 28.06.2013 18:42, schrieb Brad Anderson:

On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:

I'm currently making a few tests with std.algorithm, std.range, etc

I have a arry of words. Is it possible to count how often each word
is contained in the array and then sort the array by the count of the
individual words by chaining ranges? (e.g. without using a foreach
loop + hashmap)?


If you don't mind sorting twice:

words.sort()
 .group()
 .array()
 .sort!((a, b)= a[1]  b[1])
 .map!(a = a[0])
 .copy(words);

You could also do it with a hashmap to keep the count.


Like so:

 size_t[string] dic;
 words.map!((w) { ++dic[w.idup]; return w; })
  .array // eager (so dic is filled first), sortable
  .sort!((a, b) { bool less = dic[a]  dic[b]; return less ||
less  a  b; })
  .uniq
  .copy(words);

It's a bit ugly and abuses side effects with the hash map.  The order
will differ from the other program when words have identical counts.


I figured something like this by now too. Thank you.
But I don't quite understand what the copy is for at the end?

--
Kind Regards
Benjamin Thaut


Re: counting words

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:
I'm currently making a few tests with std.algorithm, 
std.range, etc


I have a arry of words. Is it possible to count how often each 
word is contained in the array and then sort the array by the 
count of the individual words by chaining ranges? (e.g. 
without using a foreach loop + hashmap)?


If you don't mind sorting twice:

words.sort()
 .group()
 .array()
 .sort!((a, b)= a[1]  b[1])
 .map!(a = a[0])
 .copy(words);

You could also do it with a hashmap to keep the count.


It's just missing the construction scheme for words. I had this:

text
.splitter();
.reduce!((words, w)=++words[w], words)(int[string]);

But alas... reduce's signature is not ctfe-able :(

Well, I've had a PR open for this for about 8 months now...


Re: Scope of temporaries as function arguments

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 16:50:07 UTC, Maxim Fomin wrote:

On Friday, 28 June 2013 at 16:01:05 UTC, monarch_dodra wrote:


I thought that was where you were getting to. Couldn't this 
simply be solved by having the *caller*, destroy the object 
that was postblitted into foo? Since foo ends up not being 
called (because of the exception), then I see no problem 
having the caller destroy the to-be-passed-but-ends-up-not 
object?


In case when there is no exception, struct argument is passed 
and is modified in callee, destructor in caller would have 
unchanged version (because structs are passed by value).


I'm saying the callee destroys whatever is passed to it, all 
the time, but that means callee needs to actually be called.


If caller constructs objects, but then fails to actually call 
callee, then caller *has* to be responsible for destroying the 
objects it has built, but not passed to anyone. But this is only 
if an exception is thrown:


No exception:
  Caller constructs objects into foo.
  foo is called, foo becomes owner of objects.
  foo finishes.
  foo destroys object.

Exception:
  Caller starts construction.
  Exception is thrown.
  Caller destroys objects as exception is propagating.
  All objects are destroyed, exception goes up.




Re: counting words

2013-06-28 Thread Brad Anderson

On Friday, 28 June 2013 at 16:48:08 UTC, Benjamin Thaut wrote:

Am 28.06.2013 18:42, schrieb Brad Anderson:

On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:
I'm currently making a few tests with std.algorithm, 
std.range, etc


I have a arry of words. Is it possible to count how often 
each word
is contained in the array and then sort the array by the 
count of the
individual words by chaining ranges? (e.g. without using a 
foreach

loop + hashmap)?


If you don't mind sorting twice:

words.sort()
.group()
.array()
.sort!((a, b)= a[1]  b[1])
.map!(a = a[0])
.copy(words);

You could also do it with a hashmap to keep the count.


Like so:

size_t[string] dic;
words.map!((w) { ++dic[w.idup]; return w; })
 .array // eager (so dic is filled first), sortable
 .sort!((a, b) { bool less = dic[a]  dic[b]; return 
less ||

less  a  b; })
 .uniq
 .copy(words);

It's a bit ugly and abuses side effects with the hash map.  
The order
will differ from the other program when words have identical 
counts.


I figured something like this by now too. Thank you.
But I don't quite understand what the copy is for at the end?


Just replacing your original word list with the sorted list 
(which I just realized is wrong because it will leave a bunch of 
words on the end, oops).  You could .array it instead to get a 
new array or just store the range with auto and consume that 
where needed with no extra array allocation.


Re: Scope of temporaries as function arguments

2013-06-28 Thread Maxim Fomin

On Friday, 28 June 2013 at 16:01:05 UTC, monarch_dodra wrote:


I thought that was where you were getting to. Couldn't this 
simply be solved by having the *caller*, destroy the object 
that was postblitted into foo? Since foo ends up not being 
called (because of the exception), then I see no problem having 
the caller destroy the to-be-passed-but-ends-up-not object?


In case when there is no exception, struct argument is passed and 
is modified in callee, destructor in caller would have unchanged 
version (because structs are passed by value).


Basically, it would mean creating a argument scope into which 
each arg is constructed. If something throws, then the up to 
now built args are deconstruted just like with standard scope. 
If you reach the end of the scope, then call is made, but 
passing the resposability of destruction to foo.


This is another option but suffers from the same problem (in 
posted examples exception is always thrown, but in reality it 
need not to).




Re: sort error

2013-06-28 Thread Ali Çehreli

On 06/28/2013 07:00 AM, snow wrote: Hello there,
 Ive got the following code

 http://dpaste.dzfl.pl/e391a268

 This code throws me a Range Exception in Algorithm.d.

 If I use a lower number of random vectors, like 100, the code
 terminates. Also, if I delete the template instruction like this :

 sort(individuals);

 I also don't get an exception.

Yes, what is thrown is an Error. (Error and Exception are different 
hierarchies under Throwable.)


 Does anybody know, why this is the case?

Your opCmp does not provide a complete ordering of objects:

int opCmp(ref const Vector3D vec) {
if (this.x  vec.x  this.y  vec.y  this.z  vec.z)
return 1;

if (this.x  vec.x  this.y  vec.y  this.z  vec.z)
return -1;

return 0;
}

According to that function, the following two values are neither less 
than nor greater than the other:


// passes:
assert(!(Vector3D(1, 2, 3)  Vector3D(2, 1, 3)) 
   !(Vector3D(1, 2, 3)  Vector3D(2, 1, 3)));

Ali



Re: Scope of temporaries as function arguments

2013-06-28 Thread Steven Schveighoffer

On Fri, 28 Jun 2013 12:44:02 -0400, Ali Çehreli acehr...@yahoo.com wrote:

I just finished checking. No, C++ does not have this problem. But there  
is the following related issue, which every real C++ programmer should  
know. ;)


  
http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices


Thank you, I didn't know this.  I can consider myself a real C++  
programmer now :)


-Steve


Re: Scope of temporaries as function arguments

2013-06-28 Thread Maxim Fomin

On Friday, 28 June 2013 at 16:44:03 UTC, Ali Çehreli wrote:

Ali

P.S. The C++ program that I have just used for testing:


Are you sure that the code is exact translation of demonstrated D 
problem? I see difference in argument passing order and your 
version uses try-catch block.


This code

#include iostream
#include stdexcept

using namespace std;

int callme()
{
throw runtime_error();
return 0;
}

struct S
{
int i_;

S(int i)
:
i_(i)
{
cout  constructing:   i_   at   this  '\n';
}

S(const S  that)
{
cout  copying:   that.i_   to   this  '\n';
i_ = that.i_;
}

~S()
{
cout  destroying:   i_   at   this  '\n';
}
};

void foo(S s, int i)
{
   s.i_ = 2;
}

int main()
{
S s = S(1);
foo(s, callme());

}

prints for me:

constructing: 1 at 0x7fffb93078d0
terminate called after throwing an instance of 
'std::runtime_error'

  what():
Aborted


Re: counting words

2013-06-28 Thread Benjamin Thaut

Am 28.06.2013 19:01, schrieb Brad Anderson:

On Friday, 28 June 2013 at 16:48:08 UTC, Benjamin Thaut wrote:

Am 28.06.2013 18:42, schrieb Brad Anderson:

On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote:

I'm currently making a few tests with std.algorithm, std.range, etc

I have a arry of words. Is it possible to count how often each word
is contained in the array and then sort the array by the count of the
individual words by chaining ranges? (e.g. without using a foreach
loop + hashmap)?


If you don't mind sorting twice:

words.sort()
.group()
.array()
.sort!((a, b)= a[1]  b[1])
.map!(a = a[0])
.copy(words);

You could also do it with a hashmap to keep the count.


Like so:

size_t[string] dic;
words.map!((w) { ++dic[w.idup]; return w; })
 .array // eager (so dic is filled first), sortable
 .sort!((a, b) { bool less = dic[a]  dic[b]; return less ||
less  a  b; })
 .uniq
 .copy(words);

It's a bit ugly and abuses side effects with the hash map. The order
will differ from the other program when words have identical counts.


I figured something like this by now too. Thank you.
But I don't quite understand what the copy is for at the end?


Just replacing your original word list with the sorted list (which I
just realized is wrong because it will leave a bunch of words on the
end, oops).  You could .array it instead to get a new array or just
store the range with auto and consume that where needed with no extra
array allocation.


Ok, thank you very much

--
Kind Regards
Benjamin Thaut


Re: Scope of temporaries as function arguments

2013-06-28 Thread Ali Çehreli

On 06/28/2013 10:11 AM, Steven Schveighoffer wrote:

 On Fri, 28 Jun 2013 12:44:02 -0400, Ali Çehreli acehr...@yahoo.com 
wrote:


 
http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#BestPractices 




 Thank you, I didn't know this.

Even though this issue is covered in Herb Sutter's Exceptional C++ book, 
which I had read with great interest, I re-learned it last year when a 
colleague showed that link to me.


I have always considered C++ a language where mere-mortals like myself 
must read lots and lots of books to advance (or to write any decent 
code). This thread makes me think that D is following in C++'s steps. I 
am too normal to figure out these corner cases myself. :-/


Ali



Re: Scope of temporaries as function arguments

2013-06-28 Thread Ali Çehreli

On 06/28/2013 10:17 AM, Maxim Fomin wrote:

 Are you sure that the code is exact translation of demonstrated D
 problem?

Sorry. I omitted two points.

 I see difference in argument passing order and your version
 uses try-catch block.

1) C++ does not specify whether the stack gets unwound when the program 
terminates with an uncaught exception. That's why I caught to ensure 
that the stack objects would be destroyed.


2) C++ does not specify in what order function arguments are evaluated. 
I swapped the parameters because I used gcc under Linux, where the 
parameters are executed from right-to-left.


Ali



Re: Scope of temporaries as function arguments

2013-06-28 Thread Maxim Fomin

On Friday, 28 June 2013 at 16:57:29 UTC, monarch_dodra wrote:

On Friday, 28 June 2013 at 16:50:07 UTC, Maxim Fomin wrote:

On Friday, 28 June 2013 at 16:01:05 UTC, monarch_dodra wrote:


I thought that was where you were getting to. Couldn't this 
simply be solved by having the *caller*, destroy the object 
that was postblitted into foo? Since foo ends up not being 
called (because of the exception), then I see no problem 
having the caller destroy the to-be-passed-but-ends-up-not 
object?


In case when there is no exception, struct argument is passed 
and is modified in callee, destructor in caller would have 
unchanged version (because structs are passed by value).


I'm saying the callee destroys whatever is passed to it, all 
the time, but that means callee needs to actually be called.


If caller constructs objects, but then fails to actually call 
callee, then caller *has* to be responsible for destroying 
the objects it has built, but not passed to anyone. But this is 
only if an exception is thrown:


No exception:
  Caller constructs objects into foo.
  foo is called, foo becomes owner of objects.
  foo finishes.
  foo destroys object.

Exception:
  Caller starts construction.
  Exception is thrown.
  Caller destroys objects as exception is propagating.
  All objects are destroyed, exception goes up.


In this scenario caller should distinguish between two 
situations: exception was thrown during arguments evaluation or 
was thrown somewhere in foo, when callee can call destructor for 
passed argument. Otherwise (for example, using current 
scope(failure) mechanism to tackle the problem), destructor would 
be called twice on same struct - first time inside callee as 
usual, second time - in caller which would think that exception 
was thrown during argument evaluation. I think some tweak 
required here, but this sound like a good solution.


Re: Scope of temporaries as function arguments

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 17:30:58 UTC, Ali Çehreli wrote:

On 06/28/2013 10:17 AM, Maxim Fomin wrote:

 Are you sure that the code is exact translation of
demonstrated D
 problem?

Sorry. I omitted two points.

 I see difference in argument passing order and your version
 uses try-catch block.

1) C++ does not specify whether the stack gets unwound when the 
program terminates with an uncaught exception. That's why I 
caught to ensure that the stack objects would be destroyed.


Doesn't it? The stack needs to be unwound for the exception to 
even escape. It's merely the globals that may not be destroyed. 
(AFAIK)


2) C++ does not specify in what order function arguments are 
evaluated. I swapped the parameters because I used gcc under 
Linux, where the parameters are executed from right-to-left.


Ali




Re: counting words

2013-06-28 Thread bearophile

monarch_dodra:


Well, I've had a PR open for this for about 8 months now...


Do you have Phobos commit rights? If the answer is positive then 
perhaps you can review and commit some Phobos code written by 
Andrei and he can do the same with yours.
Today it seems the major development bottleneck is the review 
queue and not having enough writing of patches :-)


Bye,
bearophile


Re: Scope of temporaries as function arguments

2013-06-28 Thread Ali Çehreli

On 06/28/2013 10:53 AM, monarch_dodra wrote:

 On Friday, 28 June 2013 at 17:30:58 UTC, Ali Çehreli wrote:

 1) C++ does not specify whether the stack gets unwound when the
 program terminates with an uncaught exception. That's why I caught to
 ensure that the stack objects would be destroyed.

 Doesn't it? The stack needs to be unwound for the exception to even
 escape. It's merely the globals that may not be destroyed. (AFAIK)

The standard does not specify it. On Linux, abort() gets called causing 
a core dump, which may be more useful than executing the destructors.


Ali



[Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread MattCoder

Hi,

I would like to know if it's possible to pass the return of a 
function as argument to another function as below:


import std.stdio;

auto foo(int x, int y){
writeln(x, y);
return 3, 4;
}

void main(){
foo(foo(1,2));
}

I would like to print:
1 2
3 4

PS: I tried return a tuple but it doesn't works.

Thanks,

Matheus.


Re: Opaque structs

2013-06-28 Thread Andrej Mitrovic
On 6/28/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
 Unfortunately this tends to spawn unreadable error messages:

It looks like there's also a blocking bug:
http://d.puremagic.com/issues/show_bug.cgi?id=10497

So I'll have to use my new technique instead anyway. :p


Re: counting words

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 17:59:58 UTC, bearophile wrote:

monarch_dodra:


Well, I've had a PR open for this for about 8 months now...


Do you have Phobos commit rights? If the answer is positive 
then perhaps you can review and commit some Phobos code written 
by Andrei and he can do the same with yours.
Today it seems the major development bottleneck is the review 
queue and not having enough writing of patches :-)


Bye,
bearophile


The answer is negative though :(


Re: counting words

2013-06-28 Thread Brad Anderson

On Friday, 28 June 2013 at 18:53:44 UTC, monarch_dodra wrote:

On Friday, 28 June 2013 at 17:59:58 UTC, bearophile wrote:

monarch_dodra:


Well, I've had a PR open for this for about 8 months now...


Do you have Phobos commit rights? If the answer is positive 
then perhaps you can review and commit some Phobos code 
written by Andrei and he can do the same with yours.
Today it seems the major development bottleneck is the review 
queue and not having enough writing of patches :-)


Bye,
bearophile


The answer is negative though :(


95 merged phobos pull requests (109 total).  Long overdue, I'd 
say.  I don't know if there is really a formal process to getting 
write privileges but if any of the people who decide are reading 
this I nominate monarch_dodra.


Re: counting words

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 19:13:28 UTC, Brad Anderson wrote:

On Friday, 28 June 2013 at 18:53:44 UTC, monarch_dodra wrote:

On Friday, 28 June 2013 at 17:59:58 UTC, bearophile wrote:

monarch_dodra:


Well, I've had a PR open for this for about 8 months now...


Do you have Phobos commit rights? If the answer is positive 
then perhaps you can review and commit some Phobos code 
written by Andrei and he can do the same with yours.
Today it seems the major development bottleneck is the review 
queue and not having enough writing of patches :-)


Bye,
bearophile


The answer is negative though :(


95 merged phobos pull requests (109 total).  Long overdue, I'd 
say.  I don't know if there is really a formal process to 
getting write privileges but if any of the people who decide 
are reading this I nominate monarch_dodra.


How did you come to that number? Total amount of pulls 
*submitted* ? I count 95 *closed* pull requests, but I think only 
about 50% of them ever made it through? I'm not sure how to check 
though (apart from counting 1 by 1...)


I'm unsure I'd be totally comfortable pulling inside phobos, but 
it *is* true that the queue is just getting longer and longer. 
There are some pulls just sitting there, submitted by trusted 
people (with pull rights), that are validated and reviewed, but 
are just waiting for a puller to do the deed. There needs to be a 
few more reviewers, the ones we have are doing a great job, but 
are overworked.


But I wouldn't want to hijack this thread, nor is learn really 
the place to talk about that.


Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread Ellery Newcomer

On 06/28/2013 11:07 AM, MattCoder wrote:

Hi,

I would like to know if it's possible to pass the return of a function
as argument to another function as below:

import std.stdio;

auto foo(int x, int y){
 writeln(x, y);
 return 3, 4;
}

void main(){
 foo(foo(1,2));
}

I would like to print:
1 2
3 4

PS: I tried return a tuple but it doesn't works.

Thanks,

Matheus.


No, functions cannot return tuples.

However, they can return std.typecons.Tuple, so you could do this:

auto foo(int i, int j) {
writeln(i,  , j);
return tuple(3,4);
}
void main() {
foo(foo(1,2).field);
}



Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread Simen Kjaeraas
On Fri, 28 Jun 2013 20:07:23 +0200, MattCoder mattco...@hotmail.com  
wrote:



Hi,

I would like to know if it's possible to pass the return of a function  
as argument to another function as below:


import std.stdio;

auto foo(int x, int y){
writeln(x, y);
return 3, 4;
}

void main(){
foo(foo(1,2));
}

I would like to print:
1 2
3 4

PS: I tried return a tuple but it doesn't works.

Thanks,

Matheus.


Not directly,  no. But this should work:


import std.stdio;
import std.typecons : tuple;

auto foo(int x, int y){
writeln(x, y);
return tuple(3, 4);
}

void main(){
foo(foo(1,2).tupleof);
}
--
Simen


Re: counting words

2013-06-28 Thread Brad Anderson

On Friday, 28 June 2013 at 19:31:22 UTC, monarch_dodra wrote:

On Friday, 28 June 2013 at 19:13:28 UTC, Brad Anderson wrote:


95 merged phobos pull requests (109 total).  Long overdue, I'd 
say.  I don't know if there is really a formal process to 
getting write privileges but if any of the people who decide 
are reading this I nominate monarch_dodra.


How did you come to that number? Total amount of pulls 
*submitted* ? I count 95 *closed* pull requests, but I think 
only about 50% of them ever made it through? I'm not sure how 
to check though (apart from counting 1 by 1...)


I'm unsure I'd be totally comfortable pulling inside phobos, 
but it *is* true that the queue is just getting longer and 
longer. There are some pulls just sitting there, submitted by 
trusted people (with pull rights), that are validated and 
reviewed, but are just waiting for a puller to do the deed. 
There needs to be a few more reviewers, the ones we have are 
doing a great job, but are overworked.


But I wouldn't want to hijack this thread, nor is learn really 
the place to talk about that.


I counted closed (I assumed most were merged).  Github makes it 
hard to glean data from pull requests.


Allow me to share Exhibit B though: 
https://github.com/D-Programming-Language/phobos/graphs/contributors?from=2012-06-21to=2013-06-21type=c


Second most prolific contributor by commits to phobos over the 
last year.


I am nominating you to do extra bureaucratic work though so I'm 
kind of being an asshole when you think about it. :P


Local templates and alias parameters

2013-06-28 Thread John Colvin

void main()
{
template A(alias a)
{
enum A = a.stringof;
}
int b;
	string s = A!b;   // Error: template instance A!(b) cannot use 
local 'b' as parameter to non-global template A(alias a)

}

Bug or feature?


Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread MattCoder

On Friday, 28 June 2013 at 19:39:41 UTC, Ellery Newcomer wrote:
However, they can return std.typecons.Tuple, so you could do 
this:


auto foo(int i, int j) {
writeln(i,  , j);
return tuple(3,4);
}
void main() {
foo(foo(1,2).field);
}



Hi Ellery,

Thanks for your help, it works nicely.


Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread MattCoder

On Friday, 28 June 2013 at 19:43:37 UTC, Simen Kjaeraas wrote:

import std.stdio;
import std.typecons : tuple;

auto foo(int x, int y){
writeln(x, y);
return tuple(3, 4);
}

void main(){
foo(foo(1,2).tupleof);
}


Hi Simen,

Thanks for your help too, it worked!


Re: Opaque structs

2013-06-28 Thread Johannes Pfau
Am Fri, 28 Jun 2013 03:40:31 +0200
schrieb Andrej Mitrovic andrej.mitrov...@gmail.com:

 struct S
 {
 @disable(S is an opaque C type and must only be used as a
 pointer) this();
 
 @disable(S is an opaque C type and must only be used as a
 pointer) this(this);
 }

A naive question: Why isn't struct S {} enough? This should be a struct
with size 0 so why do we need to disable the constructor and postblit
explicitly?


Re: Opaque structs

2013-06-28 Thread Andrej Mitrovic
On 6/28/13, Johannes Pfau nos...@example.com wrote:
 A naive question: Why isn't struct S {} enough? This should be a struct
 with size 0 so why do we need to disable the constructor and postblit
 explicitly?

Because the user should never be able to use such a struct by value,
in other words a user might mistakenly write code such as:

-
struct S { }

extern(C) S* get();
extern(C) void call(S*);

void main()
{
S* s = getS();

S s2 = *s;  // copies 1 byte
call(s2);  // no telling what will happen on the C side, usually
memory corruption + crash
}
-


Re: Get body of a function as string

2013-06-28 Thread John Colvin

On Friday, 28 June 2013 at 13:55:54 UTC, Namespace wrote:

And why don't you call the function from your clone function?


Because the body of the new function needs to see the parameters 
as known at compile-time.



Maybe this could help you: http://dpaste.1azy.net/fork/597affd2
I used it to generate my own rvalue functions because of the 
lack of rvalue references.


Thanks, that was helpful for a few hints, but it doesn't fix this 
particular problem.


Re: Get body of a function as string

2013-06-28 Thread bearophile

John Colvin:

Because the body of the new function needs to see the 
parameters as known at compile-time.


I think to curry a function all you need to know is its 
signature. And in std.traits probably there is all the 
functionality to see all kinds of function arguments, their 
names, tags, etc.


Bye,
bearophile


Re: [Question] Could a function return a list of arguments to call another function?

2013-06-28 Thread David
 However, they can return std.typecons.Tuple, so you could do this:
 
 auto foo(int i, int j) {
 writeln(i,  , j);
 return tuple(3,4);
 }
 void main() {
 foo(foo(1,2).field);
 }
 

field is deprecated in favor of expand


Re: Get body of a function as string

2013-06-28 Thread monarch_dodra

On Friday, 28 June 2013 at 20:50:55 UTC, John Colvin wrote:

On Friday, 28 June 2013 at 13:55:54 UTC, Namespace wrote:

And why don't you call the function from your clone function?


Because the body of the new function needs to see the 
parameters as known at compile-time.



Maybe this could help you: http://dpaste.1azy.net/fork/597affd2
I used it to generate my own rvalue functions because of the 
lack of rvalue references.


Thanks, that was helpful for a few hints, but it doesn't fix 
this particular problem.


Oh, hey! I remember participating in writing some of that :)

Yeah, with traits, you can get enough info to extract all the 
information you want about the function to redeclare it any way 
you want.


The only thing you *can't* get is... the body!

If you have access to the source code of the function, you could 
redeclare it as a token string? eg:


before:

int foo(int a)
{
return a+1;
}

after:
enum fooString =
q{
return a+1;
};

int foo(int a){mixin(fooString);}
int foo()(int a){mixin(fooString);}

Yeah... not a great solution.



The only way I could see it happen would be with a compile 
__trait ?


Does the compiler even have the info, or is it completely 
obliterated after the lex phase?


The compiler *should* have the info, since it can pinpoint the 
coordinates of compilation errors.


But I wouldn't know too much.


Re: Local templates and alias parameters

2013-06-28 Thread Ali Çehreli

On 06/28/2013 01:04 PM, John Colvin wrote:

void main()
{
 template A(alias a)
 {
 enum A = a.stringof;
 }
 int b;
 string s = A!b;   // Error: template instance A!(b) cannot use
local 'b' as parameter to non-global template A(alias a)
}

Bug or feature?


Popular limitation: :)

  http://d.puremagic.com/issues/show_bug.cgi?id=5710

Ali



Re: Local templates and alias parameters

2013-06-28 Thread John Colvin

On Friday, 28 June 2013 at 23:57:30 UTC, Ali Çehreli wrote:

On 06/28/2013 01:04 PM, John Colvin wrote:

void main()
{
template A(alias a)
{
enum A = a.stringof;
}
int b;
string s = A!b;   // Error: template instance A!(b) cannot 
use

local 'b' as parameter to non-global template A(alias a)
}

Bug or feature?


Popular limitation: :)

  http://d.puremagic.com/issues/show_bug.cgi?id=5710

Ali


I get that it's a problem when they are in entirely 
non-overlapping scopes, but when they are in the same local scope 
it really shouldn't be an error as there's no need for the double 
context pointer. Indeed, in this case there's no need for any 
context pointer at all, it's a purely compile-time manipulation.


I'm tempted to create a separate bug report for this as it's not 
quite the same problem.