Re: Assigning Interface to Object

2011-01-21 Thread Trass3r

Speaking of COM.. has anyone successfully used COM interfaces in D2?


I once tried to create a DDraw proxy dll but I can't remember how good it  
worked.

https://bitbucket.org/trass3r/ddrawproxy


Why we need scope(success) if I can write at the end?

2011-01-21 Thread tamir
or what's the differents between theese two:
void transactionalCreate(string filename) {
  string tempFilename = filename - .fragment;
  scope(success) {
std.file.rename(tempFilename, filename);
  }
  auto f = File(tempFilename, w);
}
and:
void transactionalCreate(string filename) {
  string tempFilename = filename - .fragment;
  auto f = File(tempFilename, w);
  std.file.rename(tempFilename, filename);
}


Type-qualified functions?

2011-01-21 Thread Sean Eskapp
How does one avoid code duplication in a snippet code like this:

class A{}

void foo(const A, void delegate(const A) fn)
{
// some stuff
// ...
// ...
}

void foo(A, void delegate(A) fn)
{
// exact same stuff, with different qualifiers
// ...
// ...
}


Re: sort and shared

2011-01-21 Thread Steven Schveighoffer
On Thu, 20 Jan 2011 21:14:06 -0500, Adam Conner-Sax  
adam_conner_...@yahoo.com wrote:



The following code:

import std.algorithm;

class Foo  {
private:
  int id_;
public:
  shared int id() const { return id_; }
}


static bool compare(in shared(Foo) a, in shared(Foo) b)
{
  return (a.id()  b.id());
}

void main()
{
  shared Foo a,b,c;
  shared(Foo)[] uFooArray = [a,b,c];
  sort!(compare)(uFooArray);
}

fails to compile with

usr/local/src/dmd2/src/phobos/std/conv.d(295): Error: function
object.Object.toString () is not callable using argument types ()


whereas if I just take all the shared away it compiles fine.  I imagine  
that
this is somewhere to do with a string function being called on an  
element of

the array and then there's no shared version of that method.

Is there a fix? Or a different way to call sort?  I can cast away shared  
for
the sort but since in the actual application I have a reason for it,  
that's a

bit worrisome.

Thanks!


This should be fixed in svn.  I encountered a very similar issue, and  
implemented a fix.  This will be fixed in the next release:


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

-Steve


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread spir

On 01/21/2011 02:18 PM, tamir wrote:

or what's the differents between theese two:
void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   scope(success) {
 std.file.rename(tempFilename, filename);
   }
   auto f = File(tempFilename, w);
}
and:
void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   auto f = File(tempFilename, w);
   std.file.rename(tempFilename, filename);
}


I'm a newcomer as well, so take my answer with a good dose of doubt.
There is no difference AFAIK.
scope(success) allows defining end-of-scope process for a given element 
--here the file-- in case of success using an idiom consistent with 
other possible outcomes (read: exit, failure). I find this a Good Thing, 
personly.


Denis
_
vita es estrany
spir.wikidot.com



Re: sort and shared

2011-01-21 Thread Adam Conner-Sax
Thanks!

I tried to apply that patch and rebuild phobos (I changed the file, remade
libphobos2.a, put it in /usr/local/lib).  That worked but I still get my error. 
I
might have done the applying or rebuilding wrong though, especially since once I
did that, even with the casting away of shared, I get some linker errors.

I'll wait for the next release, I guess, and in the meantime cast away shared
and be very afraid.

Is there any way to fix it otherwise by making the elts printable?

Adam


Re: sort and shared

2011-01-21 Thread Steven Schveighoffer
On Fri, 21 Jan 2011 10:04:56 -0500, Adam Conner-Sax  
adam_conner_...@yahoo.com wrote:



Thanks!

I tried to apply that patch and rebuild phobos (I changed the file,  
remade
libphobos2.a, put it in /usr/local/lib).  That worked but I still get my  
error. I
might have done the applying or rebuilding wrong though, especially  
since once I

did that, even with the casting away of shared, I get some linker errors.

I'll wait for the next release, I guess, and in the meantime cast away  
shared

and be very afraid.

Is there any way to fix it otherwise by making the elts printable?


Hm... it's a simple patch.  Maybe there is something different I'm not  
seeing.


I'll see if I can reproduce with my build.

-Steve


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread Steven Schveighoffer

On Fri, 21 Jan 2011 08:18:15 -0500, tamir tamir@gmail.com wrote:


