Re: Looking for a language to hang my hat on.

2015-11-17 Thread bachmeier via Digitalmars-d-learn

On Monday, 16 November 2015 at 22:39:17 UTC, Dan wrote:
I have been lurking on this site over the past few weeks trying 
to decide when (and if) to make the transition. Can anyone here 
who has already made that transition tell me how smoothly it 
went? Any major unexpected problems? Advice?


thanks!
Dan


What do you plan to do with D? Learn it so you can use it for 
personal projects? Write large apps for a business? Use it in a 
job? The answer depends on how you'll use it. Personally, I don't 
think there is a reason to transition. Instead, you should learn 
D and then use it when you are ready.


Re: How to use readText to read utf16 file?

2015-11-17 Thread Gary Willoughby via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 02:40:14 UTC, Domain wrote:

How to use readText to read utf16 file? Or other encoding file.


Here's a helpful resource when working with text files in D.

http://nomad.so/2015/09/working-with-files-in-the-d-programming-language/


Re: Invalid foreach aggregate

2015-11-17 Thread Chris via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 11:58:22 UTC, Chris wrote:


Sorry that should be:

@property void popFront()
{
  r = r[1..$];
  cnt++;
}



Re: Invalid foreach aggregate

2015-11-17 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 12:41:45 UTC, Chris wrote:

On Tuesday, 17 November 2015 at 12:22:22 UTC, Marc Schütz wrote:
In any case, I'd suggest you fix your opIndex(), except if 
there's a really good reason it is as it is.


I see. Thanks for the explanation. What would be the easiest 
fix for this example?


Do you actually need the opIndex()? If not, just remove it.


Re: Looking for a language to hang my hat on.

2015-11-17 Thread bachmeier via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 00:33:44 UTC, Chris Wright wrote:
This might change, but that's a gamble, and not one I'd take. 
For projects where you need specific libraries to exist 
already, D probably won't serve your needs. (It's definitely 
easier with C++ interop, but you'd still have to write 
bindings. htod doesn't exactly work on Linux.)


Does anyone still use htod? I thought dstep was the tool being 
used to generate bindings.


It depends on what OP plans to do. C interop is generally very 
easy, so anything available in C is also available in D, but it 
depends on how much of the glue code needs to be written. It has 
never been a big deal for me. The bigger problem is figuring out 
what the C library does than how to interface with it.


One additional thing I've learned is that other languages might 
have large numbers of libraries "available" but a lot of it is 
low quality, undocumented/poorly documented stuff. The ability to 
easily write C bindings is in many cases preferable to 
complicated C interop but existing libraries.





Re: Invalid foreach aggregate

2015-11-17 Thread Chris via Digitalmars-d-learn

I've checked several options now and it doesn't work.

