On 2011-07-16 15:24, Timon Gehr wrote:
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);
Yeah, implicits are nice as well.
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
String mixins are not a solution to DSLs in my opinion.
--
/Jacob Carlborg