Re: Visibility of variables in struct nested within a class

2013-07-08 Thread bearophile

Charles Hixson:

Is this the way things are supposed to happen?  (Changing the 
struct to a class is an OK patch, but I don't understand why it 
should either work or be necessary.)


Please show a complete very little program, and maybe someone 
will try to help you.


(Eventually it's a good idea to write a simple FAQ for D.learn, 
that also explains how to ask questions and how to give answers).


Bye,
bearophile


Re: Visibility of variables in struct nested within a class

2013-07-08 Thread bearophile
Please show a complete very little program, and maybe someone 
will try to help you.


I've seen there is code in another (broken) thread, so please 
ignore this request.


Bye,
bearophile


enforcing alias this on derived types

2013-07-08 Thread JS
I have an interface that I would like to make sure that any 
classes derived from it will use alias this, else it can 
potentially break code.


interface A(T)
{
@property T Value();
@property T Value(T value);
// need to enforce alias _value this somehow
}

class B(T) : A!T
{
private T _value;
@property T Value() { return _value; }
@property T Value(T value) { return value = _value; }
alias _value this;
// B must use alias this so B(T) behaves like type T
}


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread bearophile

Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?

Bye,
bearophile


Re: enforcing alias this on derived types

2013-07-08 Thread JS



interface A(T)
{
@property T Value();
@property T Value(T value);
// need to enforce alias Value this somehow
}

class B(T) : A!T
{
private T _value;
@property T Value() { return _value; }
@property T Value(T value) { return value = _value; }

 alias Value this;

// B must use alias this so B(T) behaves like type T
}




creating a variadic interface

2013-07-08 Thread JS


this may seem a bit nonsensical but it is just an example:

interface A(T, S...)
{
   ... Generate a getter for each type in S...
   // e.g., @property S[0] property1();
   //   @property S[1] property2();
   // 
}

I imagine I have to use a mixin template but I'm unsure how to 
create a static loop that can be used properly.


I think maybe using mixin's of mixin's is possible but I can't 
think of any simple way. Any ideas?


Re: enforcing alias this on derived types

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 08:59:16 UTC, JS wrote:
I have an interface that I would like to make sure that any 
classes derived from it will use alias this, else it can 
potentially break code.


interface A(T)
{
@property T Value();
@property T Value(T value);
// need to enforce alias _value this somehow
}

class B(T) : A!T
{
private T _value;
@property T Value() { return _value; }
@property T Value(T value) { return value = _value; }
alias _value this;
// B must use alias this so B(T) behaves like type T
}


I can't think of a neat way to do this. However,if you don't mind 
a nasty solution:


You can just force the derived class writer to write a function 
that checks. Even if they just put in a no-op, it acts as a very 
solid reminder that will also be visible to anyone else reading 
their code.


struct S{}

interface I
{
void checkForAliasThis();
}

class A : I
{
void checkForAliasThis()
{
static assert(is(typeof(this) : S));
}

S s;
alias s this;
}


Most other solutions I tried failed because the compiler 
evaluates the check (e.g. out contracts) in the interface, which 
makes the check either semantically wrong, or statically 
false/failed.


Re: enforcing alias this on derived types

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote:
Most other solutions I tried failed because the compiler 
evaluates the check (e.g. out contracts) in the interface, 
which makes the check either semantically wrong, or statically 
false/failed.


Woops, should be the contract exists in the scope of the 
interface, not the compiler evaluates the check (e.g. out 
contracts) in the interface


Re: creating a variadic interface

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 09:34:46 UTC, JS wrote:


this may seem a bit nonsensical but it is just an example:

interface A(T, S...)
{
   ... Generate a getter for each type in S...
   // e.g., @property S[0] property1();
   //   @property S[1] property2();
   // 
}

I imagine I have to use a mixin template but I'm unsure how to 
create a static loop that can be used properly.


I think maybe using mixin's of mixin's is possible but I can't 
think of any simple way. Any ideas?


Here you go :)

//just to hide the string mixin.
mixin template Getters(S ...)
{
mixin(GettersImpl!S);
}

import std.conv : to;
template GettersImpl(S ...)
{
static if(S.length == 0)
{
enum GettersImpl = ;
}
else static if(S.length == 1)
{
		enum GettersImpl = @property  ~ (S[$-1]).stringof ~  
property ~ to!string(S.length) ~ ();\n;

}
else
{
		enum GettersImpl = @property  ~ (S[$-1]).stringof ~  
property ~ to!string(S.length) ~ ();\n

   ~ GettersImpl!(S[0..$-1]);
}
}


interface A(S...)
{
mixin Getters!S;
}

class B : A!(int, long, string)
{
//if everything works, we get errors here for missing methods.
}


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 09:03:24 UTC, bearophile wrote:

Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?

Bye,
bearophile


I reckon so. It's rare to have such huge structs or classes that 
this sort of this becomes a problem for them, but massive enums 
are reasonably common.


Re: creating a variadic interface

2013-07-08 Thread JS

On Monday, 8 July 2013 at 10:16:22 UTC, John Colvin wrote:

On Monday, 8 July 2013 at 09:34:46 UTC, JS wrote:


this may seem a bit nonsensical but it is just an example:

interface A(T, S...)
{
  ... Generate a getter for each type in S...
  // e.g., @property S[0] property1();
  //   @property S[1] property2();
  // 
}

I imagine I have to use a mixin template but I'm unsure how to 
create a static loop that can be used properly.


I think maybe using mixin's of mixin's is possible but I can't 
think of any simple way. Any ideas?


Here you go :)

//just to hide the string mixin.
mixin template Getters(S ...)
{
mixin(GettersImpl!S);
}

import std.conv : to;
template GettersImpl(S ...)
{
static if(S.length == 0)
{
enum GettersImpl = ;
}
else static if(S.length == 1)
{
		enum GettersImpl = @property  ~ (S[$-1]).stringof ~  
property ~ to!string(S.length) ~ ();\n;

}
else
{
		enum GettersImpl = @property  ~ (S[$-1]).stringof ~  
property ~ to!string(S.length) ~ ();\n

   ~ GettersImpl!(S[0..$-1]);
}
}


interface A(S...)
{
mixin Getters!S;
}

class B : A!(int, long, string)
{
//if everything works, we get errors here for missing methods.
}




I guess you beat me too it but I came up with something very 
similar which I think works too(uses foreach instead of 
recursion)..



mixin template a(T...)
{
template b(TT...)
{
static string eval()
{
string s;
int i = 0;
foreach(t; TT)
s = @property ~(t).stringof~ 
Name~to!string(i++)~();\n;
return s;
}
enum b = eval();
}

mixin(mixin(b!T););

}


Re: enforcing alias this on derived types

