Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala closure context

I am not a Groovy expert, but I did read the book "Groovy in Action". In Groovy, each closure comes with a "context", where the items inside the closure can get access to pseudo-variables like "this", "owner", and "delegate", that let the items know who called the closure. This allows one to write DSLs like this (from Groovy in Action):

swing = new SwingBuilder()
frame = swing.frame(title:'Demo') {
  menuBar {
    menu('File') {
      menuItem 'New'
      menuItem 'Open'
    }
  }
  panel {
    // ...
  }
}

Note that 'menuBar' "knows" that it belongs to 'frame' because it can get context information about the owner and delegate of the closure.

Is this possible to do in Scala? If so, how?

like image 908
Ralph Avatar asked Apr 13 '10 12:04

Ralph


People also ask

What is the closure in Scala?

Scala Closures are functions which uses one or more free variables and the return value of this function is dependent of these variable. The free variables are defined outside of the Closure Function and is not included as a parameter of this function.

What is closure in Scala with example?

A closure is a function, whose return value depends on the value of one or more variables declared outside this function. The following piece of code with anonymous function. val multiplier = (i:Int) => i * 10.

On which value closure will depend?

The choice of closure type depends entirely on the degree of drainage, the existing amount of tissue for wound closure and infection status at the site of wound closure.

What is a closure in spark?

Summing up, closure is those variables and methods which must be visible for the executor to perform its computations on the RDD. This closure is serialized and sent to each executor. Understanding closure is important to avoid any unexpected behaviour of the code.


1 Answers

One way is to use a scala.util.DynamicVariable to track the context. Something like the SwingBuilder could be implemented as

import scala.util.DynamicVariable
import javax.swing._

object SwingBuilder {
  case class Context(frame: Option[JFrame], parent: Option[JComponent])
}

class SwingBuilder {
  import SwingBuilder._
  val context = new DynamicVariable[Context](Context(None,None))

  def frame(title: String)(f: =>Unit) = {
    val res = new JFrame(title)
    res.add(new JPanel())
    context.withValue(Context(Some(res),context.value.parent)){f;res}
  }

  def menuBar(f: =>Unit) = {
    val mb = new JMenuBar()
    context.value.frame.foreach(_.setJMenuBar(mb))
    context.withValue(Context(context.value.frame,Some(mb))){f;mb}
  }

  def menu(title: String)(f: =>Unit) = {
    val m = new JMenu(title)
    context.value.parent.foreach(_.asInstanceOf[JMenuBar].add(m))
    context.withValue(Context(context.value.frame,Some(m))){f;m}
  }

  def menuItem(title: String) = {
    val mi = new JMenuItem(title)
    context.value.parent.foreach(_.asInstanceOf[JMenu].add(mi))
  }
}

object Test {
  def main(args: Array[String]) {
    val builder = new SwingBuilder()
    import builder._

    val f = frame("Demo") {
      val mb = menuBar {
        menu("File") {
          menuItem("New")
          menuItem("Open")
        }
      }
    }
    f.setVisible(true)
  }
}
like image 148
Geoff Reedy Avatar answered Oct 07 '22 18:10

Geoff Reedy