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

Reply via email to