2013-07-08 Thread JS

On Monday, 8 July 2013 at 09:55:29 UTC, John Colvin wrote:

On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote:
Most other solutions I tried failed because the compiler 
evaluates the check (e.g. out contracts) in the interface, 
which makes the check either semantically wrong, or statically 
false/failed.


Woops, should be the contract exists in the scope of the 
interface, not the compiler evaluates the check (e.g. out 
contracts) in the interface


Hopefully there is a cleaner way but this beats nothing... thanks.


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread Simen Kjaeraas

On 2013-07-08, 11:03, bearophile wrote:


Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?


Filed:

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

And created a pull request:

https://github.com/D-Programming-Language/phobos/pull/1400

--
Simen


Re: creating a variadic interface

2013-07-08 Thread Artur Skawina
On 07/08/13 13:25, JS wrote:
 mixin template a(T...)
 {
 template b(TT...)
 {
 static string eval()
 {
 string s;
 int i = 0;
 foreach(t; TT)
 s = @property ~(t).stringof~ Name~to!string(i++)~();\n;
 return s;
 }
 enum b = eval();
 }
 
 mixin(mixin(b!T););
 
 }

It won't work if one of the types isn't already available inside the
template - the .stringof will give you the name, but the mixin
will fail; to avoid this you can use `T[0]` etc as the type directly,
w/o stringifying.

Something like this would also work:

   template evalExpMap(string C, string F, A...) {
  enum evalExpMap = {
 import std.array, std.conv;
 string s, l;
 static if (is(typeof(A))) alias B = typeof(A);
else   alias B = A;
 foreach (I, _; B) {
auto r = replace( replace(F, %s, A[I].stringof),
 %d, to!string(I));
l ~= (I?, :) ~ r;
s ~=   r ~ ;\n;
 }
 return replace(replace(C, %...;, s), %..., l);
  }();
   }

   interface A(T, S...) {
  mixin(evalExpMap!(q{%...;}, q{@property S[%d]/*%s*/ property%d()}, S));
   }

   class C : A!(int, long, string) { /* Needs `propertyN` implementations. */ }


It expands to:

   interface A(T, S...) {   
  @property S[0]/*long*/ property0();
  @property S[1]/*string*/ property1();
   }

and is more readable (once one knows what that helper does ;) ).

In real code, the property names may need to be more configurable;
but I'm not sure what you want to use this for. The helper rewrites
every %s pattern - type-name and every %d - index; maybe that
is enough.

artur


Re: creating a variadic interface

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote:
It won't work if one of the types isn't already available 
inside the

template - the .stringof will give you the name, but the mixin
will fail;


When would the type not be available?


Re: enforcing alias this on derived types

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 11:37:31 UTC, JS wrote:

On Monday, 8 July 2013 at 09:55:29 UTC, John Colvin wrote:

On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote:
Most other solutions I tried failed because the compiler 
evaluates the check (e.g. out contracts) in the interface, 
which makes the check either semantically wrong, or 
statically false/failed.


Woops, should be the contract exists in the scope of the 
interface, not the compiler evaluates the check (e.g. out 
contracts) in the interface


Hopefully there is a cleaner way but this beats nothing... 
thanks.


There could be merit in adding more sophisticated requirements in 
base classes and interfaces. Currently, AFAIK there isn't one.


inherited static invariant() {} would be one possibility, run 
at compile-time. Perhaps only run on classes that can be 
explicitly instantiated, but declared in any class/interface 
further up the inheritance tree. All static invariants would have 
to pass, in derived and base classes, i.e. it's a tighten-only 
contract like out.


It's a unittest of sorts, but compile-time and fully class-aware.


Re: creating a variadic interface

2013-07-08 Thread Artur Skawina
On 07/08/13 15:12, John Colvin wrote:
 On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote:
 It won't work if one of the types isn't already available inside the
 template - the .stringof will give you the name, but the mixin
 will fail;
 
 When would the type not be available?
 

   auto as() { struct An {} return An(); }
   template A(T) {}

   A!(typeof(as()))

T.stringof inside 'A' will return a name, but there's no way to map
it back to a type.
The 'A' template can be instantiated from a different module - the type
won't be available in A if A doesn't import that other module.
The type may be private, then even an import in A (or any parent scope)
won't help.

artur 


Re: creating a variadic interface

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote:

On 07/08/13 15:12, John Colvin wrote:

On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote:
It won't work if one of the types isn't already available 
inside the

template - the .stringof will give you the name, but the mixin
will fail;


When would the type not be available?



   auto as() { struct An {} return An(); }
   template A(T) {}

   A!(typeof(as()))

T.stringof inside 'A' will return a name, but there's no way to 
map

it back to a type.
The 'A' template can be instantiated from a different module - 
the type

won't be available in A if A doesn't import that other module.
The type may be private, then even an import in A (or any 
parent scope)

won't help.

artur


Ah ok, I see.

In those cases you're not going to be able to declare a function 
that explicitly uses that type anyway, whether handwritten or 
generated as above.


Re: creating a variadic interface

2013-07-08 Thread Artur Skawina
On 07/08/13 16:12, John Colvin wrote:
 On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote:
 On 07/08/13 15:12, John Colvin wrote:
 On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote:
 It won't work if one of the types isn't already available inside the
 template - the .stringof will give you the name, but the mixin
 will fail;

 When would the type not be available?


auto as() { struct An {} return An(); }
template A(T) {}

A!(typeof(as()))

 T.stringof inside 'A' will return a name, but there's no way to map
 it back to a type.
 The 'A' template can be instantiated from a different module - the type
 won't be available in A if A doesn't import that other module.
 The type may be private, then even an import in A (or any parent scope)
 won't help.
 
 Ah ok, I see.
 
 In those cases you're not going to be able to declare a function that 
 explicitly uses that type anyway, whether handwritten or generated as above.

   struct A(T) { T f(T a) { return a.blah; } }

artur


Re: creating a variadic interface

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 14:25:17 UTC, Artur Skawina wrote:

On 07/08/13 16:12, John Colvin wrote:

On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote:

On 07/08/13 15:12, John Colvin wrote:

On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote:
It won't work if one of the types isn't already available 
inside the
template - the .stringof will give you the name, but the 
mixin

will fail;


When would the type not be available?



   auto as() { struct An {} return An(); }
   template A(T) {}

   A!(typeof(as()))

T.stringof inside 'A' will return a name, but there's no way 
to map

it back to a type.
The 'A' template can be instantiated from a different module 
- the type

won't be available in A if A doesn't import that other module.
The type may be private, then even an import in A (or any 
parent scope)

won't help.


Ah ok, I see.

