13

By chance I came across weird compiling Scala syntax:

class Some extends {
  def hi = println("hi")
}

Guys:

  • Is it an official Scala supported syntax?
  • Does it mean simply extending the Object?
  • Does it somehow relate to "duck typing"?
  • Do you know interesting or tricky usages of this?

Thanks.

3 Answers 3

8

This is actually a strange quirk in Scala's syntax. An extraneous extends is allowed before beginning the body of the class. Here are the relevant parts from the Scala Syntax Summary:

ClassDef          ::=  id [TypeParamClause] {ConstrAnnotation} [AccessModifier] 
                       ClassParamClauses ClassTemplateOpt 
ClassTemplateOpt  ::=  ‘extends’ ClassTemplate | [[‘extends’] TemplateBody]
ClassTemplate     ::=  [EarlyDefs] ClassParents [TemplateBody]

ClassTemplateOpt is everything after the class's parameters, in this case everything from extends onwards. The usual use of extends is the first alternation of ClassTemplateOpt, with extends being followed either by a parent or an early initializer. However, an early initializer cannot contain a def, and there is no way to interpret the contents of the braces as a parent. It cannot be a structural type because hi has a concrete definition.

The second alternation allows the class parameters to be immediately followed by the class body, without using extends. However, an optional extends is allowed. The extends in OP's code is an example of this, and is exactly equivalent to the same code without the optional extends:

class Some {
  def hi = println("hi")
}
Sign up to request clarification or add additional context in comments.

Comments

6

This is actually just a syntactical accident (I think). Scala allows early definitions which look like

class Some extends {
  ...
} with ATrait

so the parser also accepts class Some extends { ... } which is equivalent to class Some { ... } (source).

1 Comment

It appears pre-initialized/early definitions don't permit functions to be declared though. Doing the following won't compile: trait ATrait; class Some extends { def hi = println("hi")} with ATrait
-1

Yes this is Scala's structural typing or more commonly known as duck typing.

object LoudDuck {
    def quack(): String = "QUACK"
}

object QuietDuck {
    def quack(): String = "quack"
}

object CowDuck {
    def quack(): String = "moo"
}

def quackMyDuck(duck: { def quack(): String }) {
    println(duck.quack())
}

scala>quackMyDuck(LoudDuck)
QUACK

scala>

scala>quackMyDuck(QuietDuck)
quack

scala>

scala>quackMyDuck(CowDuck)
moo

You can also declare your stuctural types with the "type" keyword.

type Duck = { def quack(): String }

def quackMyDuck(duck: Duck) {
    println(duck.quack())
}

2 Comments

The examples you give are structural typing, but the one in question isn't.
Consider type T = { def hi = println("hi") } - it doesn't compile, because structural types can't have definitions.

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.