Re: DConf 2013 Closing Keynote: Quo Vadis by Andrei Alexandrescu

2013-07-02 Thread Joseph Rushton Wakeling

On Sunday, 30 June 2013 at 03:29:06 UTC, Walter Bright wrote:

On 6/29/2013 5:08 AM, Joseph Rushton Wakeling wrote:
True, distribution was mainly by physical mail. There was some 
via BBS's and Usenet, but these were severely limited by 
bandwidth.


I'd receive bug reports by fax, paper listings, and mailed 
floppies.



This was also the heyday of the BBC Micro in UK schools, and I 
remember well the shelves full of books of sample programs in BBC 
Basic. We had lots of fun typing them up, working out how they 
worked, and then twisting them to our more evil designs.


Re: DConf 2013 Closing Keynote: Quo Vadis by Andrei Alexandrescu

2013-07-02 Thread Joseph Rushton Wakeling

On Monday, 1 July 2013 at 21:20:39 UTC, Walter Bright wrote:

On 7/1/2013 2:04 PM, Brad Roberts wrote:
Actually, Boost was specifically chosen because it didn't 
require attribution
when redistributing. If BSD hadn't had that clause we probably 
would be using it

instead.


That was indeed another important reason for it. But we were 
well aware of and approved of the idea that people could take 
it and make closed source versions.


It was always clear (and logical) to me why the core libraries 
were permissively licensed, but the 
no-need-to-give-attribution-for-non-source-distribution feature 
was a subtlety I hadn't considered before.


Re: DConf 2013 Closing Keynote: Quo Vadis by Andrei Alexandrescu

2013-07-02 Thread John Colvin

On Tuesday, 2 July 2013 at 05:21:35 UTC, Joakim wrote:

On Monday, 1 July 2013 at 21:29:21 UTC, John Colvin wrote:

On Monday, 1 July 2013 at 17:45:59 UTC, Joakim wrote:
I wouldn't call closing source that they legally allowed to 
be closed antisocial.  I'd call their contradictory, angry 
response to what their license permits antisocial. :)


Just because you're doing something legal doesn't mean you're 
not being antisocial.
Read my previous post.  Of course it's possible for a license 
to technically allow something but for the authors to 
disapprove of it, not that its antisocial to simply do 
something they disapprove of.  But, as I said earlier, the BSD 
crowd does not publicly broadcast that they disapprove of 
closing source.  In fact, they will occasionally link to press 
releases about contributions back from corporations who closed 
the source.


For people using the BSD license to then get mad when yet 
another person comes along to close source is the only 
antisocial behavior I'm seeing here.  It'd be one thing if 
they publicly said that while the BSD license allows closing 
source, they're against it.  Feel free to provide such a public 
statement, you won't find it.  It's only after you talk to them 
privately about closing source that you realize how many of 
them are against it.


As I've said repeatedly, I don't much care that their behavior 
is so antisocial, :) as long as its legal to close source.  
But it is pretty funny to cast that tag on somebody else, who 
is simply doing what their license allows and what their press 
releases trumpet.


It's a pretty psychopathic attitude to conflate legality and 
morality, it's effectively saying I have the moral right to 
do whatever I can get away with
On the contrary, it's a pretty psychopathic attitude to make 
such claims about morality when


1. nobody was talking about morality

2. the BSD crowd doesn't publicly talk about their problems 
with closing source either, whether they think it's immoral or 
antisocial or whatever.


This is all a bit moot as I was making a general point, not 
specifically related to BSD. However, in their case, I think it 
is perfectly fine that some don't like closed source personally, 
but as a group they decide to endorse it. A group where everyone 
is forced to agree on everything isn't an organisation, it's a 
cult.


I think what I'm really trying to say is this:

A license is a description of what you will *allow*, not what you 
*want*.
I personally like to take in to account what people *want* me to 
do, not just what they will *allow* me to do.


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread John Colvin

On Tuesday, 2 July 2013 at 09:11:44 UTC, Michal Minich wrote:

Sorry for posting to announce.


In future please post these questions to digitalmars.D.learn

The reason you can't implicitly convert a string to a char[] is 
because string is an alias to immutable(char)[]


Therefore, you would be providing a mutable window to immutable 
data, which is disallowed unless you *explicitly* ask for it (see 
below).


You can explicitly cast string to char[], but it is undefined 
behaviour to modify the contents of the result (i.e. don't cast 
away immutable unless you absolutely have to and even then be 
very very careful).


Re: Announcing bottom-up-build - a build system for C/C++/D

2013-07-02 Thread eles

On Monday, 1 July 2013 at 03:26:22 UTC, Graham St Jack wrote:

On Thu, 27 Jun 2013 22:49:41 +, Graham St Jack wrote:
Fixed the problem, and also:

* split bub.d up into several smaller files,

* added a Makefile to bootstrap the building of bub, and

* added a bub.cfg and Bubfile as a trivial example of how to 
use bub.


Please add an install: target to the Makefile.

Thank you.


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Regan Heath
On Tue, 02 Jul 2013 12:33:14 +0100, Michal Minich  
michal.min...@gmail.com wrote:



On Tuesday, 2 July 2013 at 11:29:05 UTC, Dicebot wrote:

On Tuesday, 2 July 2013 at 11:26:59 UTC, Michal Minich wrote:
But ... I'm asking only about implicit conversion of string literal,  
not arbitrary expressions of string type.


char[] str = abc.dup;


Thanks, that is workaround I didn't know about.

I'm really interested about reasons why it doesn't works (without  
dup/cast). At some point it had to be disabled. But I really cannot find  
a reason why that would be useful.


It is done for performance reasons.  On UNIX the compiler will put the  
literal abc into read only memory.  It could/should do the same on  
windows but doesn't yet (I believe).


So, the compiler is treating them as such, by giving them the type  
immutable(char)[] (AKA string).


And, the spec should, if it doesn't, define string literals to be  
immutable.


In older versions of DMD we didn't have string AKA immutable(char), in  
fact at one point we didn't have immutable at all.  At that time, abc  
was typed as char[] and people on UNIX systems ran headlong into an access  
violation attempting to write to ROM :p


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread John Colvin

On Tuesday, 2 July 2013 at 11:26:59 UTC, Michal Minich wrote:

On Tuesday, 2 July 2013 at 10:09:10 UTC, John Colvin wrote:
The reason you can't implicitly convert a string to a char[] 
is because string is an alias to immutable(char)[]


Therefore, you would be providing a mutable window to 
immutable data, which is disallowed unless you *explicitly* 
ask for it (see below).

would be - might be


no, would be is correct. char is mutable, immutable(char) is 
not. By definition char[] is a mutable view of data, 
immutable(char)[] is not.




You can explicitly cast string to char[], but it is undefined 
behaviour to modify the contents of the result


ok

 (i.e. don't cast
away immutable unless you absolutely have to and even then be 
very very careful).


This is not correct. You should can not cast when you 
'absolutely have to' but when you can prove by means not 
available to compiler that the data being casted are in fact 
mutable. And the 'proving' of this is what you should be 
careful about.


Eek... no, unless i'm misunderstanding you or you made a typo, 
that's not the case at all.


Don't mutate anything that has a live (and used?)* immutable 
reference to it.


Just because the data was mutable before being cast to immutable, 
doesn't mean you can just cast away immutable and mutate it.



Or, alternatively presented:

You can cast to or away from immutable when you can prove by any 
means that the data being casted are not mutated through any 
reference after the creation of or before the final use of any 
immutable references.


Erring on the safe side, you might want to wait for the immutable 
references to be actually dead and gone before any mutation.



* Would like some clarification on whether it is the usage of the 
immutable reference or the lifetime that counts, if anyone knows 
for sure.


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Michal Minich

On Tuesday, 2 July 2013 at 13:07:40 UTC, Regan Heath wrote:
It is done for performance reasons.  On UNIX the compiler will 
put the literal abc into read only memory.  It could/should 
do the same on windows but doesn't yet (I believe).


So, the compiler is treating them as such, by giving them the 
type immutable(char)[] (AKA string).


And, the spec should, if it doesn't, define string literals to 
be immutable.




Ok I understand. What I did as a first thing when I get error on 
char[] x = a was char x = cast(char[])a, Which was 
obviously incorrect - as the a was/should be placed in rom. So 
if this expression is allays wrong - casting string literal to 
mutable, then compiler should emit an error on this (If one 
implementation (dmd/win) makes this valid, it still doesn't mean 
compiler should honor implementation over specification - amusing 
it is specified that strings go into rom...)


Also, given you explanation, I see it as good to type auto x = 
a as string, but give explicit notation char[] x = a - I 
don't see reason to not allow string literal to be typed as both 
char[] and string at the same time, and convert to char[] - and 
also place in ram, if explicitly asked.


The only reason that comes now to mi mind is when working with 
old code base - before auto and immutable(char)[] .. the code had 
to use char[] x = a, but these must be all eliminated by now


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Dicebot

On Tuesday, 2 July 2013 at 13:33:10 UTC, Michal Minich wrote:
Ok I understand. What I did as a first thing when I get error 
on char[] x = a was char x = cast(char[])a, Which was 
obviously incorrect - as the a was/should be placed in rom. 
So if this expression is allays wrong - casting string literal 
to mutable, then compiler should emit an error on this


explicit cast means a order from a programmer type system, I 
know what I am doing, don't even try to bother me. You should 
never use casts to simply suppress errors (unless absolutely 
sure) in the very first place.


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Regan Heath
On Tue, 02 Jul 2013 14:33:09 +0100, Michal Minich  
michal.min...@gmail.com wrote:



On Tuesday, 2 July 2013 at 13:07:40 UTC, Regan Heath wrote:
It is done for performance reasons.  On UNIX the compiler will put the  
literal abc into read only memory.  It could/should do the same on  
windows but doesn't yet (I believe).


So, the compiler is treating them as such, by giving them the type  
immutable(char)[] (AKA string).


And, the spec should, if it doesn't, define string literals to be  
immutable.




Ok I understand. What I did as a first thing when I get error on char[]  
x = a was char x = cast(char[])a, Which was obviously incorrect -  
as the a was/should be placed in rom. So if this expression is allays  
wrong - casting string literal to mutable, then compiler should emit an  
error on this (If one implementation (dmd/win) makes this valid, it  
still doesn't mean compiler should honor implementation over  
specification - amusing it is specified that strings go into rom...)