In those cases you're not going to be able to declare a 
function that explicitly uses that type anyway, whether 
handwritten or generated as above.


   struct A(T) { T f(T a) { return a.blah; } }

artur


Right So the problem is that there's no mapping available
between the type name and the type, not that the type itself is
unavailable for use. Don't know why I'm being so slow with this
today...must be the heat!


Re: Allocating a slice object

2013-07-08 Thread Marco Leise
Am Thu, 04 Jul 2013 15:54:48 +0200
schrieb monarch_dodra monarchdo...@gmail.com:

  This should work:
 
  int[] *pSlice = (new int[][1]).ptr;
 
  -Steve
 
 Hum... That would allocate a dynamic array of slices though 
 right? There'd be the Appendable overhead for just one element...

No, it allocates a static one-element array of int[]s and then
returns the pointer to the first and only element. It's
similar to wrapping it in a struct. So +1 for that solution.

-- 
Marco



Re: Allocating a slice object

2013-07-08 Thread monarch_dodra

On Monday, 8 July 2013 at 15:43:21 UTC, Marco Leise wrote:

Am Thu, 04 Jul 2013 15:54:48 +0200
schrieb monarch_dodra monarchdo...@gmail.com:


 This should work:

 int[] *pSlice = (new int[][1]).ptr;

 -Steve

Hum... That would allocate a dynamic array of slices though 
right? There'd be the Appendable overhead for just one 
element...


No, it allocates a static one-element array of int[]s and then
returns the pointer to the first and only element. It's
similar to wrapping it in a struct. So +1 for that solution.


I don't think that allocates a static array, it's just an 
alternative syntax for dynamic array allocation. The fact that 
you are extracting a pointer from it and it only has a single 
element doesn't mean it is a static array.


//
void main()
{
int[]* pSlice = (new int[][4]).ptr;
writeln(pSlice[0 .. 4].capacity);
}
//

This prints 7 for me, which would simply be impossible for new 
was allocating a static array.


Re: enforcing alias this on derived types

2013-07-08 Thread Marco Leise
Am Mon, 08 Jul 2013 10:59:14 +0200
schrieb JS js.m...@gmail.com:

 I have an interface that I would like to make sure that any 
 classes derived from it will use alias this, else it can 
 potentially break code.
 
 interface A(T)
 {
  @property T Value();
  @property T Value(T value);
  // need to enforce alias _value this somehow
 }
 
 class B(T) : A!T
 {
  private T _value;
  @property T Value() { return _value; }
  @property T Value(T value) { return value = _value; }
  alias _value this;
  // B must use alias this so B(T) behaves like type T
 }

Interfaces only declare functions and have no state. What you
do looks like you actually want to give the interface state
through the alias ... this crutch. This is where you
use abstract classes if possible:

abstract class A(T)
{
 private T _value;
 @property T Value() { return _value; }
 @property T Value(T value) { return value = _value; }
 alias _value this;
}

class B(T) : A!T
{
}

I have only used alias ... this with structs and not
tested this code. Generally I try to avoid mixing the
realms of value types and class types in D like you
are trying to. It gives me a bad gut feeling.

In the OOP world I'd say, just use obj.Value everywhere
you want your object to work like type T.

-- 
Marco



Re: GitHub behind proxy servers among other questions

2013-07-08 Thread JohnnyK

On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote:

On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote:

Hi all,
 I have searched everywhere over the Internet and I have yet 
to find a way to clone a project using git when my workstation 
is behind a company proxy.  Can you guys clone your projects 
to a single zip file that I can download?  This would be 
easier instead of working with some strange command-line tool 
that does not recognize modern networks.  Honestly I just need 
the DWT binary with the help files so I can use the api.  I 
have spent weeks searching for a way to download DWT to my 
windows workstation at work and have yet figured out how to 
make GIT work.


Git provides a download by zip; Right side, bottom.

This is what I found on getting Git to work with a proxy:

http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy


I appreciate your response.  I have tried these.  I think the 
real issue is that I am not sure on the IP and port needed for 
the proxy here at work.  The company uses WPAD in the browser and 
I cannot figure out what the IP and port the browser is using to 
connect through the proxy.  If I knew that I probably could make 
it work.  It would be nice if GitHUB would change their Downlaod 
Zip button such that it does a recursive zip to include all the 
subfolders.


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread Dicebot

On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote:

Hi all,
  I have searched everywhere over the Internet and I have yet 
to find a way to clone a project using git when my workstation 
is behind a company proxy.  Can you guys clone your projects to 
a single zip file that I can download?  This would be easier 
instead of working with some strange command-line tool that 
does not recognize modern networks.  Honestly I just need the 
DWT binary with the help files so I can use the api.  I have 
spent weeks searching for a way to download DWT to my windows 
workstation at work and have yet figured out how to make GIT 
work.


git can clone via HTTP(S):
git clone http://github.com/D-Programming-Language/dmd.git


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote:

On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote:

On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote:

Hi all,
I have searched everywhere over the Internet and I have yet 
to find a way to clone a project using git when my 
workstation is behind a company proxy.  Can you guys clone 
your projects to a single zip file that I can download?  This 
would be easier instead of working with some strange 
command-line tool that does not recognize modern networks.  
Honestly I just need the DWT binary with the help files so I 
can use the api.  I have spent weeks searching for a way to 
download DWT to my windows workstation at work and have yet 
figured out how to make GIT work.


Git provides a download by zip; Right side, bottom.

This is what I found on getting Git to work with a proxy:

http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy


I appreciate your response.  I have tried these.  I think the 
real issue is that I am not sure on the IP and port needed for 
the proxy here at work.  The company uses WPAD in the browser 
and I cannot figure out what the IP and port the browser is 
using to connect through the proxy.  If I knew that I probably 
could make it work.  It would be nice if GitHUB would change 
their Downlaod Zip button such that it does a recursive zip to 
include all the subfolders.


I would just ssh to somewhere outside the firewall, git clone 
there, tar the folder, then scp it back. Assuming that is 
possible through your firewall.


If you're on windows then there are the always useful putty and 
winscp to do your ssh and scp work respectively.


Help me investigate a bug to file it.

2013-07-08 Thread monarch_dodra
Yeah, not very exiting, but I just spent an hour tracking down 
the fix, but now I'd like to track down *what* was making it 
break (my fix was luck). This should help Kenji (or others) 
have an easier time fixing it :)


Also, I'm only repro'ing this on linux...

I think there are two things involved here. The first, is 
accessing members of a struct for a static if, in a global scope:


//
import std.stdio;
import std.range;

struct S(R)
{
R _input;
void foo()
{
static assert(is(typeof(_input[size_t.max .. 
size_t.max]))); //ok

static assert(is(typeof(_input[size_t.max .. $]))); //ok
}
static assert(is(typeof(_input[size_t.max .. size_t.max]))); 
//ok

static assert(is(typeof(_input[size_t.max .. $]))); //NOPE!
}