Here (http://dlang.org/statement.html#foreach-with-ranges) it is 
stated that it suffices to have range primitives, if opApply 
doesn't exist. My code worked up to 2.068.0, with the 
introduction of 2.068.1 it failed. I wonder why that is.


I have empty, front and popFront in my range which is a struct, 
and it used to work.


Re: Invalid foreach aggregate

2015-11-17 Thread Marc Schütz via Digitalmars-d-learn

On Monday, 16 November 2015 at 18:18:51 UTC, Chris wrote:

On Monday, 16 November 2015 at 17:57:53 UTC, opla wrote:

On Monday, 16 November 2015 at 16:55:29 UTC, Chris wrote:
On Monday, 16 November 2015 at 16:49:19 UTC, Marc Schütz 
wrote:

On Monday, 16 November 2015 at 16:44:27 UTC, Chris wrote:
Updating my code from 2.067.1 to 2.069.1 (I skipped 2.068, 
because I was too busy).


I get this error:

invalid foreach aggregate, define opApply(), range 
primitives, or use .tupleof


for code like

foreach (ref it; myArray.doSomething) {}

Probably not the best idea anyway. What's the best fix for 
this? Thanks.


Well, what does `doSomething` return?


It returns a range that modifies individual items in myArray, 
i.e. it assigns values to fields in each item of the array.


have you...

tried without ref
tried by adding a pair of parens after doSomething ?
tried std.algorithm.each or map on doSomething ?
checked the primitives ?
checked that isInputRange!(ReturnType!doSomething) == true?


I think ref is necessary, else the items are not changed. I 
will try the other options tomorrow (Tuesday). Thanks.


I wonder was the change overdue (and I got away with it till 
2.068.1) or is it a new policy due to changes in D?


That really depends on the details, that's why I asked. It could 
be a regression, or it could be that the compiler now does 
stricter checking than before, and your implementation wasn't 
completely correct, or it could be a bug in Phobos if you use 
that to create the range.


If you can post a minimal example that works in 2.067.1, but 
doesn't with the current version, I can try to find the change 
that broke it.


Re: Invalid foreach aggregate

2015-11-17 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 11:58:22 UTC, Chris wrote:
I did just that and I could find the culprit. It's opIndex(). 
It works up until 2.068.0, with 2.068.1 I already get this 
error:


"primitives.d(7): Error: invalid foreach aggregate 
doSomething(items).opIndex()"


@property size_t opIndex()
{
  return cnt;
}


Ok, that's a strange implementation of opIndex(). Usually, a 
parameter-less opIndex() is supposed to return a slice into the 
full range, but yours returns a size_t, which of course can't be 
iterated over.


The change that made this stop working is:
https://github.com/D-Programming-Language/dmd/pull/4948

This contains, among others a fix for issue 14625 "opIndex() 
doesn't work on foreach container iteration":

https://issues.dlang.org/show_bug.cgi?id=14625

This allows to iterate directly over containers, without needing 
to slice them first. I guess it's a bit too eager, because if the 
object is already iterable without slicing (as in your example), 
it could just do that. On the other hand, it's a corner case, and 
it might actually be preferable to slice always, if the iterable 
supports it...


In any case, I'd suggest you fix your opIndex(), except if 
there's a really good reason it is as it is.


Re: Invalid foreach aggregate

2015-11-17 Thread Chris via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 12:22:22 UTC, Marc Schütz wrote:


Ok, that's a strange implementation of opIndex(). Usually, a 
parameter-less opIndex() is supposed to return a slice into the 
full range, but yours returns a size_t, which of course can't 
be iterated over.


The change that made this stop working is:
https://github.com/D-Programming-Language/dmd/pull/4948

This contains, among others a fix for issue 14625 "opIndex() 
doesn't work on foreach container iteration":

https://issues.dlang.org/show_bug.cgi?id=14625

This allows to iterate directly over containers, without 
needing to slice them first. I guess it's a bit too eager, 
because if the object is already iterable without slicing (as 
in your example), it could just do that. On the other hand, 
it's a corner case, and it might actually be preferable to 
slice always, if the iterable supports it...


In any case, I'd suggest you fix your opIndex(), except if 
there's a really good reason it is as it is.


I see. Thanks for the explanation. What would be the easiest fix 
for this example?


Re: Filtering a tuple of containers with indices

2015-11-17 Thread anonymous via Digitalmars-d-learn

On 17.11.2015 15:32, maik klein wrote:

template tupIndexToRange(alias Tup, Indices...){

[snip]

I don't quite understand how that code is supposed to work. Maybe 
there's just some detail missing, but it could also be that your 
approach can't work.



This is roughly what I want to achieve

   alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
   Integrals integrals;
   integrals[0].insertBack(1);
   integrals[1].insertBack(2);
   integrals[2].insertBack(3);

   auto range = zip(tuple(integrals[0][],integrals[1][]).expand);
   writeln(range);
   foreach(e;range){
 writeln("element: ",e);
   }
But instead of "auto range =
zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to be
generic "auto range = zip(tupIndexToRange!(integrals, AliasSeq!(0,
1)).expand);"


I think the problem can be split up into two independent tasks:

1) Select fields of a tuple by indices (to drop `integrals[3]`).
2) A "map" function for tuples (to apply `[]` to the selected arrays).

Here are two quick implementations of those applied to your problem:


template selectFromTuple(indices ...)
{
auto selectFromTuple(Types...)(Types values)
{
import std.typecons: tuple, Tuple;
static if (indices.length == 0) return Tuple!()();
else
{
enum headIndex = indices[0];
auto tail = .selectFromTuple!(indices[1 .. $])(values);
return tuple(values[headIndex], tail.expand);
}
}
}

