Re: Scale advocacy

2011-07-03 Thread Ali Çehreli
On Sun, 03 Jul 2011 20:07:43 +, Ali Çehreli wrote:

> import std.range;
> 
> // ...
> 
> ElementType!Range front_or_null(Range)(Range range) {
> return range.empty ? null : range.front;
> }
> 
> The template constraint has proven to be problematic though. I will open
> a separate thread about that.

I've figured it out: I've been using "== null" instead of "is null". This 
fails:

import std.range;

ElementType!Range front_or_null(Range)(Range range)
if (__traits(compiles,
 { bool result = ElementType!Range.init == null; } ))
{
return range.empty ? null : range.front;
}

class C
{}

void main()
{
C[] c;
front_or_null(c);
}

Replacing "==" with "is" works:

 { bool result = ElementType!Range.init is null; } ))

I would have liked this simpler syntax to work:

if (__traits(compiles, { ElementType!Range.init is null; } ))

but it fails without really telling why. Only if I move that expression 
into a code context that I can understand what the problem is. Now trying 
to compile this:

C.init is null;

produces this error:

Error: is has no effect in expression (null is cast(C)null)

I am grateful for the warning but it was puzzling for a while why the 
simple template constraint was not working. I guess it was a good 
decision to suppress the compiler errors in __traits(compiles). I wonder 
whether __traits(compiles) can be made less strict by eliminating the 
need for the silly 'bool result' in the delegate above.

But this is not a pressing issue at all. :)

Ali


Re: Scale advocacy

2011-07-03 Thread Ali Çehreli
On Sun, 03 Jul 2011 12:44:01 -0400, bearophile wrote:

> A nice and almost funny set of slides (no PDF available, I think) that
> show how to convince your boss to try Scala, it shows only very basic
> things:
> 
> http://scala-boss.heroku.com/#1
> 
> Bye,
> bearophile

D's solution to the problem at slide #28 (http://scala-boss.heroku.com/
#28) is similar to Scala's:

const(Account) findAccount(Customer customer,
   EnergyType energy,
   Date date)
{
bool matching(const(Account) account)
{
return ((account.servicePoint.energy == energy)
&&
isDateInWindow(date,
   account.moveInDate,
   account.moveOutDate));
}

return front_or_null(find!matching(customer.accounts));
}

I know that matching() could be a function literal in D as well, but I 
prefer nested functions for code clarity when the criteria is not really 
short.

Also, although returning the range directly would be more D-like, I've 
written the following front_or_null() instead of Scala's getOrElse():

import std.range;

// ...

ElementType!Range front_or_null(Range)(Range range)
{
return range.empty ? null : range.front;
}

The template constraint has proven to be problematic though. I will open 
a separate thread about that.

Ali



Re: Scale advocacy

2011-07-03 Thread bearophile
Sorry for the wrong title and the wrong newsgroup :-)

Bye,
bearophile


Scale advocacy

2011-07-03 Thread bearophile
A nice and almost funny set of slides (no PDF available, I think) that show how 
to convince your boss to try Scala, it shows only very basic things:

http://scala-boss.heroku.com/#1

Bye,
bearophile


Re: Operator Overloading and boilerplate code

2011-07-03 Thread Loopback

Thank you!

How excellent you handled the boilerplate code. Works perfectly fine as
well, except one little thing. I cannot declare this DVECTOR2 structure
immutable because the compiler complains saying this:

Error: variable __ctmp1485 cannot be read at compile time
Error: cannot evaluate __ctmp1485.this(0F,1F,0F) at compile time

As I mentioned before, I am new to D and I do not understand why the
compiler cannot evaluate the expression at compile time.

One more thing which I also am wondering is how opCast really works.
To trigger opCast you need to do an explicit cast (tell me if I'm wrong)
and when you do this, does it also work for cases like this:

cast(D3DXVECTOR2) &vector2

Does this code trigger the defined opCast (vector2 is a DVECTOR2
structure in this case) or do I have to define a new opCast in
cases where the address operator is used or is the compiler
able to distinguish the cases and cast opCast before the address
operator is evaluated?

struct DVECTOR2
{
// Controls that the parameter is a valid type
	template Accepts(T) { enum Accepts = is(T == DVECTOR2) || is(T == 
float) || is(T == D3DXVECTOR2) || is(T == POINT); }


// Whether the parameter is a float or not
template isScalar(T) { enum isScalar = is(T == float); }

// The Variables
float x = 0f;
float y = 0f;

// Default Constructor
this()(float x, float y)
{
this.x = x;
this.y = y;
}

// Float Constructor
this()(float xy) { this(xy, xy); }

// Implement D3DXVECTOR2 and POINT support
this(T)(T arg) if(Accepts!T && !isScalar!T) { this(arg.tupleof); }

// Inverse the vector
DVECTOR2 opUnary(string op)() if(op == "-") { return DVECTOR2(-x, -y); }

// Binary Operations
DVECTOR2 opBinary(string op, T)(T rhs) if(Accepts!T)
{
enum rx = isScalar!T ? "" : ".x";
enum ry = isScalar!T ? "" : ".y";

		return DVECTOR2(mixin("x" ~ op ~ "rhs" ~ rx), mixin("y" ~ op ~ "rhs" ~ 
ry));

}

// Right Binary Operator
	DVECTOR2 opBinaryRight(string op, T)(T lhs) if(Accepts!T) { return 
DVECTOR2(lhs).opBinary!op(this); }


// Assign Operator
ref DVECTOR2 opAssign(T)(T rhs) if(Accepts!T)
{
static if(isScalar!T)
x = y = rhs;

else
{
x = rhs.x;
y = rhs.y;
}

return this;
}

// In-Place Assignment Operators
	ref DVECTOR2 opOpAssign(string op, T)(T rhs) if(Accepts!T) { 
return(this.opAssign(opBinary!op(rhs))); }


// Cast Operators (to D3DXVECTOR2 and POINT)
T opCast(T)() if(Accepts!T && !isScalar!T) { return T(x, y); }
}


Re: makeIndex not working

2011-07-03 Thread Jonathan M Davis
On 2011-07-02 19:42, Adam D. Ruppe wrote:
> Jonathan M Davis wrote:
> > The range has to be mutable.
> 
> Is there any easy way around this, aside from casting away
> the outer immutable?
> 
> It's a very annoying limitation that doesn't really have to be
> there - I believe the language itself would let you pass immutable
> int[] to a regular function that expects immutable(int)[], since the
> outermost reference is passed by value anyway.

The problem is how the type is determined with templates. The _exact_ type is 
used. So, instead of generating a function which takes immutable(int)[], the 
compiler generates a function which takes an immutable int[], because you 
passed it an immutable int[], not an immutable(int)[]. And it doesn't work to 
iterate over an immutable int[], so the function fails to compile. It's the 
same reason why you can't use static arrays with range-based functions unless 
you slice them. They don't work when the type is a static array, since you 
can't pop elements off of a static array.

If the compiler were smart enough to use immutable(int)[] instead of immutable 
int[], and to use a dynamic array instead of a static one when choosing the 
type for the template, then the problem would be solved. But it isn't that 
smart. There are at least a couple of enhancement requests which relate to the 
issue, and it may be resolved at some point, but as long as the compiler uses 
the _exact_ type given for the template even when a more relaxed type would 
work, you're not going to be able to pass immutable arrays or static arrays to 
templated functions.

- Jonathan M Davis