void main()
{
auto k = iota(0, 1).cycle();
S!(typeof(k)) s;
}
//

As you can see, the static if behaves differently in a function, 
or in the raw body of the struct. Is this normal? Anybody know 
what is going on exactly? I'm trying to get more context here...


---

Second, one of the things I found strange was that only *1* of 
the two assertions failed. basically, _input[0 .. 1] is fair 
game, yet, _input[0 .. $] is not? What gives? I put my nose in 
cycles's opDollar. It is written like this:


//
private static struct DollarToken {}
DollarToken opDollar()
{
return DollarToken.init;
}
//
Nothing special about it. Just a function that returns an object. 
Declaring it const/nothrow/@safe *and* pure does not fix the 
problem...


*HOWEVER* declaring it as a manifest constant *does* fix the 
issue:

//
private static struct DollarToken {}
enum opDollar = DollarToken.init;
//



I think I've run into global static ifs using members issues 
before, but just figured I wasn't allowed to use them. 
Apparently, to issue is more subtle than this. I have *no* idea 
how to file this, I have no idea what the rules are. Any insight?


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread monarch_dodra

On Monday, 8 July 2013 at 16:49:05 UTC, John Colvin wrote:

On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote:

On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote:

On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote:

Hi all,
I have searched everywhere over the Internet and I have yet 
to find a way to clone a project using git when my 
workstation is behind a company proxy.  Can you guys clone 
your projects to a single zip file that I can download?  
This would be easier instead of working with some strange 
command-line tool that does not recognize modern networks.  
Honestly I just need the DWT binary with the help files so I 
can use the api.  I have spent weeks searching for a way to 
download DWT to my windows workstation at work and have yet 
figured out how to make GIT work.


Git provides a download by zip; Right side, bottom.

This is what I found on getting Git to work with a proxy:

http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy


I appreciate your response.  I have tried these.  I think the 
real issue is that I am not sure on the IP and port needed for 
the proxy here at work.  The company uses WPAD in the browser 
and I cannot figure out what the IP and port the browser is 
using to connect through the proxy.  If I knew that I probably 
could make it work.  It would be nice if GitHUB would change 
their Downlaod Zip button such that it does a recursive zip to 
include all the subfolders.


I would just ssh to somewhere outside the firewall, git clone 
there, tar the folder, then scp it back. Assuming that is 
possible through your firewall.


If you're on windows then there are the always useful putty and 
winscp to do your ssh and scp work respectively.


Well, the thing to remember is that he did say company, so such 
approaches to bypass a firewall could very well be a violation of 
his IT policies. I know doing this would be *major* violation of 
my companie's policies, and could be cause for termination.


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread Jesse Phillips

On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote:

It would be nice if GitHUB would change their Downlaod Zip 
button such that it does a recursive zip to include all the 
subfolders.


Ehhh, well that is useless. Sorry I couldn't hook you up with a 
solution.


Re: Help me investigate a bug to file it.

2013-07-08 Thread Artur Skawina
On 07/08/13 19:54, monarch_dodra wrote:
 struct S(R)
 {
 R _input;
 void foo()
 {
 static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok
 static assert(is(typeof(_input[size_t.max .. $]))); //ok
 }
 static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok
 static assert(is(typeof(_input[size_t.max .. $]))); //NOPE!
 }

 As you can see, the static if behaves differently in a function, or in the 
 raw body of the struct. Is this normal? Anybody know what is going on 
 exactly? I'm trying to get more context here...
 
 ---
 
 Second, one of the things I found strange was that only *1* of the two 
 assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. 
 $] is not? What gives? I put my nose in cycles's opDollar. It is written like 
 this:

Did you really mean size_t.*max* above?

Anyway, when '$' is rewritten as 'opDollar' and that is defined
as a non-static method, it would be surprising if calling the
method did work w/o any context pointer...

 //
 private static struct DollarToken {}
 DollarToken opDollar()
 {
 return DollarToken.init;
 }
 //
 Nothing special about it. Just a function that returns an object. Declaring 
 it const/nothrow/@safe *and* pure does not fix the problem...
 
 *HOWEVER* declaring it as a manifest constant *does* fix the issue:
 //
 private static struct DollarToken {}
 enum opDollar = DollarToken.init;
 //

Does declaring the opDollar function as `static` fix it?

artur


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 18:09:44 UTC, monarch_dodra wrote:

On Monday, 8 July 2013 at 16:49:05 UTC, John Colvin wrote:

On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote:

On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote:

On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote:

Hi all,
I have searched everywhere over the Internet and I have yet 
to find a way to clone a project using git when my 
workstation is behind a company proxy.  Can you guys clone 
your projects to a single zip file that I can download?  
This would be easier instead of working with some strange 
command-line tool that does not recognize modern networks.  
Honestly I just need the DWT binary with the help files so 
I can use the api.  I have spent weeks searching for a way 
to download DWT to my windows workstation at work and have 
yet figured out how to make GIT work.


Git provides a download by zip; Right side, bottom.

This is what I found on getting Git to work with a proxy:

http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy


I appreciate your response.  I have tried these.  I think the 
real issue is that I am not sure on the IP and port needed 
for the proxy here at work.  The company uses WPAD in the 
browser and I cannot figure out what the IP and port the 
browser is using to connect through the proxy.  If I knew 
that I probably could make it work.  It would be nice if 
GitHUB would change their Downlaod Zip button such that it 
does a recursive zip to include all the subfolders.


I would just ssh to somewhere outside the firewall, git clone 
there, tar the folder, then scp it back. Assuming that is 
possible through your firewall.


If you're on windows then there are the always useful putty 
and winscp to do your ssh and scp work respectively.


Well, the thing to remember is that he did say company, so 
such approaches to bypass a firewall could very well be a 
violation of his IT policies. I know doing this would be 
*major* violation of my companie's policies, and could be cause 
for termination.


I don't see how it is problematic? The firewall doesn't allow a 
particular type of connection, so you cache the result somewhere 
else and then access it via something that is allowed.


It's the same as downloading the zip file from github, only 
you're doing the zipping yourself, then using scp to do the 
download instead of http.


Is it common to have ssh connections banned in the IT policy but 
*not* blocked by the firewall?


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread JohnnyK

On Monday, 8 July 2013 at 18:34:33 UTC, Jesse Phillips wrote:

On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote:

It would be nice if GitHUB would change their Downlaod Zip 
button such that it does a recursive zip to include all the 
subfolders.


Ehhh, well that is useless. Sorry I couldn't hook you up with a 
solution.