auto mapTuple(alias op, Types ...)(Types values)
{
import std.meta: staticMap;
import std.typecons: tuple;

alias ResultType(T) = typeof(op(T.init));
alias ResultTypes = staticMap!(ResultType, Types);

ResultTypes results;
foreach (i, v; values) results[i] = op(v);
return tuple(results);
}

void main()
{
  import std.container.array;
  import std.meta: AliasSeq;
  import std.range: zip;
  import std.stdio: writeln;

  alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
  Integrals integrals;
  integrals[0].insertBack(1);
  integrals[1].insertBack(2);
  integrals[2].insertBack(3);

  auto range = integrals
.selectFromTuple!(0, 1).expand
.mapTuple!(a => a[]).expand
.zip;

  writeln(range);
  foreach(e;range){
writeln("element: ",e);
  }
}


That looks a lot like range based programming, which makes me think that 
there could be a way to use actual range algorithms from std.algorithm 
for this. But I don't see how.


Re: How to use readText to read utf16 file?

2015-11-17 Thread ponce via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 05:37:55 UTC, Domain wrote:


Thank you! Now another question: how to handle endianness?


If your file follow a file format:
the endianness should be defined there.
else it's a random text file:
either it will have a BOM with endianness,
or you will have to guess.


Re: Looking for a language to hang my hat on.

2015-11-17 Thread Dan via Digitalmars-d-learn

Thanks everyone for taking the time to respond!

@Lobo,
Start using D now. It's not all or nothing so you don't have to 
give up on C++. I have several projects that contain both C++ 
and D intermixed.




Using both does seem like a good way to transition. I could 
combine the strengths of D with the strengths of c++. I have 
never mixed two programming languages in one project, all have 
contained one language exclusively. This is another bridge to 
cross.


D will make you a better C++ programmer, but especially C++ 
template programming. D metaprogramming is so easy to read, 
write and understand compared to C++ and many of the patterns 
still apply when you're standing knee deep in C++it.


I use c++ templates extensively, and if D offers a better 
solution that is fantastic.


@Chris Wright,


Your largest problem in the short term is documentation quality.


This concerns me since it makes it very difficult for people 
trying to learn the language. I don't need that additional 
frustration.



Your largest problem in the long run will be libraries.


Also concerning, but if I can combine the two languages somehow 
as lobo suggested, there may be a solution (just need to figure 
out how and how difficult that is).


...but you'd still have to write bindings. htod doesn't exactly 
work on Linux.


I am not exactly sure what that means, which is probably not a 
good sign.

---
@Russel Windmer
But doesn't code::blocks just interface with the compiler? I 
(naively?) thought I could just install the compiler and point 
code::blocks to that compiler.

---
@Bachmeier

What do you plan to do with D?


Good point, I did not make that clear. Right now I just want to 
use it for personal projects, but someday I hope to take it 
further.


Personally, I don't think there is a reason to transition. 
Instead, you should learn D and then use it when you are ready.


That is troubling, but reasons to transition must exist or the 
language would not exist, right? I find that if I "learn" a 
language I forget it unless I actually start using it, at least 
for a short while.


January 2016 is when I should have time to experiment with D. I 
will attempt to install the language in Linux and kick the tires 
for a while. If I continuously stumble into insurmountable 
barriers, the experiment will end.


Filtering a tuple of containers with indices

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

The question is also posted on

https://stackoverflow.com/questions/33757981/filtering-a-tuple-of-containers-with-indicies


template tupIndexToRange(alias Tup, Indices...){
  import std.meta;
  static if(Indicies.length == 0){
alias tupIndexToRange = AliasSeq!();
  }
  else{
alias tupIndexToRange = AliasSeq!(Tup[ Indices[0] ][], 
tupIndexToRange!(Tup,Indices[1..$]));

  }
}

void main{
  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;

  alias IntegralRange = tupIndexToRange!(integrals,0,1);
}

void main{
  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;

  alias IntegralRange = tupIndexToRange!(integrals,0,1);
}

I want to achieve something like this

auto range = zip(tupIndexToRange!(integrals,0,1));

I think the main problem is that Tup[ Indicies[0] ] doesn't work, 
to me it should have expanded to this 
AliasSeq!(itegrals[0][],integrals[1][]);



