Здравствуйте, Александр!

> Вы не могли бы пояснить, что вы имеете ввиду под «цитированием
> себя и охватывающей функции при помощи … стандартной пары знаков
> или имён»?

Имею ввиду возможность, заложенную в языке, любой функции вызывать
себя через какое-то фиксированное, универсальное для этой роли имя.
Ну, или передавать свой адрес кому-то еще.  Подобно местоимениям «я»
или «себя»/«себе» в человеческой речи — человек говорит о себе, не
нуждаясь в имени.  Местоимение одно и то же, но относится к разным
людям в зависимости от того, кто говорит.  Конкретный синтаксис
неважен.

Один из совсем немногих языков, где это имеется — это JavaScript.
Дам пример на нем.

В этом языке у каждой функций имеется (составная) переменная
arguments, а у arguments имеется часть callee.  Так вот,
arguments.callee — это то, о чем я говорю.  В результате можно
написать, скажем, анонимный рекурсивный факториал:

function(n) {return n<2 ? 1 : n*arguments.callee(n-1)}

и вызвать его можно так:

(function(n) {return n<2 ? 1 : n*arguments.callee(n-1)})(5)

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

Еще пример: обращение связанного списка функцией reverse.
reverse создает вложенную функцию с двумя аргументами (из первого
она накапливает результат во второй) и тут же ее вызывает.  Вложенная
функция рекурсивна и анонимна.

function reverse(x) {
  return (function(x,y) {
    if (x) {
      var r = x
      x = x.next
      r.next = y
      return arguments.callee(x,r)
    }
    return y
  })(x,null)
}

(А список может быть, скажем, такой:

list = {data:1}
list = {data:2, next:list}
list = {data:3, next:list}
)

Иногда полезно подобным стандартным анонимным образом вызывать и
охватывающую функцию, возможно даже и ту, которая, в свою очередь,
ее охватывает — это позволяет уже взаимную анонимную рекурсию, но
таких средств ни в JavaScript, ни в других языках не видел.  (Сам
я такое свойство вложил в своем полуреализованном языке, но миру
от этого мало пользы :) )

Бойко

Ответить