Возможно ли в Scala создать функцию, которая запрещает использование замыканий? - PullRequest
0 голосов
/ 20 сентября 2019

Скажем, у меня есть какая-то функция, подобная этой:

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

Она принимает функцию, выводит "Делать некоторый код!"и затем вызывает переданную функцию.Например, если бы мы назвали его следующим образом:

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

Это вывело бы «Делать какой-то код!», А затем «Некоторый код готов!».

Но я бы хотел запретить использование внешних переменных внутри этого блока кода, например:

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

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

Это выведет «Выполнение некоторого кода!», А затем «Числоэто 10 ".Но я бы хотел вместо этого выдать ошибку, потому что я не хочу, чтобы number входил в сферу применения doSomeCode.Этого можно достичь в Scala?
Чтобы было ясно, я не спрашиваю, хорошая ли это идея, я просто хочу знать, возможно ли это.

Редактировать:
Причина, по которой я хочуэто потому, что я пытаюсь сделать синтаксис, который является совершенно функциональным, я хочу блок без побочных эффектов.В идеале синтаксис должен выглядеть следующим образом:

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

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

Таким образом, я, как программист, знаю, что используются только переменные a, c и d и что sum - единственный выход,Попытка использовать что-либо еще, например, b, приведет к ошибке.В настоящее время невозможно сразу узнать, какие переменные использует блок.Я могу добиться этого, просто сделав и используя функцию, подобную этой:

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
}  

Это ведет себя так же, как я хочу, но я бы хотел, чтобы он был встроен в другой код, а не снаружи каквнешняя функция.

1 Ответ

1 голос
/ 20 сентября 2019
scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String

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

Поскольку функция, зависящая от значений, которые не являются параметрами, не кодируется в системе типов, в Scala нет никакой разницы между Scala-совместимым и такой функцией, которую можно было бы выполнить с помощью компилятора.Это вряд ли возможно с макросами: плагин компилятора, вероятно, является лучшим выбором, особенно если вы хотите разрешить использование определенных значений (например, println) внутри блока.

...