Thanks for all the input.  I found a tool called NTLMAPS at 
http://ntlmaps.sourceforge.net/ which allows one to create a pass 
through proxy which understands NTLM proxy servers and are able 
to connect and forward HTTP requests and return responses so long 
story short I can now git clone as I need to NTLMAPS config file 
is pretty easy to configure with your proxy authentication 
information.  However I did have to change the following 
named/value pairs.


from this

LM_PART:1
NT_PART:0

# Highly experimental option. See research.txt for details.
# LM - 0682
# NT - 0582
# LM + NT - 0782
NTLM_FLAGS: 0682

to this

LM_PART:1
NT_PART:1

# Highly experimental option. See research.txt for details.
# LM - 0682
# NT - 0582
# LM + NT - 0782
NTLM_FLAGS: 0782

The proxy that I am behind was not happy until I did that.  
Anyway it is working now and I hope this post serves to help 
others with the same issue.


also note that I had to use http:// in place of git:// in the git 
paths and in the case of DWT I had to go to every major folder 
and git clone them individually because for some reason git 
wanted to use git:// for subsequent requests.  It is strange that 
it did not do that for the Win-Res folder just for the others.  
So I had to do commands like the following


C:\GITClonescd dwt

C:\GITClones\dwtgit clone --recursive 
http://github.com/d-widget-toolkit/base.g

it
Cloning into 'base'...
remote: Counting objects: 806, done.
remote: Compressing objects: 100% (326/326), done.
remote: Total 806 (delta 402), reused 803 (delta 401)
Receiving objects: 100% (806/806), 310.62 KiB | 261.00 KiB/s, 
done.

Resolving deltas: 100% (402/402), done.

C:\GITClones\dwtgit clone --recursive 
http://github.com/d-widget-toolkit/org.ec

lipse.swt.gtk.linux.x86.git
Cloning into 'org.eclipse.swt.gtk.linux.x86'...
remote: Counting objects: 1691, done.
remote: Compressing objects: 100% (634/634), done.
remote: Total 1691 (delta 951), reused 1659 (delta 944)
Receiving objects: 100% (1691/1691), 1.71 MiB | 361.00 KiB/s, 
done.

Resolving deltas: 100% (951/951), done.

C:\GITClones\dwtgit clone --recursive 
http://github.com/d-widget-toolkit/org.ec

lipse.swt.win32.win32.x86.git
Cloning into 'org.eclipse.swt.win32.win32.x86'...


The only other thing I wish git could do is compile it for me so 
that I wouldn't have too but until we have HDgit I guess I am 
stuck with all this command line busy work.  Thanks again for 
every ones time.


Re: GitHub behind proxy servers among other questions

2013-07-08 Thread JohnnyK

On Monday, 8 July 2013 at 19:37:08 UTC, JohnnyK wrote:
Another thing about GitHub's Download Zip button and this process 
as a whole.  While the Download Zip button does allow you to 
download the master folders with recursive directories I do find 
it somewhat cumbersome or should I say awkward since you have to 
extract these in their correct locations upon download.  This is 
not good when you are trying to follow someones instructions on 
how to download, build, and install their wares.  I just don't 
get git?  Just compile the code and put a binary up there for 
people to use.  If I want to contribute to the code base then I 
will I guess go through all this hassle but for those of us not 
smart enough to contribute and just want to use it show me the 
binary please.  In the amount of time it is taking to get this 
stuff I could have made major strides at building my own.  Also I 
don't know what this fragmented downloading is going to do in the 
future when I want an updated version of the software.  Please 
remember many of us are simpletons and don't use all these fancy 
version control systems and just need the binary so that we can 
use it.  I guess you could say we are your customers and not your 
contributors.  Please everyone in the D community try and follow 
the KISS methodology and if you do I bet you could get many more 
users of your wares and not people banging their heads until they 
give up.  Yeah I was only 2 clicks away from giving up on this 
whole D thing thinking it was just too darned hard to make it 
worth my while.  Who knows I still may give up since I have not 
attempted to compile it yet.  I think I will wait until tomorrow 
before I try to tackle that part of the destruction's.  For now I 
think I have it downloaded.  BTW did I mention that I really hate 
git and compiling other people's code just to use an edit box and 
button on a dialog???


Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki
I'm trying to implement rational numbers with fully functioning 
comparison operators, but I can't seem to figure out why I'm 
getting this error and any help would be appreciated:


Error: cannot cast from object.Object to Rat

The code I have is as follows:

int opCmp( Object o ) {
Rat other = cast(Rat) o; --- this line throws the error
…
//stuff to return -1, 0, or 1 to opCmp with rational 
numbers for , =, etc.

…
}

Thanks to anyone who can help!


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Monday, July 08, 2013 23:21:59 Ugbar Ikenaki wrote:
 I'm trying to implement rational numbers with fully functioning
 comparison operators, but I can't seem to figure out why I'm
 getting this error and any help would be appreciated:
 
 Error: cannot cast from object.Object to Rat
 
 The code I have is as follows:
 
 int opCmp( Object o ) {
   Rat other = cast(Rat) o; --- this line throws the error
  …
  //stuff to return -1, 0, or 1 to opCmp with rational
 numbers for , =, etc.
  …
 }
 
 Thanks to anyone who can help!

You're going to need to provide more code than that. Without knowing anything 
about Rat, we can't help you.

On a side note, I point out that talking about compiler errors as being 
thrown is going to cause confusion, as throwing is something completely 
different.

- Jonathan M Davis


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki

Also…Rat is a struct, not a class. Herein might lie the problem.


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki

Thanks for the quick response!

Here is the initialization code for my Rat struct. I created a 
GCD function that I've tested to work fine:


import std.stdio, std.exception;

struct Rat {
private long n; //Numerator
private long d; //Denominator



public this( long numerator, long denominator ) {
		enforce( denominator != 0, Error. Denominator can not be 0. 
(Rat.this));


//Default 0-value Rat object
if( numerator == 0 || numerator == -0 ) {
n = 0;
d = 1;

} else {
//Assign appropriates signs (+ / -) to numerator
// -x/-y
if( numerator  0  denominator  0 ) {
numerator = -numerator;
denominator = -denominator;
// x/-y
} else if( numerator  0  denominator  0 ) {
numerator = -numerator;
denominator = -denominator;
}

//Find GCD of numerator and denominator
long gcd = gcd( numerator, denominator );

			//Return reduced fraction of numerator and denominator 
(invariant)

n = numerator / gcd;
d = denominator / gcd;
}
}



The following is the code to override the opCmp function:


int opCmp( Object o ) {
Rat other = cast(Rat) o;

long num1 = n;
long den1 = d;
long num2 = other.n;
long den2 = other.d;

//If denominators are not equal to each other...
if( den1 != den2 ) {
			//Set denominators equal to each other (with corresponding 
numerators)

num1 *= den2;
den1 *= den2;

if(den2  den1) {
num2 *= (den1 / den2);
den2 *= (den1 / den2);
} else {
num2 *= (den2 / den1);
den2 *= (den2 / den1);
}

//Return opCmp int value (-1, 0, 1)
if( num1 - num2  0 ) {
return -1;
} else if( num1 - num2 == 0 ) {
return 0;
} else {  //if( num1 - num2  0 )
return 1;
}

//If denominators are equal to each other...
} else {
//Less than
if( num1 - num2  0 ) {
return -1;
//Equal to
} else if( num1 - num2 == 0 ) {
return 0;
//Greater than
} else {  //if( num1 - num2  0 )
return 1;
}
}
}


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Monday, July 08, 2013 23:31:14 Ugbar Ikenaki wrote:
 Also…Rat is a struct, not a class. Herein might lie the problem.

