3

I am trying to write a DSL with Scala. I would initially like to be able to write things like

   defType "foo"

when using it.

I had thought that the following should work:

src/main/scala/Test.scala

class Dsl {
    def defType(name: String) = "dummy"
}
object Dsl {
    def apply() = new Dsl()
}

class UseDsl {
    def foo() = {
        val dsl = Dsl()
        import dsl._

        dsl defType "foo"
        defType("foo")
        defType "foo"
    }
}

This fails to compile:

[error] Test.scala:15:17: ';' expected but string literal found.
[error]         defType "foo"
[error]                 ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Explicitly giving dsl works with spaces to separate the method names and arguments.

Implicitly using dsl and parentheses to indicate arguments vs method names works.

Attempting to use both of them together fails.

Is there a way to get that to work?

Once this is working, I plan to extend the DSL to support things like

defType "foo"
   -- "bar1" :: "quz"
   -- "bar2" :: "quz"

which would be equivalent to

dsl.defType("foo").
   --(ImplicitClass("bar1", dsl).::("quz")).
   --(ImplicitClass("bar2", dsl).::("quz"))

Is this something that I will be able to get to work? I think the ImplicitClass would work with a declaration like

def implicit ImplicitClass(a: String, implicit dsl: Dsl) = ...

but clearly, my understanding of how you can get Scala to add things to your code is imperfect.

If it won't work, what are some minimal additions that would let it work?

build.sbt

ThisBuild / organization := "test"
ThisBuild / version := "0.0.1-SNAPSHOT"
ThisBuild / scalaVersion := "2.12.8"


//
// Projects
//
lazy val root = (project in file("."))

1 Answer 1

1

No, method argument is not valid. For infix method calls without parentheses, you have to do

val1 method1 val2 method2 val3 ...

This chain can end in a method without arguments or in the last method's argument, and the first one is not too safe.

Even for members of current type, you need to do this method1 ... and can't omit this as in this.method1(...).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.