or what's the differents between theese two:
void transactionalCreate(string filename) {
  string tempFilename = filename - .fragment;
  scope(success) {
std.file.rename(tempFilename, filename);
  }
  auto f = File(tempFilename, w);
}
and:
void transactionalCreate(string filename) {
  string tempFilename = filename - .fragment;
  auto f = File(tempFilename, w);
  std.file.rename(tempFilename, filename);
}


Look at any linux kernel driver code, and you will see goto used in a very  
structured way:


if(open_port() == -1) goto FAILURE;
if(create_device() == -1) goto FAILURE2;
if(init_device() == -1) goto FAILURE3;
return SUCCESS;
FAILURE3:
destroy_device();
FAILURE2:
close_port();
FAILURE:
return ERROR;

Basically, this idiom of building a stack of resources that must be  
destroyed in reverse order on failure is very common in a lot of code.


scope(failure) or scope(exit) takes care of these tasks without using  
gotos, and by reducing the structure required to implement such things:


open_port(); // throws exception on failure
scope(failure) close_port();
create_device();
scope(failure) destroy_device();
init_device();


Now, scope(success) I believe is less common to require, but it still has  
the benefit of allowing you to group your dealings with a certain item in  
one spot.


Imagine your code looks more like this:

void transactionalCreate(string filename) {
   string tempFilename = filename ~ .fragment;
   auto f = File(tempFilename, w);
   ...
   // lots of code
   ...
   std.file.rename(tempFilename, filename);
}

It might be easier to follow code that says I'm going to create a temp  
file, and then at the end, if everything works, I'm going to copy it over  
the original in one paragraph, rather than have to read the whole  
function to see what happens to the temp file.


It's also easier to write, you just write the scope(success) and never  
have to worry about special circumstances.


You don't have to repeat yourself if you have multiple return statements.

You can also return something from a function that may throw an exception  
without having this silly structure:


auto x = fnImGoingToReturnValueOf();
std.file.rename(tempFilename, filename);
return x;

You can just do

return fnImGoingToReturnValueOf();

and scope(success) will ensure your renaming is done properly only if that  
function doesn't throw.


-Steve


Re: sort and shared

2011-01-21 Thread Steven Schveighoffer
On Fri, 21 Jan 2011 10:09:18 -0500, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Fri, 21 Jan 2011 10:04:56 -0500, Adam Conner-Sax  
adam_conner_...@yahoo.com wrote:



Thanks!

I tried to apply that patch and rebuild phobos (I changed the file,  
remade
libphobos2.a, put it in /usr/local/lib).  That worked but I still get  
my error. I
might have done the applying or rebuilding wrong though, especially  
since once I
did that, even with the casting away of shared, I get some linker  
errors.


I'll wait for the next release, I guess, and in the meantime cast away  
shared

and be very afraid.

Is there any way to fix it otherwise by making the elts printable?


Hm... it's a simple patch.  Maybe there is something different I'm not  
seeing.


I'll see if I can reproduce with my build.


Compiled your code and ran it without error (well, got a segfault because  
the elements are all null), so I think maybe the patch wasn't applied  
properly on your machine.


I guess all I can recommend is either to get phobos from svn or wait for  
the next release.


-Steve


Re: Type-qualified functions?

2011-01-21 Thread Steven Schveighoffer
On Fri, 21 Jan 2011 09:08:58 -0500, Sean Eskapp eatingstap...@gmail.com  
wrote:



How does one avoid code duplication in a snippet code like this:

class A{}

void foo(const A, void delegate(const A) fn)
{
// some stuff
// ...
// ...
}

void foo(A, void delegate(A) fn)
{
// exact same stuff, with different qualifiers
// ...
// ...
}


templates:

void foo(T)(T, void delegate(T) fn)
{
}

This parameterizes foo based on T, which could be A, const A, or int, or  
whatever works to compile the function.


You could further restrict which templates can be instantiated with a  
template constraint (say for instance, to restring foo to only instantiate  
when T is A or const(A) ).


-Steve


Re: Source code annotations alla Java

2011-01-21 Thread Ary Manzana

On 1/20/11 5:48 PM, Jacob Carlborg wrote:

On 2011-01-20 21:34, Steven Schveighoffer wrote:

On Thu, 20 Jan 2011 15:03:55 -0500, Jacob Carlborg d...@me.com wrote:


On 2011-01-20 19:18, Steven Schveighoffer wrote:

On Thu, 20 Jan 2011 13:07:58 -0500, Jacob Carlborg d...@me.com wrote:


On 2011-01-20 15:02, Steven Schveighoffer wrote:

On Thu, 20 Jan 2011 08:47:28 -0500, Justin Johansson j...@nospam.com
wrote:


Not long ago the Java Language people introduced the idea of
annotations together with an annotation processing tool (apt).

Now perhaps the idea of source code annotations is not actually a
Java
invention per se, however for someone learning D is there any
equivalent idiom [of Java annotations] in the D language?


Haven't used Java since they added annotations, but I think they are
like C# attributes?

In any case, D has an annotation syntax like:

@property

But I think at the moment, annotations have no custom ability. Only
compiler-defined annotations are allowed. This may change in the
future,
but probably not short-term. FWIW, I think we need a much richer
runtime-reflection capability before we can use custom annotations to
any great effect.

-Steve


I would rather formulate it like: currently D has a syntax for
keywords that are similar to Java annotations.


I don't think it's the same thing. Keywords are not allowed to be used
anywhere else, even for things that would parse properly were they not
keywords. They are anchors for the parser to determine where it is. In
contrast, a compiler-defined annotation is parsed just the same as a
custom one, it's just that the meaning is predefined.

For example, you can legally do:

int property;

without error, but this won't even get past the parsing stage:

int struct;

-Steve


I assume you meant int @property;?


No. I meant int property;


Of course that would work, isn't that like saying this won't work:

int struct_; // ?


A keyword is specifically not allowed where the grammar would otherwise
allow it. A symbol isn't allowed to have @ in it, so this naturally
prevents a conflict. I realize the poor example, but it's definitely not
a keyword. Otherwise, it would be listed here:
http://www.digitalmars.com/d/2.0/lex.html#keyword (actually, are
annotations part of the lexical grammar there?).

It's more like Object, which is not a keyword, but you aren't allowed to
use it to mean anything besides what it means.

The end result is, it fails if you use it in the wrong place, but the
keyword status makes it fail at the parsing stage. I am not a compiler
writer, so I'm talking a bit from my ass here.

-Steve


Ok, maybe you're right. I'm pretty sure, as you say, that a keyword in
the wrong place would fail during parsing. But I don't know where a
misplaced annotation/attribute would fail.



Jacob is right here.

This, as you say, fails:

int struct;

And also this fails:

int @property;

So yes, currently @property is just a keyword with a prepended @.

Annotations in Java anc C# can have arguments. That is not the case in 
D. For example, as it is said in DIP6, you could have:


@extern('C')
void someFunc();

instead of having extern a keyword and thus being unable to use it for 
identifiers.


Re: Type-qualified functions?

2011-01-21 Thread Sean Eskapp

 templates:

 void foo(T)(T, void delegate(T) fn)
 {
 }

 This parameterizes foo based on T, which could be A, const A, or int, or
 whatever works to compile the function.

What if the parameters are more general, for instance the first parameter is
always a Foo, the second is a delegate which takes a Foo.Bar, but they're always
qualified the same way?


