Jared DuPont
Jared DuPont

Reputation: 175

Is it possible in Scala to make a function that disallows the use of closures?

Say I have some function like this:

def doSomeCode(code: => Unit): Unit = {
  println("Doing some code!")
  code
}  

It takes in a function, prints out "Doing some code!" and then calls the passed function. If for example we called it like:

doSomeCode {
  println("Some code done!")
}

It would print out "Doing some code!", followed by "Some code done!".

But I would like to disallow the use of outside variables inside that code block, for example:

def otherFunction(): Unit = {
  val number = 10

  doSomeCode{
    println("The number is " + number)
  }
}

This will print out "Doing some code!", followed by "The number is 10". But I would like it to instead throw an error because I do not want number to be in the scope of doSomeCode. Is this possible to achieve in Scala?
To be clear I am not asking if this is a good idea, I just want to know if it is possible.

Edit:
The reason I want this is because I am trying to make a syntax that is perfectly functional, I want a block with no side effects. Ideally the syntax would look like:

val a = 1
val b = 2
val c = 3
val d = 4

val sum = use(a, c, d){
  val total = a + c + d
  total
}  

This way I as a programmer know that the only variables used are a, c, and d and that sum is the only output. Trying to use anything else, eg b, would result in an error. Currently it is not possible to know at a glance what variables a block is using. I can achieve this by just making and using a function like this:

def example(): Unit = {
  val a = 1
  val b = 2
  val c = 3
  val d = 4

  val sum = sum(a, c, d)
}

def sum(a: Int, b: Int, c: Int): Int = {
  val total = a + b + c
  total
}  

This behaves exactly like how I want it to, but I would like it to be inline with the other code, not outside as an external function.

Upvotes: 0

Views: 53

Answers (1)

Levi Ramsey
Levi Ramsey

Reputation: 20561

scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String

scala> mkClosure(5)
res0: String => String = <function1>

Since whether the function depends on values which aren't parameters isn't encoded in the type system, there's no compiler-enforceable difference in Scala between such a function and a pure one. It's unlikely to be possible with macros: a compiler plugin is probably your best bet, especially if you want to allow certain values (e.g. println) to be used inside a block.

Upvotes: 1

Related Questions