Reputation: 175
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
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