As Dicebot has replied, cast() is the mechanism the programmer uses to  
force the compiler to do what s/he wants regardless of what it thinks.   
The compiler assumes that if cast() is used that the programmer knows what  
they're doing.  Only use cast() if you have no other option.


In this simple case, the compiler could detect the error, or as you say  
below take the cast(char[]) as a hint to place the a in RAM instead.   
But, 99.9% of cases are more complex than this simple one, so the  
cost/benefit of detecting the error make it very low priority, perhaps  
never to be implemented.  Likewise for the place in RAM idea.  Both/either  
would be nice, but neither is necessary now provide a lot of benefit.


Also, given you explanation, I see it as good to type auto x = a as  
string, but give explicit notation char[] x = a - I don't see reason  
to not allow string literal to be typed as both char[] and string at the  
same time, and convert to char[] - and also place in ram, if explicitly  
asked.


To explicitly place a in RAM you would write
  char[] x = a.dup;

Or:
  char[] x = new char[1];
  x[0] = 'a';

The only reason that comes now to mi mind is when working with old code  
base - before auto and immutable(char)[] .. the code had to use char[] x  
= a, but these must be all eliminated by now


Old code using char[] x = a was technically invalid (it just happened to  
run ok on windows, or linux if no mutation was done) and will now error as  
such.


For old code raising this error the correct solution ..
 - if mutable is required is to add .dup.
 - if mutable is not required is to replace char[] with string or  
auto.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Michal Minich

On Tuesday, 2 July 2013 at 13:39:36 UTC, Dicebot wrote:

On Tuesday, 2 July 2013 at 13:33:10 UTC, Michal Minich wrote:
Ok I understand. What I did as a first thing when I get error 
on char[] x = a was char x = cast(char[])a, Which was 
obviously incorrect - as the a was/should be placed in rom. 
So if this expression is allays wrong - casting string literal 
to mutable, then compiler should emit an error on this


explicit cast means a order from a programmer type system, I 
know what I am doing, don't even try to bother me. You should 
never use casts to simply suppress errors (unless absolutely 
sure) in the very first place.


I completely agree.

The other thing is, for the less aware programmers, a warning on 
non-linux and a error on linux might be nice. As this cast (on 
linux), will _allways_ result in undefined behavior. It is 
something compiler can  easily tell, and advice use .dup instead 
of cast...


Re: Why implicit conversion of string literal to char[] does not works?

2013-07-02 Thread Maxim Fomin

On Tuesday, 2 July 2013 at 09:10:33 UTC, Michal Minich wrote:

void main ()
{
char[] str = abc;
// Error: cannot implicitly convert expression (abc)
// of type string to char[]
}

I thought there is no harm in that?


char[] str = ['a', 'b', 'c'];

This will only allocate once without placing data in object file. 
This is caused by obsolete Cism moved into modern language to 
treat string literals as constant objects (perhaps reasoning was 
made in 1980s in memory constraints of those times).


Ideally char[] str = abc should be as normal as int[] arr = 
[0,1,2] allowing to play with data as much as you wish.


Re: Automatic typing

2013-07-02 Thread Andrei Alexandrescu

On 7/1/13 7:35 PM, JS wrote:

On Tuesday, 2 July 2013 at 02:15:09 UTC, Andrei Alexandrescu wrote:

On 7/1/13 6:29 PM, JS wrote:

Would would be nice is an experimental version of D where would could
easily extend the language to try out such concepts to see if they truly
are useful and how difficult to implement. e.g., I could attempt to add
said feature, it could be merged with the experimental compiler, those
interested can download the compiler and test the feature out... all
without negatively affecting D directly. If such features could be
implemented dynamically then it would probably be pretty powerful.


I don't think such a feature would make it in D, even if the
implementation cost was already sunken (i.e. an implementation was
already done and one pull request away).

Ascribing distinct objects to the same symbol is a very core feature
that affects and is affected by everything else. We'd design a lot of
D differently if that particular feature were desired, and now the
fundamentals of the design are long frozen. For a very simple example,
consider:

auto a = 2.5; // fine, a is double
...
a = 3;



No, not under what I am talking about. You can't downgrade a type, only
upgrade it. a = 3, a is still a float. Using the concept I am talking
about, your example does nothing new.

but reverse the numbers:

auto a = 3;
a = 2.5;

and a is now a float, and your logic then becomes correct EXCEPT a is
expanded, which is safe.

I really don't know how to make it any clearer but I'm not sure if
anyone understands what I'm talking about ;/


You can definitely assume you are being well understood. That's going to 
break a lot of code because of e.g. calls to overloaded functions in 
between changes of type.


Just drop this. Not only it won't make it into D, it's also not 
particularly interesting.



Andrei


Re: Automatic typing

2013-07-02 Thread F i L

Steven Schveighoffer wrote:
There are very good reasons not to do this, even if possible.  
Especially if the type can change.


+1

This sort of inference can only lead to problems down the line, 
IMO.


Re: SIMD on Windows

2013-07-02 Thread bearophile

Jonathan Dunlap:

Thanks Jerro, I went ahead and used a pointer reference to 
ensure it's being saved back into the array 
(http://dpaste.dzfl.pl/52710926). Two things:

1) still showing zero time delta
2) On windows 7 x74, using a SAMPLE_AT size of 3 or higher 
will cause the program to immediately quit with no output at 
all. Even the first statement of writeln in the constructor 
doesn't execute.


Have you taken a look at the asm?

Bye,
bearophile


UFCS and constructors

2013-07-02 Thread monarch_dodra
Coming back from learn here. There was an example where somebody 
accidentally called a constructor via UFCS. I am kind of 
surprised that it worked. I thought UFCS was for functions only, 
and that constructors (specifically) were off limits.


Am I mistaken? Is UFCS explicitly allowed for constructors? Or 
did we kind of forget to take it into account?


One of the big problems with allowing UFCS and constructors is 
that a . which meant scope can now mean function call. If I 
remember correctly, that is the reason why qualified calls (eg 
'a'.std.uni.toLower()) aren't allowed in UFCS (Am I correct?), 
but with constructors, you get the same problem:


Allow me to demonstrate:


import std.stdio;

struct Bar
{
struct S
{
int i;
}
enum j = 1;
}

struct S
{
int[10] i;
}

void main()
{
writeln(Bar.S());   (1)
writeln(Bar.j.S()); (2)
}


(1) is a standard scope call: instantiate a Bar.S. This prints 
S(0).
(2) is actually: get the value j from Bar, and then UFCS 
construct an S using that J. This prints:  S([1, 1, 1, 1, 1, 1, 
1, 1, 1, 1])


Furthermore, I find UFCS construction confusing on the grounds 
that there is no actual constructor function eg: this(...) 
call: This is just aggregate initialization, which looks *very* 
confusing when written that way.




So to sum up the question: Was UFCS + constructors are really 
desired feature? Was it taken into account? Do we want to keep it?


In particular, the standard workaround of free function 
constructor (EG Take vs take) would serve much better here.


Re: UFCS and constructors

2013-07-02 Thread bearophile

monarch_dodra:

Is UFCS explicitly allowed for constructors? Or did we kind of 
forget to take it into account?


I think it's allowed, but such design decisions should be written 
in a kind of document... instead of just in the D front end 
source code.


See also:
http://d.puremagic.com/issues/show_bug.cgi?id=9857

Bye,
bearophile


Re: UFCS and constructors

2013-07-02 Thread Jonathan M Davis
On Tuesday, July 02, 2013 09:35:38 monarch_dodra wrote:
 Coming back from learn here. There was an example where somebody
 accidentally called a constructor via UFCS. I am kind of
 surprised that it worked. I thought UFCS was for functions only,
 and that constructors (specifically) were off limits.
 
 Am I mistaken? Is UFCS explicitly allowed for constructors? Or
 did we kind of forget to take it into account?

I'm not sure that it was ever decided one way or the other so much as happened 
into being due to how UFCS was implemented. I know that it's come up before, 
and folks were arguing on both sides. Personally, I think that it's a horrible 
idea.

- Jonathan M Davis


Re: UFCS and constructors

2013-07-02 Thread Maxim Fomin

On Tuesday, 2 July 2013 at 07:35:39 UTC, monarch_dodra wrote:


One of the big problems with allowing UFCS and constructors 
is that a . which meant scope can now mean function call.


Just for the interest - try to guess what following in D may be:

a.b = c.d();

This is a good example how overloaded D syntax is.




(1) is a standard scope call: instantiate a Bar.S. This prints 
S(0).
(2) is actually: get the value j from Bar, and then UFCS 
construct an S using that J. This prints:  S([1, 1, 1, 1, 1, 
1, 1, 1, 1, 1])


Furthermore, I find UFCS construction confusing on the grounds 
that there is no actual constructor function eg: this(...) 
call: This is just aggregate initialization, which looks *very* 
confusing when written that way.




So to sum up the question: Was UFCS + constructors are really 
desired feature? Was it taken into account? Do we want to keep 
it?


