Re: Scale advocacy
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
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
Sorry for the wrong title and the wrong newsgroup :-) Bye, bearophile
Scale advocacy
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
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
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