So, this is Rat's opCmp, correct? If it's a struct, it makes no sense for it 
to take an Object. Object is the base class for all classes and has nothing to 
do with structs. opCmp needs to take Rat, not Object. And to be fully 
functional, you might need to have a ref overload as well (since sometimes the 
compiler and runtime get overly picky about exact signatures - which is slowly 
getting fixed fortunately). So, something like this should work:

int opCmp(Rat other)
{
return this.opCmp(other);
}

int opCmp(ref Rat other)
{
//do stuff for comparison
}

- Jonathan M Davis


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ali Çehreli

On 07/08/2013 02:21 PM, Ugbar Ikenaki wrote:

I'm trying to implement rational numbers with fully functioning
comparison operators, but I can't seem to figure out why I'm getting
this error and any help would be appreciated:

Error: cannot cast from object.Object to Rat

The code I have is as follows:

int opCmp( Object o ) {
 Rat other = cast(Rat) o; --- this line throws the error
 …
 //stuff to return -1, 0, or 1 to opCmp with rational numbers
for , =, etc.
 …
}

Thanks to anyone who can help!


Yeah, the signature of opCmp is different for structs so you don't need 
to cast.


Once you have the subtraction defined, opCmp can be as simple as the 
following:


/* Sort order operator: Returns a negative value if this
 * fraction is before, a positive value if this fraction
 * is after, and zero if both fractions have the same sort
 * order. */
int opCmp(const ref Fraction rhs) const
{
immutable result = this - rhs;
/* Being a long, num cannot be converted to int
 * automatically; it must be converted explicitly by
 * 'to' (or cast). */
return to!int(result.num);
}

I have a couple of chapters that go over operator overloading.

Operator Overloading:

  http://ddili.org/ders/d.en/operator_overloading.html

Object is specifically for classes:

  http://ddili.org/ders/d.en/object.html

Ali



Re: Help me investigate a bug to file it.

2013-07-08 Thread monarch_dodra

On Monday, 8 July 2013 at 18:55:30 UTC, Artur Skawina wrote:

On 07/08/13 19:54, monarch_dodra wrote:

struct S(R)
{
R _input;
void foo()
{
static assert(is(typeof(_input[size_t.max .. 
size_t.max]))); //ok
static assert(is(typeof(_input[size_t.max .. $]))); 
//ok

}
static assert(is(typeof(_input[size_t.max .. 
size_t.max]))); //ok

static assert(is(typeof(_input[size_t.max .. $]))); //NOPE!
}


As you can see, the static if behaves differently in a 
function, or in the raw body of the struct. Is this normal? 
Anybody know what is going on exactly? I'm trying to get more 
context here...


---

Second, one of the things I found strange was that only *1* of 
the two assertions failed. basically, _input[0 .. 1] is fair 
game, yet, _input[0 .. $] is not? What gives? I put my nose in 
cycles's opDollar. It is written like this:


Did you really mean size_t.*max* above?


Yeah. It's not a runtime test. In this case, I *also* need to 
make sure that the slie operation accepts a size_t arg. If I use 
size_t.min, it statically evaluates to zero, so the test becomes 
sens-less: saying fun(size_t.min) works doesn't actually 
guarantee you can pass a size_t: it may actually only accepts 
ubytes or short indexing.


But I guess that is a detail in the scope of the original problem.


Anyway, when '$' is rewritten as 'opDollar' and that is defined
as a non-static method, it would be surprising if calling the
method did work w/o any context pointer...


But, the context pointer *should* be defined as whatever the 
owner of the indexing/slicing object is, no? In this case, it's 
simply _input. It has nothing to do with the this pointer being 
available...


If anything, it kind of worries me about *what* the 
implementation is doing with the this pointer, but I haven't been 
able to trick it into calling a wrong function.



Does declaring the opDollar function as `static` fix it?

artur


Yes. It does fix it. I think you put your finger exactly on where 
the issue is. I'll report it in the morning. Thank you for 
participating :)


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread H. S. Teoh
On Mon, Jul 08, 2013 at 02:42:30PM -0700, Jonathan M Davis wrote:
 On Monday, July 08, 2013 23:31:14 Ugbar Ikenaki wrote:
  Also…Rat is a struct, not a class. Herein might lie the problem.
 
 So, this is Rat's opCmp, correct? If it's a struct, it makes no sense
 for it to take an Object. Object is the base class for all classes and
 has nothing to do with structs. opCmp needs to take Rat, not Object.
 And to be fully functional, you might need to have a ref overload as
 well (since sometimes the compiler and runtime get overly picky about
 exact signatures - which is slowly getting fixed fortunately). So,
 something like this should work:
 
 int opCmp(Rat other)
 {
 return this.opCmp(other);
 }
 
 int opCmp(ref Rat other)
[...]

The second overload above should be:

int opCmp(ref const Rat other) const

