Prototype buildsystem "Drake"

Timon Gehr timon.gehr at gmx.ch
Sat Jul 16 06:24:39 PDT 2011


Jacob Carlborg wrote:
> On 2011-07-15 17:16, Andrei Alexandrescu wrote:
>> On 7/15/11 7:58 AM, Jacob Carlborg wrote:
>>> I'm not very familiar with Scala but I found this:
>>> http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/
>>>
>>
>> Interesting. What are the features that do make a DSL better looking in
>> Scala than in D?
>>
>>
>> Thanks,
>>
>> Andrei
>
> This is just what I think (I've thrown in Ruby and CoffeeScript as well)
>
> Scala:
>
> * Delegate syntax - Scala allows passing a delegate to a syntax like this:
>
> loop {
>     // code
> }
>
> This allows to create, what look likes, new statements. I don't recall
> how the "loop" function should be implemented but it was quite complex
> and had something do with partial functions.
>
> Scala also has this nice delegate syntax:
>
> foo(a => a + a)
>
> * Infix operators - Allows to call any method that takes one argument
> without parentheses and without the dot:
>
> object.func("asd")
>
> Can be called like this:
>
> object func "asd"
>
> * Naming methods - In Scala you can name a method "+", "-", "*" and
> similar. You are not limited to A-Za-z_0-9. Together with infix
> operators this is how Scala implements operator overloading. This also
> allows to add new operators.
>
> * No semicolons
> * Is in general very good at inferring types, including return types
> * Almost everything is an expression
> * The constructor is built-in the class declaration:
>
> class Foo
> {
>      // this is the constructor
>      def foo = "foo"
> }

One of the more important features you didn't mention are the so-called
"implicits". Implicits are basically scoped implicit conversions, but strictly
more powerful: They can deduce the conversion function based on an extended
context, like the signature of a member function the resulting type should
provide. Eg:

class IntExtensions(i: Int){
      def times(j: Int) = i*j
}

implicit def intExtensions(i: Int) = new IntExtensions(i) // implicit conversion
of Int to IntExtensions
implicit def strToInt(s: String) = s match { // implicit conversion from String to Int
         case "one" => 1
         case "two" => 2
         case "three" => 3
         //...
         case _ => throw new Exception("Unknown number " + s)
}
implicit def intExtensions(s: String) = new IntExtensions(strToInt(s)) // implicit
conversion from String to IntExtensions (implicits are not automagically
transitive, probably for compiler efficiency)


// now you can write stuff like (this also depends on infix operators):
val x="three" times "two" times	"one"
val y=3 times "two"
val z="three" times 2

assert(x==6 && y==6 && z==6);

If D had UFCS and infix operators, it would have a lot more power to build DSELs.
I don't know exactly how infix operators would play with Ds somewhat ambiguous
declaration syntax.
Of course, there are always string mixins, but then you are departing from valid D
syntax with your DSL.

mixin(myDSLtoD(q{not D code}));
or
myDSL!q{not D code};


Cheers,
-Timon


More information about the Digitalmars-d mailing list