I think this worth bug issue. Even if this behavior would be 
proven to be correct (I guess many wish it wouldn't), bugzilla 
request could be posted as an ask to provide use case in D 
documentation site to show this behavior explicitly.




Re: UFCS and constructors

2013-07-02 Thread deadalnix

On Tuesday, 2 July 2013 at 08:16:38 UTC, Jonathan M Davis wrote:

On Tuesday, July 02, 2013 09:35:38 monarch_dodra wrote:
Coming back from learn here. There was an example where 
somebody

accidentally called a constructor via UFCS. I am kind of
surprised that it worked. I thought UFCS was for functions 
only,

and that constructors (specifically) were off limits.

Am I mistaken? Is UFCS explicitly allowed for constructors? Or
did we kind of forget to take it into account?


I'm not sure that it was ever decided one way or the other so 
much as happened
into being due to how UFCS was implemented. I know that it's 
come up before,
and folks were arguing on both sides. Personally, I think that 
it's a horrible

idea.

- Jonathan M Davis


We are 2. that is horrible.


Re: memory allocation in dmd

2013-07-02 Thread Don

On Saturday, 22 June 2013 at 21:41:15 UTC, Walter Bright wrote:
Compiling std.algorithm for unittests consumes all the memory 
on many machines. I've been looking into what is allocating all 
that memory, and it isn't so easy without adding 
instrumentation code anywhere.


Anyone know of a convenient tool to do this on Linux?

(valgrind just hangs, or at least I gave up on it after 6 hours)


I did a check on the CTFE part of it. You can do this by setting 
SHOWPERFORMANCE to 1 in the top of interpret.c. This produces:


$ dmd -c -unittest std.algorithm
 CTFE Performance 
max call depth = 20 max stack = 63
array allocs = 356  assignments = 45356

That's actually not so terrible. The number of assignments gives 
a rough idea of how many CTFE statements are executed (almost 
everything interesting is an assignment). Most of the assignments 
are IntegerExpressions, of about 8 bytes, so it's under a 
megabyte in total. Note that there are very few array 
allocations, they are the thing that can really chew up memory 
quickly in CTFE.


So although CTFE generally leaks memory like the Exxon Valdez 
leaks oil, I don't think it's to blame in this particular case.


Re: UDP enhancement

2013-07-02 Thread JS

On Tuesday, 2 July 2013 at 04:49:55 UTC, estew wrote:


 It's location in the class my not be the same but that is, 
 in

 general, irrelevant unless you are messing with the bits of
the class.



Actually we do this a lot in C++ where I work to ensure proper 
alignment. We are also starting to do this in D where we have 
C++ - D bindings so we can make our D structs exactly match 
our C++ structs in memory.


Personally I see less benefit over:

public @property int value;

This approach is nice. It can be used both when layout is 
important and when it is don't care and is clearer. I can 
look at the struct and immediately read its memory footprint.


Your suggested proposal cannot be used when layout is important 
as it is left to the compiler. It would require a workaround to 
coerce the compiler into submission, or additional compiler 
circuitry making it even more complex and slowing it down.


Or just use the old way. Just because one extends a feature does 
not mean the old feature is removed. If you need to hack up the 
bits just explicitly allocate the field... simple as that.




Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/02/2013 09:35 AM, monarch_dodra wrote:


Furthermore, I find UFCS construction confusing on the grounds that there is no 
actual
constructor function eg: this(...) call:  This is just aggregate 
initialization,


Aggregate initialization is the job of the constructor. It is a default 
constructor call.



which looks *very* confusing when written that way.



I disagree, even though the example appears to be specifically designed 
to confuse. Actual usage looks like this:


import std.stdio, std.bigint

void main(){
writeln(2.BigInt ^^ 123456);
}







So to sum up the question: Was UFCS + constructors are really desired
feature?


UFCS allows foo(a,b) to be written as a.foo(b), if 'foo' is not a member 
of a.



Was it taken into account?


I guess so.


Do we want to keep it?



There is no reason to artificially ban it.


In particular, the standard workaround of free function constructor


What is the difference?


(EG Take vs take) would serve much better here.


take is not a free function constructor.


Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/02/2013 09:35 AM, monarch_dodra wrote:

...

One of the big problems with allowing UFCS and constructors is that a
. which meant scope can now mean function call.
...


I missed this point.

'One of the drawbacks of UFCS is that bar.foo which meant scope 
lookup or opDispatch instantiation or alias this lookup can now 
also mean UFCS lookup.'


Fixed.


Re: UFCS and constructors

2013-07-02 Thread deadalnix

On Tuesday, 2 July 2013 at 12:57:50 UTC, Timon Gehr wrote:

On 07/02/2013 09:35 AM, monarch_dodra wrote:

...

One of the big problems with allowing UFCS and constructors 
is that a

. which meant scope can now mean function call.
...


I missed this point.

'One of the drawbacks of UFCS is that bar.foo which meant 
scope lookup or opDispatch instantiation or alias this 
lookup can now also mean UFCS lookup.'


Fixed.


That is an issue, we have all of this, and prioritization 
mechanism is implementation defined right now.


Re: UFCS and constructors

2013-07-02 Thread Kenji Hara
2013/7/2 deadalnix deadal...@gmail.com

 On Tuesday, 2 July 2013 at 08:16:38 UTC, Jonathan M Davis wrote:

 On Tuesday, July 02, 2013 09:35:38 monarch_dodra wrote:

 Coming back from learn here. There was an example where somebody
 accidentally called a constructor via UFCS. I am kind of
 surprised that it worked. I thought UFCS was for functions only,
 and that constructors (specifically) were off limits.

 Am I mistaken? Is UFCS explicitly allowed for constructors? Or
 did we kind of forget to take it into account?


 I'm not sure that it was ever decided one way or the other so much as
 happened
 into being due to how UFCS was implemented. I know that it's come up
 before,
 and folks were arguing on both sides. Personally, I think that it's a
 horrible
 idea.

 - Jonathan M Davis


 We are 2. that is horrible.


I don't know what design decision had been there about it.

Historically, there's no restriction against UFCS-callable entity.
With 2.030 (released on May 11, 2009) and git head, following code
completely works.

void foo(int[]) {}
void bar(T)(T) {}

struct Foo { int[] x; }
struct Bar { this(int[]) {} }
struct Baz { static opCall(int[]) { return 0; } }

int[] function(int[]) fp;
int[] delegate(int[]) dg;

struct Functor { int opCall(int[]) { return 0; } }
Functor fn;

void main()
{
fp = function(int[] x){ return x; };
dg = delegate(int[] x){ return x; };

int[] a;
a.foo();
a.bar();
auto x1 = a.Foo();
auto x2 = a.Bar();
auto x3 = a.Baz();
a.fp();
a.dg();
a.fn();
}

While improvement of dmd front-end code, I didn't touch it.
Yes, I did never designed it...

Kenji Hara


Re: Automatic typing

2013-07-02 Thread Ivan Kazmenko

On Saturday, 29 June 2013 at 03:20:27 UTC, JS wrote:
I don't disagree with you and I'm not saying auto is not 
useful. IMO though, auto is almost all convenience and very 
little to do with solving errors.


A very simple use case is:

auto x = 0;
...
x = complex(1, 1) + x;

which obviously is an error.


Let me expand the example with this:

auto x = 0;
complex y;
...
x = complex(1, 1) + x; // ouch, I meant the next line!
y = complex(1, 1) + x;

Personally, I appreciate the strengths of static typing here, 
forcing me to choose which of the two behaviors I meant instead 
of silently picking one of them.


Ivan Kazmenko.


Re: UFCS and constructors

2013-07-02 Thread monarch_dodra

On Tuesday, 2 July 2013 at 12:46:42 UTC, Timon Gehr wrote:

On 07/02/2013 09:35 AM, monarch_dodra wrote:

which looks *very* confusing when written that way.



I disagree, even though the example appears to be specifically 
designed to confuse. Actual usage looks like this:


import std.stdio, std.bigint

void main(){
writeln(2.BigInt ^^ 123456);
}


Yeah... tailored for confusion... that could be the biggest issue 
actually:


I always get surprised when arrays are 1 item initialized, and 
even more so when done in a struct via aggregate initialization. 
I'd say *that* was actually the bigger culprit in my example, and 
the one that lead to my confusion, which I then blamed (or 
called wolf) on UFCS If it wasn't for UFCS, that would have 
been turned down! UFCS actually had nothing to do with it. :(


Well, thanks for the explanation and debunk.


Member lookup (Was: Re: UFCS and constructors)

2013-07-02 Thread Timon Gehr

On 07/02/2013 03:00 PM, deadalnix wrote:

On Tuesday, 2 July 2013 at 12:57:50 UTC, Timon Gehr wrote:

On 07/02/2013 09:35 AM, monarch_dodra wrote:

...

One of the big problems with allowing UFCS and constructors is that a
. which meant scope can now mean function call.
...


I missed this point.

'One of the drawbacks of UFCS is that bar.foo which meant scope
lookup or opDispatch instantiation or alias this lookup can now
also mean UFCS lookup.'

Fixed.


That is an issue, we have all of this, and prioritization mechanism is
implementation defined right now.


Yup. I'll go with:

1: If member is present (current scope or super class scope), use that,
   otherwise try opDispatch in the same scopes. Block alias this at
   this point.

2: If no success, loop through all alias this definitions and apply 1.
   for the corresponding scopes. Collect possible members.

3: Error out if multiple possible distinct members.

4: Try UFCS rewrite if no matches.

(Of course, even checking whether a member is present, or looping over 
all alias this definitions are not entirely trivial processes themselves 
in the general case.)


This seems to be compatible with what DMD does.



Function templates do implicit conversions for their arguments

2013-07-02 Thread TommiT
This is a pretty big delta between C++ and D. It's going to 
surprise everybody coming from C++, especially when it says in 
TDPL (page 140) that: However, having the language attempt 
combinatorially at the same time implicit conversions and type 
deduction is a dicey proposition in the general case, so D does 
not attempt to do all that.


D
---
struct Wrap(Gift)
{
Gift gift;
}

struct Teddy
{
int id;

Wrap!Teddy getWrapped() @property
{
return Wrap!Teddy(this);
}

alias getWrapped this;
}

Gift tearOpen(Gift)(Wrap!Gift wrappedGift)
{
return wrappedGift.gift;
}

void main()
{
auto ted = Teddy(123);
auto r = tearOpen(ted); // N! Teddy!
assert(r == ted); // Phew, Teddy was implicitly gift-wrapped
  // and we tore the wrap open, not Teddy.
}


C++
---
template typename Gift
struct Wrap
{
Gift gift;
};

struct Teddy
{
int id;

operator WrapTeddy()
{
return WrapTeddy{*this};
}
};

template typename Gift
Gift tearOpen(WrapGift wrappedGift)
{
return wrappedGift.gift;
}

int main()
{
Teddy ted (123);
tearOpen(ted); // No matching function call to 'tearOpen'
}


This difference between D and C++ should be noted somewhere in 
the documentation with big red letters.


Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 16:59:50 UTC, TommiT wrote:

[..]
C++
---
[..]
Teddy ted (123);
[..]


That should be:
Teddy ted {123};


Re: UDP enhancement

2013-07-02 Thread Kapps

On Monday, 1 July 2013 at 01:35:40 UTC, Jonathan M Davis wrote:


I believe that the way that this sort of enhancement has 
typically been

suggested is to do something like

public @property int value;

which would be lowered to something like

public @property int value() @safe const pure nothrow { return 
_value; }
public @property int value(int v) @safe pure nothrow { return 
_value = v; }

private int _value;

- Jonathan M Davis


As someone who uses properties almost everywhere, and almost 
never uses public fields, this is one of my biggest gripes with D 
remaining. It's incredibly annoying to have to do things like


private int _width;
/// Gets or sets the total width, in pixels, of this control.
@property int width() const {
return _width;
}
/// ditto
@property void width(int value) {
this._width = value;
}


Something like

/// Gets or sets the total width, in pixels, of this control.
@property const int width;

Is just so much nicer and saves so much bloat. I feel like the 
current property syntax is one of those places where IDE code 
snippets will start to become, not necessary, but extremely 
useful. It's the type of manual repetition that D aims to avoid, 
but in this case fails at.
I don't know if I agree with automatically expanding to const 
though. I'd like to be able to do '@property Control parent' 
without needing to return a const(Control) because the property 
is expanded to be const. Although if we had a virtual keyword, 
final is something that I think should be default for properties, 
and I think it's a mistake that the current @property doesn't 
infer final in the first place. Safe and nothrow are two 
assumptions that are probably quite safe to assume for the most 
part as well.


Re: UFCS and constructors

2013-07-02 Thread Jonathan M Davis
On Tuesday, July 02, 2013 14:46:41 Timon Gehr wrote:
  Do we want to keep it?
 
 There is no reason to artificially ban it.

There's nothing artificial about it. Constructors are not normal functions and 
should not be treated as such. They're fundamentally different from normal 
functions.

Also, in all other cases, UFCS involves using a free function as if it were a 
member function, so it's incredibly bizarre as well as inconsistent with the 
rest of UFCS to allow constructors to be used with it.

- Jontahan M Davis


Re: UDP enhancement

2013-07-02 Thread Jonathan M Davis
On Tuesday, July 02, 2013 19:49:39 Kapps wrote:
 On Monday, 1 July 2013 at 01:35:40 UTC, Jonathan M Davis wrote:
  I believe that the way that this sort of enhancement has
  typically been
  suggested is to do something like
  
  public @property int value;
  
  which would be lowered to something like
  
  public @property int value() @safe const pure nothrow { return
  _value; }
  public @property int value(int v) @safe pure nothrow { return
  _value = v; }
  private int _value;
  
  - Jonathan M Davis
 
 As someone who uses properties almost everywhere, and almost
 never uses public fields, this is one of my biggest gripes with D
 remaining. It's incredibly annoying to have to do things like
 
 private int _width;
 /// Gets or sets the total width, in pixels, of this control.
 @property int width() const {
 return _width;
 }
 /// ditto
 @property void width(int value) {
 this._width = value;
 }
 
 
 Something like
 
 /// Gets or sets the total width, in pixels, of this control.
 @property const int width;
 
 Is just so much nicer and saves so much bloat. I feel like the
 current property syntax is one of those places where IDE code
 snippets will start to become, not necessary, but extremely
 useful. It's the type of manual repetition that D aims to avoid,
 but in this case fails at.
 I don't know if I agree with automatically expanding to const
 though.

inout would probably be better then. But without that, anyone wanting to be 
const-correct is going to have to declare all of the getters themselves. inout 
isn't quite there, because there are many cases where you really do want to 
return const even when the object is mutable, but it would probably be a good 
compromise.

- Jonathan M Davis


Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread Jesse Phillips

On Tuesday, 2 July 2013 at 16:59:50 UTC, TommiT wrote:

D
---
struct Wrap(Gift)
{
Gift gift;
}

struct Teddy
{
int id;

Wrap!Teddy getWrapped() @property
{
return Wrap!Teddy(this);
}

alias getWrapped this;
}


C++ doesn't have alias this. The behavior that it should be 
simulating is inheritance, I'd probably fail writing C++ for this 
so here is some D code to translate:


import std.stdio;

class Wrap(Gift) {
abstract Gift gift();
}

class Teddy : Wrap!Teddy {
int id;

this(int i) { id = i; }

override Teddy gift() { return this; }
}

Gift tearOpen(Gift)(Wrap!Gift wrappedGift)
{
return wrappedGift.gift;
}

void main() {
auto ted = new Teddy(123);
auto r = tearOpen(ted); // N! Teddy!
assert(r == ted); // Phew, Teddy was implicitly gift-wrapped
  // and we tore the wrap open, not Teddy.
}


Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread Ali Çehreli

On 07/02/2013 11:46 AM, Jesse Phillips wrote:

 C++ doesn't have alias this. The behavior that it should be simulating
 is inheritance

But 'alias this' is also for automatic type conversions. TommiT's had 
implemented 'operator WrapTeddy() const' (const added by me) but C++ 
does not attempt that automatic type conversion. D does attempt the 
conversion. I think that is TommiT's point.


Ali



Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 18:47:00 UTC, Jesse Phillips wrote:


[..] The behavior that it [alias this] should be simulating is 
inheritance, [..]


Okay. I had thought of alias this as *merely* implicit 
conversion. But it really makes sense that it simulates (models) 
inheritance and the implicit conversion (to the base type) is 
just a consequence of that.


On Tuesday, 2 July 2013 at 18:47:00 UTC, Jesse Phillips wrote:


[..] I'd probably fail writing C++ for this so here is some D 
code to translate:


import std.stdio;

class Wrap(Gift) {
abstract Gift gift();
}

class Teddy : Wrap!Teddy {
int id;

this(int i) { id = i; }

override Teddy gift() { return this; }
}

Gift tearOpen(Gift)(Wrap!Gift wrappedGift)
{
return wrappedGift.gift;
}

void main() {
auto ted = new Teddy(123);
auto r = tearOpen(ted); // N! Teddy!
assert(r == ted); // Phew, Teddy was implicitly gift-wrapped
  // and we tore the wrap open, not Teddy.
}


Here's what the corresponding code would be in C++:

#include cassert

template typename Gift
class Wrap
{
public:
virtual Gift gift() = 0;
};

class Teddy : public WrapTeddy
{
public:
int id;

Teddy(int i) : id(i) { }

Teddy gift() { return *this; }

bool operator==(const Teddy other) const
{
return id == other.id;
}
};

template typename Gift
Gift tearOpen(WrapGift wrappedGift)
{
return wrappedGift.gift();
}

int main()
{
auto ted = Teddy(123);
auto r = tearOpen(ted); // OK
assert(r == ted); // OK
return 0;
}


Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread Maxim Fomin

On Tuesday, 2 July 2013 at 16:59:50 UTC, TommiT wrote:

...


Slightly changed original code

struct Wrap(T)
{
T t;
}

struct S
{
int id;

Wrap!S getWrapped()
{
return Wrap!S(this);
}

alias getWrapped this;
}

T tearOpen(T)(Wrap!T wrappedT)
{
return wrappedT.t;
}

void main()
{
S ted = S(123);
S r = tearOpen(ted);
assert(r == ted);
}

Since both S(123) and tearOpen(ted) has same type and return same 
value comparison succeeds. tearOpen(ted) should take Wrap!T but 
argument has different type. Argument has alias this, so it is 
analyzed and since it is aliased to Wrap!S, passing succeeds. 
This is how alias this is designed to work. What have you 
surprised here?


Feature request: Path append operators for strings

2013-07-02 Thread TommiT
How would you feel about adding the '/' binary operator and the 
'/=' assignment operator for strings, wstrings and dstrings? The 
operators would behave the same way as they do with 
boost::filesystem::path objects:


http://www.boost.org/doc/libs/1_54_0/libs/filesystem/doc/reference.html#path-appends

In short (and omitting some details) code such as:

string s = C:\\Users / John;

...would be the same as:

string s = C:\\Users ~ std.path.dirSeparator ~ John;


Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/02/2013 07:58 PM, Jonathan M Davis wrote:

On Tuesday, July 02, 2013 14:46:41 Timon Gehr wrote:

Do we want to keep it?


There is no reason to artificially ban it.


There's nothing artificial about it. Constructors are not normal functions and
should not be treated as such.
They're fundamentally different from normal
functions.

Also, in all other cases, UFCS involves using a free function as if it were a
member function, so it's incredibly bizarre as well as inconsistent with the
rest of UFCS to allow constructors to be used with it.

- Jontahan M Davis



It is an artificial limitation, because you need to add an explicit 
check after symbol lookup to ban constructors.



Analogies are always broken, but the rest of the post reads to me 
roughly like:


Dogs are not pets, and should not be treated as such.
They are fundamentally different from pets.

Also, there are no other pets that bark, so it's incredibly bizarre as 
well as inconsistent with the rest of the notion of a 'pet' to have a 
pet dog.


- Tmion M Gehr



This has happened before. What am I missing?


Re: Feature request: Path append operators for strings

2013-07-02 Thread Simen Kjaeraas

On 2013-07-02, 21:46, TommiT wrote:

How would you feel about adding the '/' binary operator and the '/='  
assignment operator for strings, wstrings and dstrings? The operators  
would behave the same way as they do with boost::filesystem::path  
objects:


http://www.boost.org/doc/libs/1_54_0/libs/filesystem/doc/reference.html#path-appends

In short (and omitting some details) code such as:

string s = C:\\Users / John;

...would be the same as:

string s = C:\\Users ~ std.path.dirSeparator ~ John;


This would be much better done with a library type:

auto s = Path(C:\\Users) / John;

--
Simen


Re: Feature request: Path append operators for strings

2013-07-02 Thread Jonathan M Davis
On Tuesday, July 02, 2013 21:46:26 TommiT wrote:
 How would you feel about adding the '/' binary operator and the
 '/=' assignment operator for strings, wstrings and dstrings? The
 operators would behave the same way as they do with
 boost::filesystem::path objects:
 
 http://www.boost.org/doc/libs/1_54_0/libs/filesystem/doc/reference.html#path
 -appends
 
 In short (and omitting some details) code such as:
 
 string s = C:\\Users / John;
 
 ...would be the same as:
 
 string s = C:\\Users ~ std.path.dirSeparator ~ John;

That's what std.path.buildPath is for.

- Jonathan M Davis


Re: Function templates do implicit conversions for their arguments

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 19:39:56 UTC, Maxim Fomin wrote:
[..] This is how alias this is designed to work. What have you 
surprised here?


I had started to think about alias this as C++'s implicit 
conversion operator. And I remembered wrong how alias this was 
explained in TDPL. I remembered it somehow like this:


Whenever a variable der of type Derived is used where a type 
Base is expected, the compiler tries der.getBase also. (assuming 
alias getBase this; in Derived)


And since a templated parameter doesn't *expect* anything, I 
figured it wouldn't convert.


But alias this is defined in TDPL (page 265) like so:
The workings of alias payload this are quite simple. Whenever a 
value obj of type Final!T is used in a context that would be 
illegal for its type, the compiler rewrites obj as obj.payload.


Just an honest mistake on my part.


Re: UFCS and constructors

2013-07-02 Thread Maxim Fomin

On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:


Analogies are always broken, but the rest of the post reads to 
me roughly like:


Dogs are not pets, and should not be treated as such.
They are fundamentally different from pets.

Also, there are no other pets that bark, so it's incredibly 
bizarre as well as inconsistent with the rest of the notion of 
a 'pet' to have a pet dog.


- Tmion M Gehr




class A
{
  this() {}
  void foo(){}
}

A a = new A; // calls ctor, not foo

Of course constructors are special because not any function is 
called upon object construction. Same logic was made when ability 
to overload some operators was blocked. All operators are, well, 
operators but you cannot overload all of them. It appears that 
sometimes it does make sense to restrict operation on some 
particular elements of the set and sometimes not.


Anyway, without final decision on this issue, there would be 
endless controversy between those who point on commonness of all 
functions and those who point on peculiarity of some of them.


Re: Feature request: Path append operators for strings

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 19:56:20 UTC, Jonathan M Davis wrote:

On Tuesday, July 02, 2013 21:46:26 TommiT wrote:

How would you feel about adding the '/' binary operator and the
'/=' assignment operator for strings, wstrings and dstrings? 
The

operators would behave the same way as they do with
boost::filesystem::path objects:

http://www.boost.org/doc/libs/1_54_0/libs/filesystem/doc/reference.html#path
-appends

In short (and omitting some details) code such as:

string s = C:\\Users / John;

...would be the same as:

string s = C:\\Users ~ std.path.dirSeparator ~ John;


That's what std.path.buildPath is for.

- Jonathan M Davis


Oh, I hadn't noticed that function. I don't know about its 
behaviour of dropping path components situated before a rooted 
path component. Throwing an Exception would seem like a better 
behaviour in that situation.


Re: Feature request: Path append operators for strings

2013-07-02 Thread monarch_dodra

On Tuesday, 2 July 2013 at 19:46:34 UTC, TommiT wrote:
How would you feel about adding the '/' binary operator and the 
'/=' assignment operator for strings, wstrings and dstrings? 
The operators would behave the same way as they do with 
boost::filesystem::path objects:


There is a *massive* difference here. boost::filesystem adds the
overload for *path* objects. It doesn't add a global operator for
any indiscriminate string.


Re: Feature request: Path append operators for strings

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 20:31:14 UTC, monarch_dodra wrote:

On Tuesday, 2 July 2013 at 19:46:34 UTC, TommiT wrote:
How would you feel about adding the '/' binary operator and 
the '/=' assignment operator for strings, wstrings and 
dstrings? The operators would behave the same way as they do 
with boost::filesystem::path objects:


There is a *massive* difference here. boost::filesystem adds the
overload for *path* objects. It doesn't add a global operator 
for any indiscriminate string.


As far as I can tell, Phobos already uses strings or 
const(char)[] to represent paths all over the place. So, I 
figured, we can't add a separate Path type at this point because 
that train has passed. Although, I don't know if that design 
would have been a better anyway. Division operator for strings 
doesn't make any sense, and I doubt there will ever be some other 
meaning for '/' that would make more sense than a directory 
separator for strings in the context of programming.


Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/02/2013 10:16 PM, Maxim Fomin wrote:

On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:


Analogies are always broken, but the rest of the post reads to me
roughly like:

Dogs are not pets, and should not be treated as such.
They are fundamentally different from pets.

Also, there are no other pets that bark, so it's incredibly bizarre as
well as inconsistent with the rest of the notion of a 'pet' to have a
pet dog.

- Tmion M Gehr




class A
{
   this() {}
   void foo(){}
}

A a = new A; // calls ctor, not foo

Of course constructors are special because not any function is called
upon object construction.


(We are discussing struct constructors.)

Of course. I fully agree. Obviously there is a reason why those 
functions are called constructors.


But one could now extend on the original argument, and say that eg. all 
the overloading rules should be different for constructors, because they 
are fundamentally different and should under no circumstances be treated 
like 'normal functions'. Do you see what the point is? This is not a 
valid way of justifying a breaking language change.



Same logic


Logics that can prove some equivalent statements are not necessarily 
equivalent. (In particular, it does not rule out inconsistency of one of 
them.)



was made when ability to overload
some operators was blocked. All operators are, well, operators but you
cannot overload all of them. It appears that sometimes it does make
sense to restrict operation on some particular elements of the set and
sometimes not.
...


Such restrictions need to be justified. The justification should make 
(at least some) sense. There is no point in heuristically designing 
language features from observations about other language features 
without applying insight.


(Anyway, I do not think that overloading of a fixed set of primitive 
operators using specially named member functions is a good mechanism for 
infix notation.)





Re: Feature request: Path append operators for strings

2013-07-02 Thread Walter Bright

On 7/2/2013 1:47 PM, TommiT wrote:

Division operator for strings doesn't make any sense,


That's why overloading / to do something completely unrelated to division is 
anti-ethical to writing understandable code. The classic example of this is the 
overloading of  and  for stream operations in C++.


Re: Feature request: Path append operators for strings

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 21:48:54 UTC, Walter Bright wrote:

On 7/2/2013 1:47 PM, TommiT wrote:

Division operator for strings doesn't make any sense,


That's why overloading / to do something completely unrelated 
to division is anti-ethical to writing understandable code. The 
classic example of this is the overloading of  and  for 
stream operations in C++.


I've never thought of it like that. At some point I remember 
writing a vector type which overloaded its binary * operator to 
mean dot product (or cross product, I can't remember). So, you 
can overload an operator, but you can't overload the meaning of 
an operator.


Re: Feature request: Path append operators for strings

2013-07-02 Thread Araq

On Tuesday, 2 July 2013 at 21:48:54 UTC, Walter Bright wrote:

On 7/2/2013 1:47 PM, TommiT wrote:

Division operator for strings doesn't make any sense,


That's why overloading / to do something completely unrelated 
to division is anti-ethical to writing understandable code. The 
classic example of this is the overloading of  and  for 
stream operations in C++.


Before C came along, '' meant much less ...


Re: Feature request: Path append operators for strings

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 22:28:24 UTC, TommiT wrote:


I've never thought of it like that. [..]


Boost Filesystem overloads the meaning of / to mean append to 
path. Boost Exception overloads  to mean add this info to 
this exception. Boost Serialization overloads  and  to mean 
serialize and deserialize, and  to mean either one of those.


So no wonder I was under the impression that we're allowed to 
overload the meaning of operators.


Re: Feature request: Path append operators for strings

2013-07-02 Thread Jonathan M Davis
On Wednesday, July 03, 2013 00:55:59 TommiT wrote:
 So no wonder I was under the impression that we're allowed to
 overload the meaning of operators.

Well, of course, you _can_ overload them to do different stuff. It's trivial to 
make most overloaded operators do something completely different from what they 
do normally. The argument against it is that doing so is bad practice, because 
it makes your code hard to understand. And for some operators (e.g. opCmp and 
opEquals), D actually implements the overloaded operator in a way that giving 
it an alternate meaning doesn't work. You _could_ do it with / though. It's 
just arguably bad practice to do so. But since you can get the same 
functonality out of a normal function without the confusion, it really doesn't 
make sense in general to overload operators to do something fundamentally 
different with a user-defined type than what they do with the built-in types. 
However, some people are really hung up on making everything terse or making 
it look like mathh or whatnot and insist on abusing operators by overloading 
them with completely different meanings.

- Jonathan M Davis


Re: Feature request: Path append operators for strings

2013-07-02 Thread Artur Skawina
On 07/02/13 22:47, TommiT wrote:
  Division operator for strings doesn't make any sense, and I doubt there will 
 ever be some other meaning for '/' that would make more sense than a 
 directory separator for strings in the context of programming.

Umm,

 $ /usr/bin/pike
 Pike v7.8 release 537 running Hilfe v3.5 (Incremental Pike Frontend)
  /a/b//c / /;
 (1) Result: ({ /* 5 elements */
 ,
 a,
 b,
 ,
 c
 })

That's the only sane use of the division operator on string types;
anything else would be extremely confusing.

And this still does not mean that it would be a good idea in D.
Typing out splitter() is not /that/ hard. 

artur


Re: Feature request: Path append operators for strings

2013-07-02 Thread John Colvin

On Tuesday, 2 July 2013 at 22:56:00 UTC, TommiT wrote:

On Tuesday, 2 July 2013 at 22:28:24 UTC, TommiT wrote:


I've never thought of it like that. [..]


Boost Filesystem overloads the meaning of / to mean append to 
path. Boost Exception overloads  to mean add this info to 
this exception. Boost Serialization overloads  and  to 
mean serialize and deserialize, and  to mean either one of 
those.


So no wonder I was under the impression that we're allowed to 
overload the meaning of operators.


Such overloads make for code that's fast to write but hard to 
read, especially to outsiders. It's a tempting direction, but not 
a good one.


Re: Feature request: Path append operators for strings

2013-07-02 Thread Walter Bright

On 7/2/2013 4:28 PM, monarch_dodra wrote:

The classic example of this is the overloading of  and  for stream
operations in C++.


Or overloading ~ to mean concat ?


Binary ~ has no other meaning, so it is not overloading it to mean something 
else.


Re: Feature request: Path append operators for strings

2013-07-02 Thread monarch_dodra

On Tuesday, 2 July 2013 at 21:48:54 UTC, Walter Bright wrote:

On 7/2/2013 1:47 PM, TommiT wrote:

Division operator for strings doesn't make any sense,


That's why overloading / to do something completely unrelated 
to division is anti-ethical to writing understandable code.


s/division/The common agreed upon semantic/

The classic example of this is the overloading of  and  for 
stream operations in C++.


Or overloading ~ to mean concat ?


Re: Feature request: Path append operators for strings

2013-07-02 Thread TommiT

On Tuesday, 2 July 2013 at 23:08:37 UTC, Artur Skawina wrote:

On 07/02/13 22:47, TommiT wrote:
 Division operator for strings doesn't make any sense, and I 
doubt there will ever be some other meaning for '/' that would 
make more sense than a directory separator for strings in 
the context of programming.


Umm,


$ /usr/bin/pike
Pike v7.8 release 537 running Hilfe v3.5 (Incremental Pike 
Frontend)

 /a/b//c / /;
(1) Result: ({ /* 5 elements */
,
a,
b,
,
c
})


That's the only sane use of the division operator on string 
types;

anything else would be extremely confusing.

And this still does not mean that it would be a good idea in D.
Typing out splitter() is not /that/ hard.

artur


Perhaps an even more logical meaning for / operator for strings 
would be to divide the string to N equal sized parts (plus a 
potential remainder):

abcdefg / 3
result: [ab, cd, ef, g]

But your divide this string using this divider character is 
pretty logical too (once you know it).


optimized immutable containers

2013-07-02 Thread finalpatch

Is anyone aware of the new immutable containers in .Net framework?
http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx.

While we can attach the immutable qualifier to any D containers, 
they will not perform nearly as well because they are essentially 
mutable structures. Making them immutable doesn't change the way 
they work, it merely forbids us to call the modifying methods. 
Every time we need to modify them we have to copy the entire 
thing which is not very efficient.


The .Net immutable containers are specially optimized so that 
they share the underlying data as much as possible. Creating a 
modified copy is cheap, usually O(1) or O(logN).


I think having something similar in D would make immutables much 
more attractive.


Re: optimized immutable containers

2013-07-02 Thread bearophile

finalpatch:

I think having something similar in D would make immutables 
much more attractive.


I think that eventually we'll have some good immutable data 
structure in Phobos (based on finger trees, etc). But first 
probably there's a need for some mutable ones :-)


Bye,
bearophile


Re: UFCS and constructors

2013-07-02 Thread deadalnix

On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:
It is an artificial limitation, because you need to add an 
explicit check after symbol lookup to ban constructors.




That seems very implementation defined. The lookup will gives you 
a class or struct declaration, so special casing the constructor 
is mandatory anyway.




Re: UDP enhancement

2013-07-02 Thread Daniel Murphy
Kapps opantm2+s...@gmail.com wrote in message 
news:zroaabiwkaxqybrtd...@forum.dlang.org...

 As someone who uses properties almost everywhere, and almost never uses 
 public fields, this is one of my biggest gripes with D remaining. It's 
 incredibly annoying to have to do things like

 private int _width;
 /// Gets or sets the total width, in pixels, of this control.
 @property int width() const {
 return _width;
 }
 /// ditto
 @property void width(int value) {
 this._width = value;
 }


 Something like

 /// Gets or sets the total width, in pixels, of this control.
 @property const int width;

 Is just so much nicer and saves so much bloat. I feel like the current 
 property syntax is one of those places where IDE code snippets will start 
 to become, not necessary, but extremely useful. It's the type of manual 
 repetition that D aims to avoid, but in this case fails at.
 I don't know if I agree with automatically expanding to const though. I'd 
 like to be able to do '@property Control parent' without needing to return 
 a const(Control) because the property is expanded to be const. Although if 
 we had a virtual keyword, final is something that I think should be 
 default for properties, and I think it's a mistake that the current 
 @property doesn't infer final in the first place. Safe and nothrow are two 
 assumptions that are probably quite safe to assume for the most part as 
 well.

You should probably try using template mixins, if all you need to do is 
expand some code. 




Re: UFCS and constructors

2013-07-02 Thread deadalnix

On Tuesday, 2 July 2013 at 21:38:26 UTC, Timon Gehr wrote:
Such restrictions need to be justified. The justification 
should make (at least some) sense. There is no point in 
heuristically designing language features from observations 
about other language features without applying insight.




The whole point of UFCS is to be able to provide additional 
custom methods to a object (class or struct). Constructor UFCS 
don't fulfill that use case.


Nothing is removed from the language as factories method can be 
introduced anyway.


Re: UFCS and constructors

2013-07-02 Thread bearophile

deadalnix:

The whole point of UFCS is to be able to provide additional 
custom methods to a object (class or struct). Constructor 
UFCS don't fulfill that use case.


Nothing is removed from the language as factories method can be 
introduced anyway.


This frames the topic in a wrong way. Constructors are not normal 
functions, they are special, but functional languages show us 
that's it's a very good idea to see them as functions.


And the original point of UFCS doesn't matter much. What matters 
is what are the practical disadvantages of allowing UFCSyntax for 
constructors (like the original post in this thread), and what 
are their practical advantages/uses (like a handy usage in UFCS 
chains). Then we take a look at what's the resulting balance and 
we decide. And such decisions should then become the written 
specifics of this part of the D design.


Bye,
bearophile


Re: UFCS and constructors

2013-07-02 Thread Jonathan M Davis
On Wednesday, July 03, 2013 04:00:45 bearophile wrote:
 deadalnix:
  The whole point of UFCS is to be able to provide additional
  custom methods to a object (class or struct). Constructor
  UFCS don't fulfill that use case.
  
  Nothing is removed from the language as factories method can be
  introduced anyway.
 
 This frames the topic in a wrong way. Constructors are not normal
 functions, they are special, but functional languages show us
 that's it's a very good idea to see them as functions.
 
 And the original point of UFCS doesn't matter much. What matters
 is what are the practical disadvantages of allowing UFCSyntax for
 constructors (like the original post in this thread), and what
 are their practical advantages/uses (like a handy usage in UFCS
 chains). Then we take a look at what's the resulting balance and
 we decide. And such decisions should then become the written
 specifics of this part of the D design.

The primary benefit of UFCS is generic code, because if uses UFCS, generic code 
doesn't have to care whether a function is a member function or a free 
function (particularly when that can vary drastically depending on what type 
is used to instantiate the template). Construction is not and cannot be 
generic. The closest that you could get would be a factory function, which is 
quite different. But constructors themselves cannot be generic. As such, using 
constructors with UFCS in generic code just doesn't work, meaning that the 
only gain that you're getting from using UFCS with constructors is that you 
get a slightly different syntax that you might like better for one reason or 
another. But I see no technical reason why it could add any benefit over simply 
calling the constructor normally. And as such, I think that allowing UFCS to 
work with constructors is definitely an anti-feature.

- Jonathan M Davis


Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/03/2013 04:12 AM, Jonathan M Davis wrote:

On Wednesday, July 03, 2013 04:00:45 bearophile wrote:

deadalnix:

The whole point of UFCS is to be able to provide additional
custom methods to a object (class or struct). Constructor
UFCS don't fulfill that use case.

Nothing is removed from the language as factories method can be
introduced anyway.


This frames the topic in a wrong way. Constructors are not normal
functions, they are special, but functional languages show us
that's it's a very good idea to see them as functions.

And the original point of UFCS doesn't matter much. What matters
is what are the practical disadvantages of allowing UFCSyntax for
constructors (like the original post in this thread), and what
are their practical advantages/uses (like a handy usage in UFCS
chains). Then we take a look at what's the resulting balance and
we decide. And such decisions should then become the written
specifics of this part of the D design.


The primary benefit of UFCS is generic code,  because if uses UFCS, generic code
doesn't have to care whether a function is a member function or a free
function (particularly when that can vary drastically depending on what type
is used to instantiate the template).


No. Generic code has to be careful with UFCS, because every method that 
is called on a suitable variable via UFCS can be (accidentally) replaced 
by the client code.



Construction is not and cannot be generic.


The point is that struct constructors can be generically used like other 
callables.


import std.stdio, std.algorithm;

struct S{
int x;
}

void main(){
auto x = [1,2,3];
writeln(x.map!S);
}

There is nothing to be gained from subtly breaking this analogy. UFCS 
can be applied to any callable.


You are probably not going to like this, but the following code also works:

import std.stdio;

struct S{
int opCall(int x){ return x+1; }
}

S s;

void main(){
auto x = 1;
writeln(x.s);
}


The closest that you could get would be a factory function, which is
quite different.  But constructors themselves cannot be generic. As such, using
constructors with UFCS in generic code just doesn't work, meaning that the
only gain that you're getting from using UFCS with constructors is that you
get a slightly different syntax that you might like better for one reason or
another. But I see no technical reason why it could add any benefit over simply
calling the constructor normally. And as such, I think that allowing UFCS to
work with constructors is definitely an anti-feature.
...


To be an anti-feature it has to be harmful, not just of less benefit 
than some other (aspect of the) feature.




Re: D vs C++ - Where are the benchmarks?

2013-07-02 Thread Mehrdad

On Monday, 1 July 2013 at 02:53:24 UTC, Jonathan M Davis wrote:

On Monday, July 01, 2013 04:37:43 Mehrdad wrote:

On Sunday, 30 June 2013 at 20:49:28 UTC, Peter Alexander wrote:
 sometimes faster

Would love an example that demonstrates it!


Anything involving taking a lot of substrings is likely to be 
faster in D thanks to slices



That doesn't mean D is faster. It just means it's less painful 
to get the same performance.



Regarding what someone else mentioned, I wasn't talking about the 
backend either.


As an example of what I was looking for, consider that people 
claim a GC can be faster than manual memory management. If that's 
the scenario we're talking about, then what I was asking for is 
to see piece of _code_ (not a hand-wavy explanation!) that 
demonstrates GC-based code being faster than non-GC-based code.


If it's a different feature (I don't know what), then I'd like to 
know what it is strictly in terms of performance.



In other words, I know C++ is _painful_ to write fast code in, 
but that doesn't make it slower; it just makes it more painful. 
On the other hand, if you could demonstrate that e.g. the GC is 
faster than manual memory management, then I'd totally agree D is 
faster than C++.


Re: UFCS and constructors

2013-07-02 Thread Timon Gehr

On 07/03/2013 03:37 AM, deadalnix wrote:

On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:

It is an artificial limitation, because you need to add an explicit
check after symbol lookup to ban constructors.



That seems very implementation defined.


It is true for two implementations and one spec I am aware of.


The lookup will gives you a class or struct declaration,


Hopefully the UFCS lookup gives me a fully analysed call expression.
That's the point of specifying features by rewrite rules.


so special casing the constructor is mandatory anyway.



Yes, the call expression needs some kind of check in order to support 
struct literals. Cancelling that support in some way in case the call 
expression happens to have been generated by an UFCS rewrite requires 
another check, which complicates the formal specification of UFCS for no 
gain.


Re: UFCS and constructors

2013-07-02 Thread Jonathan M Davis
On Wednesday, July 03, 2013 04:54:41 Timon Gehr wrote:
 On 07/03/2013 04:12 AM, Jonathan M Davis wrote:
  On Wednesday, July 03, 2013 04:00:45 bearophile wrote:
  deadalnix:
  The whole point of UFCS is to be able to provide additional
  custom methods to a object (class or struct). Constructor
  UFCS don't fulfill that use case.
  
  Nothing is removed from the language as factories method can be
  introduced anyway.
  
  This frames the topic in a wrong way. Constructors are not normal
  functions, they are special, but functional languages show us
  that's it's a very good idea to see them as functions.
  
  And the original point of UFCS doesn't matter much. What matters
  is what are the practical disadvantages of allowing UFCSyntax for
  constructors (like the original post in this thread), and what
  are their practical advantages/uses (like a handy usage in UFCS
  chains). Then we take a look at what's the resulting balance and
  we decide. And such decisions should then become the written
  specifics of this part of the D design.
  
  The primary benefit of UFCS is generic code, because if uses UFCS,
  generic code doesn't have to care whether a function is a member function
  or a free function (particularly when that can vary drastically depending
  on what type is used to instantiate the template).
 
 No. Generic code has to be careful with UFCS, because every method that
 is called on a suitable variable via UFCS can be (accidentally) replaced
 by the client code.

That's the whole point! If you absolutely have to be certain that it's not 
calling a free function, then don't use UFCS, but the primary benefits of UFCS  
are making it so that generic code doesn't have to care whether a function is 
a free function and making it so that types can overload the behavior of free 
functions (e.g. having a member function find which is optimized for that type 
and can be used in place of std.algorithm.find).

  Construction is not and cannot be generic.
 
 The point is that struct constructors can be generically used like other
 callables.
 
 import std.stdio, std.algorithm;
 
 struct S{
 int x;
 }
 
 void main(){
 auto x = [1,2,3];
 writeln(x.map!S);
 }
 
 There is nothing to be gained from subtly breaking this analogy. UFCS
 can be applied to any callable.
 
 You are probably not going to like this, but the following code also works:
 
 import std.stdio;
 
 struct S{
 int opCall(int x){ return x+1; }
 }
 
 S s;
 
 void main(){
 auto x = 1;
 writeln(x.s);
 }

That is _very_ broken IMHO. It makes no sense for parens to be optional with 
opCall. The whole point of opCall is to overload the parens!

  The closest that you could get would be a factory function, which is
  quite different. But constructors themselves cannot be generic. As such,
  using constructors with UFCS in generic code just doesn't work, meaning
  that the only gain that you're getting from using UFCS with constructors
  is that you get a slightly different syntax that you might like better
  for one reason or another. But I see no technical reason why it could add
  any benefit over simply calling the constructor normally. And as such, I
  think that allowing UFCS to work with constructors is definitely an
  anti-feature.
  ...
 
 To be an anti-feature it has to be harmful, not just of less benefit
 than some other (aspect of the) feature.

I _do_ think that it's harmful. It obfuscates code without adding any benefit.

- Jonathan M Davis


Re: C standard libraries

2013-07-02 Thread CJS



It is in core.stdc. For example:

import core.stdc.stdio; // stdio.h
import core.stdc.stdlib;// stdlib.h

etc.



Thanks! I'm confused why that module isn't mentioned in the  
library reference page.


What's the difference between core.stdc and std.c? The docs do 
refer to core.stdc, though std.c.stdio in Phobos' source just 
imports core.stdc.stdio. The duplication seems a bit weird, and 
I'm wondering if one method is deprecated or migth be removed in 
the future.




Re: Handling different types gracefully

2013-07-02 Thread bearophile

Roderick Gibson:

Variant is a possiblity. How is the performance with large 
containers of these, since these structures will likely hold 
the majority of the data in the game?


You probably have to benchmark yourself. (But I have suggested an 
Algebraic).


Bye,
bearophile


Re: Eponymous template with full template syntax

2013-07-02 Thread monarch_dodra

On Monday, 1 July 2013 at 22:46:55 UTC, Ali Çehreli wrote:

On 07/01/2013 02:10 PM, monarch_dodra wrote:

 That is confusing.

 UFCS construction: Yes.

I *think* I did not know it but I can't be sure. :)


AH... I looked at the threads some more: I was actually thinking 
about a proposal that wanted (just like UFCS), to allow 
non-intrusively adding constructors.


So I guess UFCS and constructors are fair game? I do not like 
this at all...


Re: Template constraints and opAdd

2013-07-02 Thread bearophile

John:


Mass!(T,S) opAdd(Mass!(T,S) other) {


If you are using D2 then don't use opAdd, use opBinary:

http://dlang.org/operatoroverloading.html#Binary


Time ago I added an enhancement request for a warning (that later 
is meant to become a deprecation) that helps avoid your problem:


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

Bye,
bearophile


Re: C standard libraries

2013-07-02 Thread John Colvin

On Monday, 1 July 2013 at 18:09:32 UTC, Jonathan M Davis wrote:

On Monday, July 01, 2013 18:32:30 CJS wrote:

Is there some header/module that includes declaration for all C
standard libraries?

I'm wondering both in general for future reference, and for the
specific case of wanting to time a function and not knowing 
what

in D--even after looking through the docs--would do something
equivalent to clock and CLOCKS_PER_SEC in the C standard 
library

time.h.


If you want to time a function, checkout std.datetime.StopWatch:
http://dlang.org/phobos/std_datetime.html#StopWatch



+1

I really came to hate c's clock, StopWatch has been much more 
pleasant experience to work with.


Re: opDispatch and UFCS

2013-07-02 Thread Artur Skawina
On 07/02/13 02:45, cal wrote:
 import std.conv, std.stdio, std.algorithm;
 
 struct S {
 void opDispatch(string s, T...)(T t) if (s.startsWith(foo)) {
 writeln(s);
 }
 }
 
 void main() {
 S s;
 s.foo();
 auto p = s.to!string(); // Error: s.opDispatch!(to) isn't a template
 }
 
 Should the constraint on opDispatch allow the UFCS to call on S?

To avoid this kind of issues:

   struct S {
   template opDispatch(string s) if (s.startsWith(foo)) {
   void opDispatch(T...)(T t) {
   writeln(s);
   }
   }
   }

And, yes, the compiler should be able to handle your simpler case too,
but currently doesn't (if there are several overloads then the
transformation isn't necessarily this easy). I usually end up doing
something like:

   struct S {
   static bool _disp(string s) {
  if (s.startsWith(foo))
 return true;
  // ... other checks, AA lookups, introspection etc.
  return false;
   }
   template opDispatch(string s) if (_disp(s)) {
   void opDispatch(T...)(T t) {
   writeln(s);
   }
   }
   }

Dealing with the various frontend quirks can be fun.

artur


Re: C standard libraries

2013-07-02 Thread Gary Willoughby

Use core.stdc, and forget of std.c.

Bye,
bearophile


What's the reason for that?


Re: C standard libraries

2013-07-02 Thread bearophile

Gary Willoughby:


What's the reason for that?


Moving the C stuff in core is probably a way to remember D 
programmers that stuff is not normal stuff you are supposed to 
use in D programs. A D programmer should use the normal safer and 
nicer D functions. Core is there for special cases.


Bye,
bearophile


Re: C standard libraries

2013-07-02 Thread Adam D. Ruppe

On Tuesday, 2 July 2013 at 06:33:03 UTC, CJS wrote:
Thanks! I'm confused why that module isn't mentioned in the  
library reference page.


I don't know.


What's the difference between core.stdc and std.c?


std.c is what it was called in earlier versions of D, before 
there was a clear separation between phobos as the standard 
library (std.*) and druntime as the runtime library (core.*). 
Phobos is supposed to be 100% on top of druntime, so it is 
optional and interchangeable with ease.


The runtime, however, needed access to some C functions for its 
own implementation. Since it isn't allowed to depend on std.*, 
the C functions got moved into core.*.


The older std.c is kept around just for compatibility with the 
old names before the move, at least as far as I know. Maybe they 
haven't fully deprecated it though because there's other reasons 
I don't know about, since it has been many years now since the 
move.


Re: C standard libraries

2013-07-02 Thread bearophile

Adam D. Ruppe:

The older std.c is kept around just for compatibility with the 
old names before the move, at least as far as I know. Maybe 
they haven't fully deprecated it though because there's other 
reasons I don't know about, since it has been many years now 
since the move.


In D/Phobos/Dmd there is a ton of stuff that's supposed to be
obsolete, that should not be used, that is deprecated, etc. I
presume Walter thinks that the problems caused from keeping it
and from unwanted usages of it, is smaller than the breaking
troubles caused by removing it. I am person that likes to keeps
things ordered and clean, so I prefer to remove old stuff after a
suitable deprecation period, instead of keeping it around almost
forever (like floating point special comparison operators).

Bye,
bearophile


Re: Handling different types gracefully

2013-07-02 Thread Roderick Gibson

On Tuesday, 2 July 2013 at 06:54:58 UTC, bearophile wrote:

Roderick Gibson:

Variant is a possiblity. How is the performance with large 
containers of these, since these structures will likely hold 
the majority of the data in the game?


You probably have to benchmark yourself. (But I have suggested 
an Algebraic).


Bye,
bearophile


I should know the types at compile time, so I will be using it 
most likely, but reading the docs it looks like Algebraic is 
built on top of the same structure as Variant. Is there any 
difference in implementation?


How to get warnings about unused imports ?

2013-07-02 Thread Gabi

Hi,

How to find unused imports ?

It seems the compiler doesn't do it, but is there any other tool 
for that?
This seems like small issue, but those unused imports pile up 
pretty quickly


Regards,
Gabi


Re: Handling different types gracefully

2013-07-02 Thread bearophile

Roderick Gibson:

I should know the types at compile time, so I will be using it 
most likely, but reading the docs it looks like Algebraic is 
built on top of the same structure as Variant. Is there any 
difference in implementation?


Take a look at the Phobos source code, it's much faster than 
waiting for my answer. Algebraic is built on top of VariantN. 
Algebraic accepts only a limited number of types, while Variant 
doesn't have such limitation. So Algebraic is type safe.


And maybe Algebraic can ideally be implemented more efficiently 
than a Variant because to denote the contained type an enum 
suffices, instead of a TypeInfo.


Please take a look at VariantN if it contains the enum or a 
Typeinfo or something else.


Bye,
bearophile


Re: Handling different types gracefully

2013-07-02 Thread Roderick Gibson

On Tuesday, 2 July 2013 at 21:45:57 UTC, bearophile wrote:

Roderick Gibson:

I should know the types at compile time, so I will be using it 
most likely, but reading the docs it looks like Algebraic is 
built on top of the same structure as Variant. Is there any 
difference in implementation?


Take a look at the Phobos source code, it's much faster than 
waiting for my answer. Algebraic is built on top of VariantN. 
Algebraic accepts only a limited number of types, while Variant 
doesn't have such limitation. So Algebraic is type safe.


And maybe Algebraic can ideally be implemented more efficiently 
than a Variant because to denote the contained type an enum 
suffices, instead of a TypeInfo.


Please take a look at VariantN if it contains the enum or a 
Typeinfo or something else.


Bye,
bearophile


Thanks, I'll do that. Thanks for the help, bearophile!


Re: opDispatch and UFCS

2013-07-02 Thread cal

On Tuesday, 2 July 2013 at 11:04:20 UTC, Artur Skawina wrote:

To avoid this kind of issues:

   struct S {
   template opDispatch(string s) if (s.startsWith(foo)) {
   void opDispatch(T...)(T t) {
   writeln(s);
   }
   }
   }


That's a handy workaround, thank you.


ref tuples

2013-07-02 Thread Brad Anderson
C++11's std::tuple includes a function std::tie that takes 
references to the arguments and returns a tuple that maintains 
the references to the arguments.


Along with the usual cases where you'd want reference semantics 
it also enables this interesting construct for unpacking tuples.


int a, b;
tie(a, b) = make_tuple(1, 2);

assert(a == 1  b == 2);

Is there any way to do something similar with std.typecons.Tuple?


Re: opDispatch and UFCS

2013-07-02 Thread Kenji Hara

On Tuesday, 2 July 2013 at 00:45:23 UTC, cal wrote:

import std.conv, std.stdio, std.algorithm;

struct S {
void opDispatch(string s, T...)(T t) if 
(s.startsWith(foo)) {

writeln(s);
}
}

void main() {
S s;
s.foo();
auto p = s.to!string(); // Error: s.opDispatch!(to) isn't 
a template

}

Should the constraint on opDispatch allow the UFCS to call on 
S?


That's a compiler bug.
http://d.puremagic.com/issues/show_bug.cgi?id=10526

Kenji Hara


Stop to! rounding?

2013-07-02 Thread Josh

writeln(to!double(151.42499));//prints 151.425

Is there any way to stop this rounding?

Thanks,
Josh


Re: Stop to! rounding?

2013-07-02 Thread Jonathan M Davis
On Wednesday, July 03, 2013 06:23:12 Josh wrote:
 writeln(to!double(151.42499));//prints 151.425
 
 Is there any way to stop this rounding?

No. double can't hold the value 151.42499. There are _tons_ of values that it 
can't hold exactly. The same goes for float and real. Floating point values are 
rounded all the time. Note that

double d = 151.42499;
writeln(d);

prints exactly the same thing as your example.

- Jonathan M Davis


Re: Stop to! rounding?

2013-07-02 Thread Josh

On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:

On Wednesday, July 03, 2013 06:23:12 Josh wrote:

writeln(to!double(151.42499));//prints 151.425

Is there any way to stop this rounding?


No. double can't hold the value 151.42499. There are _tons_ of 
values that it
can't hold exactly. The same goes for float and real. Floating 
point values are

rounded all the time. Note that

double d = 151.42499;
writeln(d);

prints exactly the same thing as your example.

- Jonathan M Davis


Is there any way I would be able to hold that number then?

Thanks,
Josh


Re: Stop to! rounding?

2013-07-02 Thread cal

On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:

On Wednesday, July 03, 2013 06:23:12 Josh wrote:

writeln(to!double(151.42499));//prints 151.425

Is there any way to stop this rounding?


No. double can't hold the value 151.42499. There are _tons_ of 
values that it
can't hold exactly. The same goes for float and real. Floating 
point values are

rounded all the time. Note that

double d = 151.42499;
writeln(d);

prints exactly the same thing as your example.

- Jonathan M Davis



void main()
{
   double d = 151.42499;
   assert(d == 151.42499);
}

The rounding occurs in writeln surely.


Re: Stop to! rounding?

2013-07-02 Thread Jonathan M Davis
On Wednesday, July 03, 2013 07:04:47 cal wrote:
 On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:
  On Wednesday, July 03, 2013 06:23:12 Josh wrote:
  writeln(to!double(151.42499));//prints 151.425
  
  Is there any way to stop this rounding?
  
  No. double can't hold the value 151.42499. There are _tons_ of
  values that it
  can't hold exactly. The same goes for float and real. Floating
  point values are
  rounded all the time. Note that
  
  double d = 151.42499;
  writeln(d);
  
  prints exactly the same thing as your example.
  
  - Jonathan M Davis
 
 void main()
 {
 double d = 151.42499;
 assert(d == 151.42499);
 }
 
 The rounding occurs in writeln surely.

That's true because _both_ of the floating point values there get rounded to 
151.425, and 151.425 is equal to 151.425. writeln is not doing anything wrong. 
I highly suggest that you read this:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

- Jonathan M Davis


Re: Stop to! rounding?

2013-07-02 Thread Ali Çehreli

On 07/02/2013 10:09 PM, Jonathan M Davis wrote:

 On Wednesday, July 03, 2013 07:04:47 cal wrote:

 void main()
 {
  double d = 151.42499;
  assert(d == 151.42499);
 }

 The rounding occurs in writeln surely.

 That's true because _both_ of the floating point values there get 
rounded to

 151.425,

The value that can be stored is not 151.42499, nor 151.425.

import std.stdio;
import std.conv;

void main()
{
auto a = to!double(151.42499);
writefln(%.60f, a);
}

Prints:

151.4249908194547262974083423614501953125000

 writeln is not doing anything wrong.

True. It is using its default floating point precision, 6.

Ali



Re: Stop to! rounding?

2013-07-02 Thread cal

On Wednesday, 3 July 2013 at 05:10:03 UTC, Jonathan M Davis wrote:

On Wednesday, July 03, 2013 07:04:47 cal wrote:
On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis 
wrote:

 On Wednesday, July 03, 2013 06:23:12 Josh wrote:
 writeln(to!double(151.42499));//prints 151.425
 
 Is there any way to stop this rounding?
 
 No. double can't hold the value 151.42499. There are _tons_ 
 of

 values that it
 can't hold exactly. The same goes for float and real. 
 Floating

 point values are
 rounded all the time. Note that
 
 double d = 151.42499;

 writeln(d);
 
 prints exactly the same thing as your example.
 
 - Jonathan M Davis


void main()
{
double d = 151.42499;
assert(d == 151.42499);
}

The rounding occurs in writeln surely.


That's true because _both_ of the floating point values there 
get rounded to
151.425, and 151.425 is equal to 151.425. writeln is not doing 
anything wrong.

I highly suggest that you read this:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

- Jonathan M Davis


import std.stdio;
void main()
{
double d = 151.42499;
writefln(%.10f, d);
}


Re: Stop to! rounding?

2013-07-02 Thread H. S. Teoh
On Tue, Jul 02, 2013 at 10:14:33PM -0700, Ali Çehreli wrote:
[...]
 import std.stdio;
 import std.conv;
 
 void main()
 {
 auto a = to!double(151.42499);
 writefln(%.60f, a);
 }

I wouldn't write it like that; IMO it's better to write:

writefln(%.*f, double.dig, a);

So that you don't give the wrong impression that there are more digits
than are actually there. Using double.dig also lets you see all the
digits that *are* there, not a rounded value, that the OP was
complaining about.


T

-- 
The easy way is the wrong way, and the hard way is the stupid way. Pick one.


[Issue 10491] Type inference for function arguments with default value

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10491


bearophile_h...@eml.cc changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||WONTFIX


--- Comment #5 from bearophile_h...@eml.cc 2013-07-02 00:29:40 PDT ---
OK, closed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 7227] [] syntax for empty associative array too?

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=7227



--- Comment #5 from bearophile_h...@eml.cc 2013-07-02 00:33:38 PDT ---
(In reply to comment #3)

 This patch has chosen the [] syntax over the [:] syntax.

But I prefer the [:] syntax, because it's more precise.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10475] destructor is called on 'for' loop variable even when initialization failed

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10475



--- Comment #6 from github-bugzi...@puremagic.com 2013-07-02 00:43:41 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/6c7d77f690f509255950321e3e0fec9f29d02df6
fix Issue 10475 - destructor is called on 'for' loop variable even when
initialization failed

https://github.com/D-Programming-Language/dmd/commit/aaf64112624abab1f6cc8f610223f6e12b525e09
Merge pull request #2286 from 9rnsr/fix10475

Issue 10475 - destructor is called on 'for' loop variable even when
initialization failed

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 7227] [] syntax for empty associative array too?

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=7227



--- Comment #6 from bearophile_h...@eml.cc 2013-07-02 00:46:28 PDT ---
Having two obvious syntaxes to do the same thing is not so good. So I suggest
to also introduce a warning for the usage of null as associative array
literal:


void foo(int[int]) {}
void main() {
foo(null);
int[int][] aas = [null];
aas[0] = [1: 2, 2: 3];
}

=

test.d(3): Warning: explicit [:] empty associative array literal is better than
null, that will be deprecated
test.d(4): Warning: explicit [:] empty associative array literal is better than
null, that will be deprecated

(The wording of such warning message is modelled on another warning message:
test.d(3): Warning: explicit element-wise assignment (a)[] = 2 is better than a
= 2)

(This warning is not meant to be kept. Later this warning is meant to become a
deprecation, and later an error).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10320] Warning for old-style operator overloading methods definition

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10320



--- Comment #1 from bearophile_h...@eml.cc 2013-07-02 01:01:58 PDT ---
Cases like in this thread show that it's important to give a warning now:

http://forum.dlang.org/thread/hwfzaysrfxiiumppx...@forum.dlang.org

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 5207] Immutability is broken in constructors

2013-07-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=5207



--- Comment #3 from Lars T. Kyllingstad bugzi...@kyllingen.net 2013-07-02 
02:01:08 PDT ---
I'm not suggesting that the assignment be prohibited.  Rather, I think it
should be illegal to *access* the variable before it is initialised.

If the current behaviour is by design, consider this an enhancement request.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


  1   2   >