Re: Source code annotations alla Java

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 12:36:23 Ary Manzana wrote:
 On 1/20/11 5:48 PM, Jacob Carlborg wrote:
  On 2011-01-20 21:34, Steven Schveighoffer wrote:
  On Thu, 20 Jan 2011 15:03:55 -0500, Jacob Carlborg d...@me.com wrote:
  On 2011-01-20 19:18, Steven Schveighoffer wrote:
  On Thu, 20 Jan 2011 13:07:58 -0500, Jacob Carlborg d...@me.com wrote:
  On 2011-01-20 15:02, Steven Schveighoffer wrote:
  On Thu, 20 Jan 2011 08:47:28 -0500, Justin Johansson j...@nospam.com
  
  wrote:
  Not long ago the Java Language people introduced the idea of
  annotations together with an annotation processing tool (apt).
  
  Now perhaps the idea of source code annotations is not actually a
  Java
  invention per se, however for someone learning D is there any
  equivalent idiom [of Java annotations] in the D language?
  
  Haven't used Java since they added annotations, but I think they are
  like C# attributes?
  
  In any case, D has an annotation syntax like:
  
  @property
  
  But I think at the moment, annotations have no custom ability. Only
  compiler-defined annotations are allowed. This may change in the
  future,
  but probably not short-term. FWIW, I think we need a much richer
  runtime-reflection capability before we can use custom annotations
  to any great effect.
  
  -Steve
  
  I would rather formulate it like: currently D has a syntax for
  keywords that are similar to Java annotations.
  
  I don't think it's the same thing. Keywords are not allowed to be used
  anywhere else, even for things that would parse properly were they not
  keywords. They are anchors for the parser to determine where it is. In
  contrast, a compiler-defined annotation is parsed just the same as a
  custom one, it's just that the meaning is predefined.
  
  For example, you can legally do:
  
  int property;
  
  without error, but this won't even get past the parsing stage:
  
  int struct;
  
  -Steve
  
  I assume you meant int @property;?
  
  No. I meant int property;
  
  Of course that would work, isn't that like saying this won't work:
  
  int struct_; // ?
  
  A keyword is specifically not allowed where the grammar would otherwise
  allow it. A symbol isn't allowed to have @ in it, so this naturally
  prevents a conflict. I realize the poor example, but it's definitely not
  a keyword. Otherwise, it would be listed here:
  http://www.digitalmars.com/d/2.0/lex.html#keyword (actually, are
  annotations part of the lexical grammar there?).
  
  It's more like Object, which is not a keyword, but you aren't allowed to
  use it to mean anything besides what it means.
  
  The end result is, it fails if you use it in the wrong place, but the
  keyword status makes it fail at the parsing stage. I am not a compiler
  writer, so I'm talking a bit from my ass here.
  
  -Steve
  
  Ok, maybe you're right. I'm pretty sure, as you say, that a keyword in
  the wrong place would fail during parsing. But I don't know where a
  misplaced annotation/attribute would fail.
 
 Jacob is right here.
 
 This, as you say, fails:
 
 int struct;
 
 And also this fails:
 
 int @property;
 
 So yes, currently @property is just a keyword with a prepended @.
 
 Annotations in Java anc C# can have arguments. That is not the case in
 D. For example, as it is said in DIP6, you could have:
 
 @extern('C')
 void someFunc();
 
 instead of having extern a keyword and thus being unable to use it for
 identifiers.

No. No attributes are keywords. The reasoning is simple. A keyword is a word 
that would be a valid identifier but isn't, because the language treats it as 
special. @ is not a valid part of an identifier. So, @property can't be a 
keyword. And property certainly isn't a keyword, since you _can_ use it as an 
identifier, so it isn't a keyword with @ prepended on either.

True, @property is treated as a special symbol by the compiler, and I don't 
expect that it really treats it like an attribute with the name property (which 
it will pretty much have to do if we ever get user-defined attributes), but 
definitely isn't a keyword, because it was never possible for it to be a valid 
identifier in the first place.

- Jonathan M Davis


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 05:18:15 tamir wrote:
 or what's the differents between theese two:
 void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   scope(success) {
 std.file.rename(tempFilename, filename);
   }
   auto f = File(tempFilename, w);
 }
 and:
 void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   auto f = File(tempFilename, w);
   std.file.rename(tempFilename, filename);
 }

scope(success) will be run _regardless_ of how you leave that scope (except for 
if an exepction is thrown). So, you can have one line with scope(success) and 
multiple return statements or breaks or continues or whatnot, and that 
scope(success) statement will be run in all cases. If you didn't use 
scope(success), then you'd have to duplicate that code at every point that the 
scope could be exited successfully.

Now, if there's only one way to exit a particular scope successfully, then 
scope(success) is less useful. However, even in cases like that it can improve 
code maintanence and readability when it comes to stuff like resources. For 
instance, if you were to open a file at the beginning of a function, having a 
scope(success) statement immediately following it makes it clear that closing 
the function has been taken care of, whereas without the scope statement, you'd 
have to worry about putting it at the end of the function separate from where 
the file was opened. Having them together makes the code clearer. Now, a file 
isn't the best example, since you'd want success(exit) in that case, and the 
File struct std.stdio deals with it anyway through its destructor, but the 
example should give you the basic idea.

- Jonathan M Davis


toString why not const

2011-01-21 Thread Tom
Hi, I'm trying to override Object's toString. I've noted it isn't a 
const method, namely:


string toString() const;

This cause me troubles when using it on a const reference.

Shouldn't it be const?

Thanks,
Tom;


Re: Type-qualified functions?