This is roughly what I want to achieve

  alias Integrals = AliasSeq!(Array!int, Array!float, 
Array!double);

  Integrals integrals;
  integrals[0].insertBack(1);
  integrals[1].insertBack(2);
  integrals[2].insertBack(3);

  auto range = zip(tuple(integrals[0][],integrals[1][]).expand);
  writeln(range);
  foreach(e;range){
writeln("element: ",e);
  }
But instead of "auto range = 
zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to 
be generic "auto range = zip(tupIndexToRange!(integrals, 
AliasSeq!(0, 1)).expand);"


Maybe I need use mixins?


Re: dataframe implementations

2015-11-17 Thread Jay Norwood via Digitalmars-d-learn

I looked through the dataframe code and a couple of comments...

I had thought perhaps an app could read in the header info and 
type info from hdf5, and generate D struct definitions with 
column headers as symbol names.  That would enable faster 
processing than with the associative arrays, as well as support 
the auto-completion that would be helpful in writing expressions.


The csv type info for columns could be inferred, or else stated 
in the reader call, as done as an option in julia.


In both cases the column names would have to be valid symbol 
names for this to work.  I believe Julia also expects this, or 
else does some conversion on your column names to make them valid 
symbols. I think the D csv processing would also need to check if 
the


The jupyter interactive environment supports python pandas and 
Julia dataframe column names in the autocompletion, and so I 
think the D debugging environment would need to provide similar 
capability if it is to be considered as a fast-recompile 
substitute for interactive dataframe exploration.


It seems to me that your particular examples of stock data would 
eventually need to handle missing data, as supported in Julia 
dataframes and python pandas.  They both provide ways to drop or 
fill missing values.  Did you want to support that?











Re: Looking for a language to hang my hat on.

2015-11-17 Thread bachmeier via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 14:21:27 UTC, Dan wrote:

Personally, I don't think there is a reason to transition. 
Instead, you should learn D and then use it when you are ready.


That is troubling, but reasons to transition must exist or the 
language would not exist, right? I find that if I "learn" a 
language I forget it unless I actually start using it, at least 
for a short while.


January 2016 is when I should have time to experiment with D. I 
will attempt to install the language in Linux and kick the 
tires for a while. If I continuously stumble into 
insurmountable barriers, the experiment will end.


I meant there is no reason to abandon C++ in favor of D. The 
lowest cost way to get started with D is to write some functions 
in D and call them from C++. I personally don't like the term 
"transition" because it implies significant cost.


Re: Invalid foreach aggregate

2015-11-17 Thread Chris via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 11:26:19 UTC, Marc Schütz wrote:



That really depends on the details, that's why I asked. It 
could be a regression, or it could be that the compiler now 
does stricter checking than before, and your implementation 
wasn't completely correct, or it could be a bug in Phobos if 
you use that to create the range.


If you can post a minimal example that works in 2.067.1, but 
doesn't with the current version, I can try to find the change 
that broke it.


I did just that and I could find the culprit. It's opIndex(). It 
works up until 2.068.0, with 2.068.1 I already get this error:


"primitives.d(7): Error: invalid foreach aggregate 
doSomething(items).opIndex()"


Here's the example:

=

import std.stdio : writeln;
import std.range.primitives;

void main()
{
  string[] items = ["a", "b", "c"];
  foreach (ref it; items.doSomething())
  {
writeln(it);
  }
}

auto doSomething(InputRange)(ref InputRange r)
{
  struct DoSomething
  {
private
{
  InputRange r;
  size_t cnt;
}

this(InputRange r)
{
  this.r = r;
}

@property bool empty()
{
  return r.length == 0;
}

@property auto front()
{
  return r[0];
}

@property void popFront()
{
  r = r[1..$];
}

@property size_t length() const
{
  return r.length;
}

@property size_t opIndex()
{
  return cnt;
}

@property auto save() const
{
return this;
}
  }

  return DoSomething(r);
}




Re: Looking for a language to hang my hat on.

2015-11-17 Thread Chris Wright via Digitalmars-d-learn
On Tue, 17 Nov 2015 10:53:04 +, bachmeier wrote:

> On Tuesday, 17 November 2015 at 00:33:44 UTC, Chris Wright wrote:
>> This might change, but that's a gamble, and not one I'd take.
>> For projects where you need specific libraries to exist already, D
>> probably won't serve your needs. (It's definitely easier with C++
>> interop, but you'd still have to write bindings. htod doesn't exactly
>> work on Linux.)
> 
> Does anyone still use htod? I thought dstep was the tool being used to
> generate bindings.