otherwise the typeinfo of Rat will be wrong, and using Rat in AA's will
not work correctly. (DMD is very picky about the exact signature of
opCmp when it's generating typeinfos -- as I found out yesterday.)


T

-- 
I think the conspiracy theorists are out to get us...


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki
Wow! You guys are fast and helpful! Thank you Jonathan and Ali! I 
already got it to work, and Ali, your book is great! I've read 
about the first 150 pages. I'll check out those operator 
overloading chapters for sure.


-U


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki

And thanks for that pointer, too, H.S.


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Ugbar Ikenaki

Here's one more question:

Before I knew that opEquals existed, I tried overloading the 
equality expressions (== and !=) in opBinary using the code 
below. It worked. Why would the overloaded opBinary version get 
called if the equality expressions are held in opEquals? I'm just 
interested in knowing how dmd chooses where to take an expression 
from if it lies in multiple places (e.g. == in opEquals and 
opBinary), even if what I did was just add the == operator to 
opBinary. (Is that what I did there?)


   override bool opBinary( string op ) ( Rect r ) if( op == 
== ) {

//Check if rectangle coordinates are equal
		if( left == r.left  right == r.right  top == r.top  
bottom == r.bottom ) {

return true;
} else {
return false;
}
}


Thanks!


Re: Help me investigate a bug to file it.

2013-07-08 Thread Artur Skawina
On 07/08/13 23:45, monarch_dodra wrote:
 On Monday, 8 July 2013 at 18:55:30 UTC, Artur Skawina wrote:
 On 07/08/13 19:54, monarch_dodra wrote:
 struct S(R)
 {
 R _input;
 void foo()
 {
 static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok
 static assert(is(typeof(_input[size_t.max .. $]))); //ok
 }
 static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok
 static assert(is(typeof(_input[size_t.max .. $]))); //NOPE!
 }

 As you can see, the static if behaves differently in a function, or in the 
 raw body of the struct. Is this normal? Anybody know what is going on 
 exactly? I'm trying to get more context here...

 ---

 Second, one of the things I found strange was that only *1* of the two 
 assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. 
 $] is not? What gives? I put my nose in cycles's opDollar. It is written 
 like this:

 Did you really mean size_t.*max* above?
 
 Yeah. It's not a runtime test. In this case, I *also* need to make sure that 
 the slie operation accepts a size_t arg. If I use size_t.min, it statically 
 evaluates to zero, so the test becomes sens-less: saying fun(size_t.min) 
 works doesn't actually guarantee you can pass a size_t: it may actually only 
 accepts ubytes or short indexing.

Didn't think of that; these implicit narrowing conversion can be, umm,
surprising. But as long as the right overload gets picked, I guess
they're safe. Thanks for the explanation.


 Anyway, when '$' is rewritten as 'opDollar' and that is defined
 as a non-static method, it would be surprising if calling the
 method did work w/o any context pointer...
 
 But, the context pointer *should* be defined as whatever the owner of the 
 indexing/slicing object is, no? In this case, it's simply _input. It has 
 nothing to do with the this pointer being available...
 
 If anything, it kind of worries me about *what* the implementation is doing 
 with the this pointer, but I haven't been able to trick it into calling a 
 wrong function.

It's just like

   struct S {
  auto opDollar() { return 42; }
  enum a = opDollar();
   }

This can't work - there is no S object to call the method with.

  enum a = S.init.opDollar();

would work, just as making the method static.


 Does declaring the opDollar function as `static` fix it?
 
 Yes. It does fix it. I think you put your finger exactly on where the issue 
 is. I'll report it in the morning. Thank you for participating :)

Thank you for still trying to improve the std lib.
I gave up on using it, other than for toy examples, long time ago.
Hopefully it will be usable at some point.

artur


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Tuesday, July 09, 2013 00:35:32 Ugbar Ikenaki wrote:
 Here's one more question:
 
 Before I knew that opEquals existed, I tried overloading the
 equality expressions (== and !=) in opBinary using the code
 below. It worked. Why would the overloaded opBinary version get
 called if the equality expressions are held in opEquals? I'm just
 interested in knowing how dmd chooses where to take an expression
 from if it lies in multiple places (e.g. == in opEquals and
 opBinary), even if what I did was just add the == operator to
 opBinary. (Is that what I did there?)
 
 override bool opBinary( string op ) ( Rect r ) if( op ==
 == ) {
   //Check if rectangle coordinates are equal
   if( left == r.left  right == r.right  top == r.top 
 bottom == r.bottom ) {
   return true;
   } else {
   return false;
   }
   }
 
 
 Thanks!

I don't believe that that will ever work. If you want to overload == and !=, 
use opEquals. opBinary isn't used for that. Look at 
http://dlang.org/operatoroverloading.html if you want to see which function to 
use to overload for each operator.

- Jonathan M Davis


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread H. S. Teoh
On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote:
 Here's one more question:
 
 Before I knew that opEquals existed, I tried overloading the
 equality expressions (== and !=) in opBinary using the code below.
 It worked. Why would the overloaded opBinary version get called if
 the equality expressions are held in opEquals?
[...]

I doubt opBinary was actually called. Probably what happened was that ==
defaulted to the built-in implementation of opEquals, which simply
performs a bitwise comparison of the struct/class, and it just so
happened that it was close to (or the same) as what you intended.

Basically, when you write x==y, the compiler looks for opEquals and
opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
neither are found, then the compiler generates a default implementation
of opEquals, which basically does a bitwise comparison of x and y.


T

-- 
Arise, you prisoners of Windows
Arise, you slaves of Redmond, Wash,
The day and hour soon are coming
When all the IT folks say Gosh!
It isn't from a clever lawsuit
That Windowsland will finally fall,
But thousands writing open source code
Like mice who nibble through a wall.
-- The Linux-nationale by Greg Baker


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote:
 On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote:
  Here's one more question:
  
  Before I knew that opEquals existed, I tried overloading the
  equality expressions (== and !=) in opBinary using the code below.
  It worked. Why would the overloaded opBinary version get called if
  the equality expressions are held in opEquals?
 
 [...]
 
 I doubt opBinary was actually called. Probably what happened was that ==
 defaulted to the built-in implementation of opEquals, which simply
 performs a bitwise comparison of the struct/class, and it just so
 happened that it was close to (or the same) as what you intended.
 
 Basically, when you write x==y, the compiler looks for opEquals and
 opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
 otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
 neither are found, then the compiler generates a default implementation
 of opEquals, which basically does a bitwise comparison of x and y.