2011-01-21 Thread Jesse Phillips
Sean Eskapp Wrote:

 
  templates:
 
  void foo(T)(T, void delegate(T) fn)
  {
  }
 
  This parameterizes foo based on T, which could be A, const A, or int, or
  whatever works to compile the function.
 
 What if the parameters are more general, for instance the first parameter is
 always a Foo, the second is a delegate which takes a Foo.Bar, but they're 
 always
 qualified the same way?

Their is probably better ways to do this...

void main() {
foo(new Foo, (int) { });
}

void foo(T, U)(T t, void delegate(U) fn) 
   if(__traits(compiles, fn(t.bar))) {
}

class Foo {
int bar() {
return 0;
}
}


Re: toString why not const

2011-01-21 Thread Jesse Phillips
Tom Wrote:

 Hi, I'm trying to override Object's toString. I've noted it isn't a 
 const method, namely:
 
 string toString() const;
 
 This cause me troubles when using it on a const reference.
 
 Shouldn't it be const?
 
 Thanks,
 Tom;

Phobos hasn't become very const aware. There have been bugs and things 
preventing such an effort. So I do believe it should be const, but between the 
other priorities, and possible signature change for toString, it isn't done yet.


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread Andrej Mitrovic
When there are multiple calls that can fail, and where I have to do
clean-up code in a certain order and under certain conditions I use
scope(exit). For example:

import std.stdio;
import std.exception;

void main()
{
foo();
}

enum NoError = true;

bool Initialize() { return true; }
bool Start() { return false; }

void Terminate() { writeln(Terminated.); }
void Stop() { writeln(Stopped.); }