dstep doesn't work out of the box. A simple `dub run dstep` results in 
compilation errors.


Re: compatible types for chains of different lengths

2015-11-17 Thread Brad Anderson via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 22:47:17 UTC, Jon D wrote:
I'd like to chain several ranges and operate on them. However, 
if the chains are different lengths, the data type is 
different. This makes it hard to use in a general way. There is 
likely an alternate way to do this that I'm missing.


[snip]

Is there a different way to do this?

--Jon


One solution:

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

void main(string[] args)
{
auto x1 = ["abc", "def", "ghi"];
auto x2 = ["jkl", "mno", "pqr"];
auto x3 = ["stu", "vwx", "yz"];
auto chain1 = chain(x1, (args.length > 1) ? x2 : []);
auto chain2 = chain(x1, x2, (args.length > 1) ? x3 : []);
chain1.joiner(", ").writeln;
chain2.joiner(", ").writeln;
}


compatible types for chains of different lengths

2015-11-17 Thread Jon D via Digitalmars-d-learn
I'd like to chain several ranges and operate on them. However, if 
the chains are different lengths, the data type is different. 
This makes it hard to use in a general way. There is likely an 
alternate way to do this that I'm missing.


A short example:

$ cat chain.d
import std.stdio;
import std.range;
import std.algorithm;

void main(string[] args)
{
auto x1 = ["abc", "def", "ghi"];
auto x2 = ["jkl", "mno", "pqr"];
auto x3 = ["stu", "vwx", "yz"];
auto chain1 = (args.length > 1) ? chain(x1, x2) : chain(x1);
auto chain2 = (args.length > 1) ? chain(x1, x2, x3) : 
chain(x1, x2);

chain1.joiner(", ").writeln;
chain2.joiner(", ").writeln;
}
$ dmd chain.d
chain.d(10): Error: incompatible types for ((chain(x1, x2)) : 
(chain(x1))): 'Result' and 'string[]'
chain.d(11): Error: incompatible types for ((chain(x1, x2, x3)) : 
(chain(x1, x2))): 'Result' and 'Result'


Is there a different way to do this?

--Jon


Re: Filtering a tuple of containers with indices

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

On Tuesday, 17 November 2015 at 15:48:10 UTC, anonymous wrote:

On 17.11.2015 15:32, maik klein wrote:

[...]

[snip]

I don't quite understand how that code is supposed to work. 
Maybe there's just some detail missing, but it could also be 
that your approach can't work.


[...]


Thanks but I have one question.

.selectFromTuple!(0, 1).expand

Does this result in a copy? I avoided doing it like this because 
I was worried that I would copy every array. But I also don't 
fully understand when D will copy.



Also doing

  foreach(e;range){
e[0] = 10;
e[1] = 10.0f;
writeln("element: ",e);
  }
  foreach(e;range){
writeln("element: ",e);
  }

doesn't mutate the range at all.



Re: Filtering a tuple of containers with indices

2015-11-17 Thread anonymous via Digitalmars-d-learn

On 17.11.2015 20:46, maik klein wrote:

.selectFromTuple!(0, 1).expand

Does this result in a copy? I avoided doing it like this because I was
worried that I would copy every array. But I also don't fully understand
when D will copy.


Yes and no. It copies the Array structs, but it does not copy the 
elements of the arrays. If I remember correctly, std.container.Array 
uses reference counting, and copying them should be cheap.


By the way, do you have a good reason to go with Array!int rather than 
int[]? They're similar, but the builtin int[] may be easier to handle.



Also doing

   foreach(e;range){
 e[0] = 10;
 e[1] = 10.0f;
 writeln("element: ",e);
   }
   foreach(e;range){
 writeln("element: ",e);
   }

doesn't mutate the range at all.


You need to mark the `e` as `ref`: `foreach(ref e; range)`. Otherwise, 
it's a copy of the element, and any changes to it are forgotten at the 
end of the iteration.


But even with `ref` it doesn't work. Seems to be a bug in or a 
limitation of `zip`. Works with `lockstep`:


  auto ranges = integrals
