Как «замыкания» настолько мощная абстракция, что объектные системы и фундаментальные управляющие структуры реализуются с его помощью? - PullRequest
4 голосов
/ 16 марта 2011

Вот цитата из программирования scala глава 1:

Замыкания являются настолько мощной абстракцией, что объектные системы и фундаментальные управляющие структуры часто реализуются с их использованием

Судя по всему, это утверждение не о Scala, а о замыканиях в целом, но я не могу имеет большой смысл из этого. Возможно, это какая-то жемчужина мудрости, предназначенная только для этих могущественных авторов компиляторов!

Так, кто использует Closures для реализации фундаментальных структур управления и почему?

Редактировать: Я помню, как читал кое-что о пользовательских структурах управления в groovy, используя синтаксис замыкания в качестве последнего параметра вызова метода и делая структуру доступной для вашего кода с помощью мета-классов или use ключевое слово с категориями . Может ли это быть что-то связанное?

Редактировать: Я нашел следующую ссылку на синтаксис Groovy пользовательских структур управления здесь (слайд 38):

Пользовательские структуры управления

Благодаря закрытиям

  • Когда замыкания выполняются в последний раз, их можно убрать из скобок
    параметры окружающей среды
  • unless(account.balance > 100.euros, { account.debit 100.euros })
  • unless(account.balance > 100.euros) { account.debit 100.euros }
  • Подпись def unless(boolean b, Closure c)

Очевидно, что groovy предлагает синтаксический сахар для того, чтобы сделать пользовательские структуры управления на основе Closure похожими на первоклассные структуры управления, предлагаемые самим языком.

Ответы [ 4 ]

7 голосов
/ 16 марта 2011

Я прокомментировал случай контрольных структур. Позвольте мне прокомментировать замыкания как объекты. Подумайте, что происходит, когда вы вызываете метод объекта; он имеет доступ не только к списку аргументов, но и к полям объекта. То есть метод / функция закрывается над полями. Это ничем не отличается от «голой» функции (т. Е. Не объектного метода), которая закрывает переменные в области видимости. Однако синтаксис объекта обеспечивает хороший механизм абстракции и модульности.

Например, я мог бы написать

case class Welcome(message: String) {
  def greet(name: String) = println(message + ", " + name)
}
val w = Welcome("Hello")
w.greet("Dean")

против

val message = "Hello"
val greet = (name: String) => println(message + ", " + name)
greet("Dean")

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

class Welcome2(message: String) {    // removed "case"
  def greet(name: String) = println(message + ", " + name)
}
val w = new Welcome2("Hello")        // added "new"
w.greet("Dean")

Это все еще работает! Теперь greet закрывает значение входного параметра, а не поля.

var welcome = "Hello"
val w2 = new Welcome2(welcome)
w2.greet("Dean")     // => "Hello, Dean"
welcome = "Guten tag"
w2.greet("Dean")     // => "Hello, Dean"  (even though "welcome" changed)

Но если класс напрямую ссылается на переменную во внешней области видимости,

class Welcome3 {                  // removed "message"
  def greet(name: String) = println(welcome + ", " + name) // reference "welcome"
}
val w3 = new Welcome3
w3.greet("Dean")                  // => "Guten tag, Dean"
welcome = "Buon giorno"
w3.greet("Dean")                  // => "Buon giorno, Dean"

Имеет смысл?

3 голосов
/ 16 марта 2011

Существует три основных управляющих структуры:

Последовательность

a = 1
b = 2
c = a + b

Условия

if (a != b) {
  c = a + b
} else {
  c = a - b
}

Итерации / петли

for (a <- array) {
  println(a)
}

Итак, я предполагаю, что они означают, что внутренне многие языки используют замыкания для структур управления (вы можете посмотреть последние две структуры).

Как пример:

if (a < b) {
  for (i = a; a < b; a++) {
    println(i)
    c = i * i
  }
} else {
  c = a - b
}

То есть for - это закрытие внутри закрытия if, и else - это тоже закрытие. Вот как я это понимаю. Они создают замыкание для первого if, если условие выполняется, создайте замыкание внутри фигурных скобок, назовите его. Затем создайте замыкание для цикла for и вызовите его, пока условие выполняется.

И я думаю, что нет списка языков, которые используют замыкания внутри.

Обновление:

Например, вы можете реализовать свой собственный цикл for в Scala (o является кириллицей, поэтому он будет компилироваться):

def fоr(start: Unit, condition: => Boolean, increment: => Unit)(body: => Unit): Unit = {
  if (condition) {
    body
    increment
    fоr(0, condition, increment)(body)
  }
}

var i = 0

fоr (i = 0, i < 1000, i += 1) {
  print(i + " ")
}

Так что на самом деле это то, как это может быть реализовано в других языках на внутреннем уровне.

1 голос
/ 18 марта 2011

Я бы сказал, что " замыкания являются такой мощной абстракцией ... ", потому что в отличие от стандартных методов, у вас есть ссылка на вызывающий объект, независимо от области, в которой было вызвано замыкание.

Например, в Groovy вы можете добавить новый метод "прописные буквы" для типа String:

String.metaClass.capitalize = {  
    delegate[0].upper() + delegate[1..-1].lower()  
}   
"hello".capitalize() // "Hello"

Или вы можете сделать что-то более сложное, например, создать домен-специфический язык (DSL), используя замыкания.

class ClosureProps {

       Map props = [:]  
       ClosureProps(Closure c) {  
           c.delegate = this // pass closure scope to "this"
           c.each{"$it"()} // iterate through closure, triggering missingMethod()
       }  
       def methodMissing(String name, args) {  
           props[name] = args.collect{it} // collect extracted closure properties
       }  
       def propertyMissing(String name) {  
           name  
       }  
}  

Пример

class Team {

        // the closure
        static schema = {  
            table team  
            id teamID  
            roster column:playerID, cascade:[update,delete]  
        }  
}  
def c = new ClosureProps(Team.schema)  
println c.props.id // prints "teamID"
0 голосов
/ 16 марта 2011

а) Пожалуйста, попробуйте по крайней мере поискать темы, прежде чем задавать вопросы.

б) После того, как вы это сделаете, задайте конкретные вопросы.

в) Лексические закрытия - это функции, которые имеютлексическая среда недоступна там, где они вызываются.Таким образом, их параметры могут использоваться для выбора сообщений и передачи параметров вместе с этими сообщениями.Для общих структур управления их недостаточно, если только они не могут повлиять на стек вызовов, в виде продолжений.

...