void foo()
{
auto error = Initialize();
enforce(error == NoError, new Exception(Couldn't initialize));
scope(exit)
Terminate(); // call Terminate only if Initialize was successful

error = Start();
enforce(error == NoError, new Exception(Couldn't start));
scope(exit)
Stop(); // call Stop only if Start was successful
}

If I change the first scope to scope(success), Terminate will not be
called if the call to Start() failed. This can be bad in cases where
Terminate would release some hardware resource (it can lock up an app,
for example). scope statements won't be ran if an exception is throwed
before that scope statement is reached. So, that's one thing to keep
in mind.


Re: toString why not const

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 13:02:56 Tom wrote:
 Hi, I'm trying to override Object's toString. I've noted it isn't a
 const method, namely:
 
 string toString() const;
 
 This cause me troubles when using it on a const reference.
 
 Shouldn't it be const?
 
 Thanks,
 Tom;

It's a long-standing bug: http://d.puremagic.com/issues/show_bug.cgi?id=1824

In theory, the issues with const in the compiler and in Phobos will be focused 
on and sorted out not too long after the 64-bit port of dmd has been finished, 
but regardless, it's still an outstanding issue and definitely annoying.

Also, be warned that (due to another bug) you _can't_  declare a struct's 
toString to be const (it must be _exactly_ string toString() { ... }). You 
_can_, however, override toString() to be const on classes, though how much 
good 
it really does you, I'm not sure. Hopefully all that stuff will be sorted out 
semi-soon.

- Jonathan M Davis


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 14:49:44 Andrej Mitrovic wrote:
 When there are multiple calls that can fail, and where I have to do
 clean-up code in a certain order and under certain conditions I use
 scope(exit). For example:
 
 import std.stdio;
 import std.exception;
 
 void main()
 {
 foo();
 }
 
 enum NoError = true;
 
 bool Initialize() { return true; }
 bool Start() { return false; }
 
 void Terminate() { writeln(Terminated.); }
 void Stop() { writeln(Stopped.); }
 
 void foo()
 {
 auto error = Initialize();
 enforce(error == NoError, new Exception(Couldn't initialize));
 scope(exit)
 Terminate(); // call Terminate only if Initialize was successful
 
 error = Start();
 enforce(error == NoError, new Exception(Couldn't start));
 scope(exit)
 Stop(); // call Stop only if Start was successful
 }
 
 If I change the first scope to scope(success), Terminate will not be
 called if the call to Start() failed. This can be bad in cases where
 Terminate would release some hardware resource (it can lock up an app,
 for example). scope statements won't be ran if an exception is throwed
 before that scope statement is reached. So, that's one thing to keep
 in mind.

That's why you choose the appropriate version of scope(). And while 
scope(success) is still definitely useful, it's far less useful than 
scope(failure) or scope(exit).

- Jonathan M Davis


Re: Can/should spawn work with functions that return?

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 14:12:18 Andrej Mitrovic wrote:
 import std.stdio;
 import std.concurrency;
 
 void foo(int var)
 {
 }
 
 bool bar(int var)
 {
 return true;
 }
 
 void barWrapper(int var)
 {
 bar(var);
 }
 
 void main()
 {
 spawn(foo, 1);
 spawn(barWrapper, 1);
 spawn(bar, 1);
 }
 
 Errors:
 testSpawn.d(24): Error: template std.concurrency.spawn(T...) does not match
 any function template declaration testSpawn.d(24): Error: template
 std.concurrency.spawn(T...) cannot deduce template function from argument
 types !()(bool function(int var),int)
 
 Of course, when my foreground thread spawns a background thread it doesn't
 wait for it to finish, so assigning a return value doesn't make much
 sense. I can see how that can be an error (in any case that error message
 above is not very informative).
 
 But what if I want to spawn a thread with an existing function 'bar' that
 has side-effects, but I'm not interested in its return value even though
 it has one?
 
 Right now I'm forced to either:
 a) remove any returns from 'bar' and change it to a void function, which
 can be really complicated if other functions already depend on its return
 value, or b) write a new void function that can be called with spawn(),
 which internally calls 'bar' but discards it's value (so basically it's a
 wrapper). This is what I've done in the example code.
 
 So, is spawning threads on functions that return banned by design? I
 couldn't read about this anywhere on the D site or TDPL.

The current design does not give you any way to access a return value from a 
spawned function, even if it allowed you to use such a function. And given that 
fact, it really doesn't make sense conceptually to have spawn work with 
non-void 
functions. I'm not sure that there are any technical barriers to it however. 
Still, as it stands, if a function isn't _designed_ to be called with spawn, I 
don't see what good it generally does you. If it's not sending messages to the 
parent thread, then what's the point of calling it? You can't _have_ side 
effects 
unless the function alters a shared global.

I do have an enhancement request related to getting return values from spawned 
functions though:

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

- Jonathan M Davis


Re: toString why not const

2011-01-21 Thread bearophile
Jesse Phillips:

 So I do believe it should be const, but between the other priorities, and 
 possible signature change for toString, it isn't done yet.

There also the idea of introducing the writeTo() standard method, that's neat 
:-)

Bye,
bearophile


Re: Can/should spawn work with functions that return?

2011-01-21 Thread Andrej Mitrovic
Sorry, I should be careful with the word side-effects. What I meant
was the newly spawned thread does its own job that the main thread
doesn't care much about. It doesn't touch main's state or any shared
variables. It does some work other than return a value. But the
function I wanted the new thread to execute happened to have a return
value, so I couldn't spawn the thread.

Really, the issue is that sometimes I have to convert C code to D and
concurrency is dealt with differently in the two languages, not to
mention the fact that I have next to no experience with using threads
in any language (but I'm forced to use them in some cases).

So, sometimes I'll ask silly questions because I'm very new to this,
but hopefully I'll learn a thing or two. I do enjoy your long and
informative responses though, Jonathan. :)


Re: Why we need scope(success) if I can write at the end?

2011-01-21 Thread spir

On 01/21/2011 09:56 PM, Jonathan M Davis wrote:

On Friday, January 21, 2011 05:18:15 tamir wrote:

or what's the differents between theese two:
void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   scope(success) {
 std.file.rename(tempFilename, filename);
   }
   auto f = File(tempFilename, w);
}
and:
void transactionalCreate(string filename) {
   string tempFilename = filename - .fragment;
   auto f = File(tempFilename, w);
   std.file.rename(tempFilename, filename);
}


scope(success) will be run _regardless_ of how you leave that scope (except for
if an exepction is thrown). So, you can have one line with scope(success) and
multiple return statements or breaks or continues or whatnot, and that
scope(success) statement will be run in all cases. If you didn't use
scope(success), then you'd have to duplicate that code at every point that the
scope could be exited successfully.

Now, if there's only one way to exit a particular scope successfully, then
scope(success) is less useful. However, even in cases like that it can improve
code maintanence and readability when it comes to stuff like resources. For
instance, if you were to open a file at the beginning of a function, having a
scope(success) statement immediately following it makes it clear that closing
the function has been taken care of, whereas without the scope statement, you'd
have to worry about putting it at the end of the function separate from where
the file was opened. Having them together makes the code clearer. Now, a file
isn't the best example, since you'd want success(exit) in that case, and the
File struct std.stdio deals with it anyway through its destructor, but the
example should give you the basic idea.

- Jonathan M Davis


I just realised scope(success) can avoid 2 kinds of bugs, one common, 
one naughty:
* at first coding time, simply forgetting releasing resources (one 
thinks at that when accessing it, but then, it's easy to forget), or any 
other exit task
* at maintenance time, opening a new exit point for a function (new 
return), and forgetting the exit task there


Denis
_
vita es estrany
spir.wikidot.com



const-typed class does not have const members

2011-01-21 Thread Sean Eskapp
The following code yields results as commented.

import std.stdio;

class A
{
int b;
}

void main()
{
const A a = new A;
writeln(typeof(a).stringof); // const(A)
writeln(typeof(a.b).stringof); // const(int)

writeln((const A).stringof); // const(A)
writeln(typeof((const A).b).stringof); // int
}

Given this information, how do I work around this in templates? I'd like a
template which can type its params based on members of T, for instance:

void foo(T)(T x, typeof(T.member) y)

but this will yield non-const second parameters even if T is const. Help 
anybody?


Re: const-typed class does not have const members

2011-01-21 Thread Ali Çehreli

Sean Eskapp wrote:
 The following code yields results as commented.

 import std.stdio;

 class A
 {
int b;
 }

 void main()
 {
const A a = new A;
writeln(typeof(a).stringof); // const(A)
writeln(typeof(a.b).stringof); // const(int)

writeln((const A).stringof); // const(A)
writeln(typeof((const A).b).stringof); // int
 }

 Given this information, how do I work around this in templates? I'd 
like a

 template which can type its params based on members of T, for instance:

 void foo(T)(T x, typeof(T.member) y)

 but this will yield non-const second parameters even if T is const. 
Help anybody?


Ironically, parameter list is not a useful place to constraint the 
parameter types. At the least, you probably want some conversions. If 
so, would this work:


import std.traits;

void foo(T, M)(T x, M m)
if (isImplicitlyConvertible!(M, typeof(T.member)))
{}

class C
{
int member;
}

void main()
{
auto c = new C;
foo(c, 42);
}

If you want to ensure that the member is assignable, you can try this:

import std.traits;

void foo(T, M)(T x, M m)
if (__traits(compiles, { x.member = m; }))
{}

class C
{
int member;
}

void main()
{
const auto c = new C;  // -- compilation error
foo(c, 42);
}

But the error message is only somewhat helpful:

deneme.d(26369): Error: template deneme.foo(T,M) if 
(__traits(compiles,delegate ()

{
x.member = m;
}
)) does not match any function template declaration
deneme.d(26369): Error: template deneme.foo(T,M) if 
(__traits(compiles,delegate ()

{
x.member = m;
}
)) cannot deduce template function from argument types !()(const(C),int)

Ali


Re: Can/should spawn work with functions that return?

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 15:23:37 Andrej Mitrovic wrote:
 Sorry, I should be careful with the word side-effects. What I meant
 was the newly spawned thread does its own job that the main thread
 doesn't care much about. It doesn't touch main's state or any shared
 variables. It does some work other than return a value. But the
 function I wanted the new thread to execute happened to have a return
 value, so I couldn't spawn the thread.
 
 Really, the issue is that sometimes I have to convert C code to D and
 concurrency is dealt with differently in the two languages, not to
 mention the fact that I have next to no experience with using threads
 in any language (but I'm forced to use them in some cases).
 
 So, sometimes I'll ask silly questions because I'm very new to this,
 but hopefully I'll learn a thing or two. I do enjoy your long and
 informative responses though, Jonathan. :)

Well, I'd suggest just wrapping the function call in a lambda, unless spawn 
doesn't like that for some reason. I suppose that spawn could be made take 
functions with return values, but it's not generally something that you'd do, 
and it _is_ pretty easy to wrap such functions, so it seems to me like it's 
probably better as it is - though I can see why it would be annoying if you 
kept 
needing to spawn functions with return values. Still, that makes me wonder 
about 
what you're doing. I guess that you could be doing I/O or somethnig, but you 
certainly can't be talking back to the parent thread without having written 
things that way (in which case, you'd have made the spawned function void). You 
could always put in an enhancement request, though it does seem wrong to me 
(conceptually-speaking, if nothing else) to have a spawned function with a 
return value.

- Jonathan M Davis