.selectFromTuple!(0, 1).expand
.mapTuple!(a => a[]).expand;
  auto range = ranges.zip;

  import std.range: lockstep;
  foreach(ref e0, ref e1; lockstep(ranges)){
e0 = 10;
e1 = 10.0f;
  }
  foreach(e;range){
writeln("element: ",e);
  }



Re: opEquals default behaviour - poorly documented or am I missing something?

2015-11-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/17/15 3:25 PM, user123ABCabc wrote:

On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:

if (typeid(a) == typeid(b)) return a.opEquals(b);


Wow this is terrible to compare two objects in D. The line I quoted
means that two TypeInfoClass are likely to be allocated, right ?


No, those are immutable stored in the data segment. Fetching them costs 
only doing the fetch of the class info pointer.


-Steve


Re: opEquals default behaviour - poorly documented or am I missing something?

2015-11-17 Thread Ali Çehreli via Digitalmars-d-learn

On 11/17/2015 12:40 AM, MichaelZ wrote:
> In http://dlang.org/operatoroverloading.html#eqcmp it is stated that
>
> "If opEquals is not specified, the compiler provides a default version
> that does member-wise comparison."
>
> However, doesn't this only apply to structs, and not objects?

Correct. The behavior for class objects is the following algorithm on 
the same page:


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

This one:

bool opEquals(Object a, Object b)
{
if (a is b) return true;
if (a is null || b is null) return false;
if (typeid(a) == typeid(b)) return a.opEquals(b);
return a.opEquals(b) && b.opEquals(a);
}

Ali



Re: opEquals default behaviour - poorly documented or am I missing something?

2015-11-17 Thread user123ABCabc via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:

if (typeid(a) == typeid(b)) return a.opEquals(b);


Wow this is terrible to compare two objects in D. The line I 
quoted means that two TypeInfoClass are likely to be allocated, 
right ?


But usually when comparing objects one rather cares about the 
reference itself, so a comparison of the two heap addresses is 
enough in this case. (meaning same or not same instance, 
regardless of the their members values).





Re: compatible types for chains of different lengths

2015-11-17 Thread Jon D via Digitalmars-d-learn

On Tuesday, 17 November 2015 at 23:22:58 UTC, Brad Anderson wrote:


One solution:

 [snip]



Thanks for the quick response. Extending your example, here's 
another style that works and may be nicer in some cases.


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

void main(string[] args)
{
auto x1 = ["abc", "def", "ghi"];
auto x2 = ["jkl", "mno", "pqr"];
auto x3 = ["stu", "vwx", "yz"];

auto y1 = (args.length > 1) ? x1 : [];
auto y2 = (args.length > 2) ? x2 : [];
auto y3 = (args.length > 3) ? x3 : [];

chain(y1, y2, y3).joiner(", ").writeln;
}



opEquals default behaviour - poorly documented or am I missing something?

2015-11-17 Thread MichaelZ via Digitalmars-d-learn
In http://dlang.org/operatoroverloading.html#eqcmp it is stated 
that


"If opEquals is not specified, the compiler provides a default 
version that does member-wise comparison."


However, doesn't this only apply to structs, and not objects?  
The default behaviour of opEquals for objects seems to be "is".



A few paragraphs later, in 
http://dlang.org/operatoroverloading.html#compare, the 
description of the default version is repeated:

""
If overriding Object.opCmp() for classes, the class member 
function signature should look like:

...
If structs declare an opCmp member function, it should have the 
following form:

...
Note that opCmp is only used for the inequality operators; 
expressions like a == b always uses opEquals. **If opCmp is 
defined but opEquals isn't, the compiler will supply a default 
version of opEquals that performs member-wise comparison.**

""

Even here, the fact that the described default opEquals behaviour 
appears to only apply to structs is far from clear.



Or am I missing something that should be obvious?

Thanks,
-- MichaelZ


Re: Looking for a language to hang my hat on.

2015-11-17 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2015-11-16 at 22:39 +, Dan via Digitalmars-d-learn wrote:
> 
[…]
> My platform of choice is 64-bit Fedora using Code::Blocks (yes, I 
> use an IDE as a crutch). It seems that D supports this combo.

Last time I looked at Code::Blocks it couldn't do a dark theme, and the
D support was for an ancient form of D.

It would be good if we could get Kingsley's IntelliJ IDEA D plugin into
CLion.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part