Actually, what it's supposed to do isn't necessarily a bitwise comparison. 
It's supposed to do a recursive comparison of all of the members, where it 
calls == on each of the members. If a bitwise comparison will do that, then it 
may end up as a bitwise comparison for efficiency reasons, but it's not 
necessarily a bitwise comparison. It used to be that it was doing a bitwise 
comparison when it wasn't supposed to, but that was fixed fairly recently 
(though I don't recall if that fix has been released yet).

Basically, there's no reason to overload opEquals unless you have a member 
which you don't want to compare with == (e.g. pointers).

- Jonathan M Davis


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Monday, July 08, 2013 16:48:05 Jonathan M Davis wrote:
 On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote:
  On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote:
   Here's one more question:
   
   Before I knew that opEquals existed, I tried overloading the
   equality expressions (== and !=) in opBinary using the code below.
   It worked. Why would the overloaded opBinary version get called if
   the equality expressions are held in opEquals?
  
  [...]
  
  I doubt opBinary was actually called. Probably what happened was that ==
  defaulted to the built-in implementation of opEquals, which simply
  performs a bitwise comparison of the struct/class, and it just so
  happened that it was close to (or the same) as what you intended.
  
  Basically, when you write x==y, the compiler looks for opEquals and
  opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
  otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
  neither are found, then the compiler generates a default implementation
  of opEquals, which basically does a bitwise comparison of x and y.
 
 Actually, what it's supposed to do isn't necessarily a bitwise comparison.
 It's supposed to do a recursive comparison of all of the members, where it
 calls == on each of the members. If a bitwise comparison will do that, then
 it may end up as a bitwise comparison for efficiency reasons, but it's not
 necessarily a bitwise comparison. It used to be that it was doing a bitwise
 comparison when it wasn't supposed to, but that was fixed fairly recently
 (though I don't recall if that fix has been released yet).
 
 Basically, there's no reason to overload opEquals unless you have a member
 which you don't want to compare with == (e.g. pointers).

I should point out though (in case someone misunderstands) is that that 
applies specifically to structs. You always have to overload opEquals on 
classes if you want == to work properly (since Object's opEquals does a 
comparison of the references rather than the objects).

- Jonathan M Davis


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread H. S. Teoh
On Mon, Jul 08, 2013 at 04:48:05PM -0700, Jonathan M Davis wrote:
 On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote:
[...]
  Basically, when you write x==y, the compiler looks for opEquals and
  opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
  otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
  neither are found, then the compiler generates a default
  implementation of opEquals, which basically does a bitwise
  comparison of x and y.
 
 Actually, what it's supposed to do isn't necessarily a bitwise
 comparison.  It's supposed to do a recursive comparison of all of the
 members, where it calls == on each of the members. If a bitwise
 comparison will do that, then it may end up as a bitwise comparison
 for efficiency reasons, but it's not necessarily a bitwise comparison.
 It used to be that it was doing a bitwise comparison when it wasn't
 supposed to, but that was fixed fairly recently (though I don't recall
 if that fix has been released yet).
 
 Basically, there's no reason to overload opEquals unless you have a
 member which you don't want to compare with == (e.g. pointers).
[...]

Unfortunately, this isn't true for opCmp. If you don't define opCmp, the
typeinfo of the struct will have a compare function that basically does
bitwise comparison. Proof:

struct S {
int[] data;
}
void main() {
auto s = S([1,2,3]);
auto t = S([1,2,3]);
auto u = S([1,2,4]);

assert(s == t);
assert(s != u);
assert(typeid(s).compare(s, t) == 0); // FAILS
assert(typeid(s).compare(s, u) != 0);
}

Should this be filed as a DMD bug?


T

-- 
A computer doesn't mind if its programs are put to purposes that don't match 
their names. -- D. Knuth


Re: Help me investigate a bug to file it.

2013-07-08 Thread Artur Skawina
On 07/09/13 00:43, Artur Skawina wrote:
 On 07/08/13 23:45, monarch_dodra wrote:
 But, the context pointer *should* be defined as whatever the owner of the 
 indexing/slicing object is, no? In this case, it's simply _input. It has 
 nothing to do with the this pointer being available...

 If anything, it kind of worries me about *what* the implementation is doing 
 with the this pointer, but I haven't been able to trick it into calling a 
 wrong function.
 
 It's just like

Sorry, didn't read that code again before replying. What is
indeed unintuitive is that the first typeof expression succeeds
but the other one fails. But this is related to how typeof() works,
apparently by design. Eg:

   auto f(int a) { return a; }
   pragma(msg, typeof(f(1))); // int. OK.
   alias INT = int;
   pragma(msg, typeof(f(INT))); // int. OK...
   //pragma(msg, typeof(f(int))); // Compile error. 
   
That plus a non-existing this._input, results in a bit (too much)
magic, and the first test passes. The other one fails because of
the '$' (ie opDollar() call).

artur


Re: Beginner problem: casting in opCmp override

2013-07-08 Thread Jonathan M Davis
On Monday, July 08, 2013 16:58:03 H. S. Teoh wrote:
 On Mon, Jul 08, 2013 at 04:48:05PM -0700, Jonathan M Davis wrote:
  On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote:
 [...]
 
   Basically, when you write x==y, the compiler looks for opEquals and
   opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
   otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
   neither are found, then the compiler generates a default
   implementation of opEquals, which basically does a bitwise
   comparison of x and y.
  
  Actually, what it's supposed to do isn't necessarily a bitwise
  comparison.  It's supposed to do a recursive comparison of all of the
  members, where it calls == on each of the members. If a bitwise
  comparison will do that, then it may end up as a bitwise comparison
  for efficiency reasons, but it's not necessarily a bitwise comparison.
  It used to be that it was doing a bitwise comparison when it wasn't
  supposed to, but that was fixed fairly recently (though I don't recall
  if that fix has been released yet).
  
  Basically, there's no reason to overload opEquals unless you have a
  member which you don't want to compare with == (e.g. pointers).
 
 [...]
 
 Unfortunately, this isn't true for opCmp. If you don't define opCmp, the
 typeinfo of the struct will have a compare function that basically does
 bitwise comparison. Proof:
 
   struct S {
   int[] data;
   }
   void main() {
   auto s = S([1,2,3]);
   auto t = S([1,2,3]);
   auto u = S([1,2,4]);
 
   assert(s == t);
   assert(s != u);
   assert(typeid(s).compare(s, t) == 0); // FAILS
   assert(typeid(s).compare(s, u) != 0);
   }
 
 Should this be filed as a DMD bug?

Yes. opCmp's behavior should definitely match opEquals' behavior.

- Jonathan M Davis


function type stringification

2013-07-08 Thread Timothee Cour
I'm a bit confused with the behavior of function type stringification:


int main(string[]args){
  auto foo=main;
  pragma(msg,typeid(typeof(foo)));
  pragma(msg,typeid(typeof(foo)).stringof);

  //pragma(msg,typeid(typeof(foo)));

  import std.stdio;
  writeln(typeid(typeof(foo)).stringof);
  writeln(typeid(typeof(foo)));
  writeln(typeof(main).stringof);

  writeln(typeid(typeof(main)).stringof);
  writeln(typeof(main).stringof);
  return 0;
}


dmd -run main.d:

 D17TypeInfo_PFAAyaZi6__initZ
D17TypeInfo_PFAAyaZi6__initZ
D17TypeInfo_PFAAyaZi6__initZ
int()*
int function(string[] args)
D16TypeInfo_FAAyaZi6__initZ
int(string[] args)

A)
pragma(msg,typeid(typeof(foo))); adds an extra space compared to
pragma(msg,typeid(typeof(foo)).stringof);

B)
can someone please explain the behavior of each stringification? Eg,
writeln(typeid(typeof(foo))) discards input argument types (int()*), etc.