Да. Посмотрите на связанные разделы работы этих 2 бумаг:
https://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/index.htm http://www.filpizlo.com/papers/pizlo-ismm2007-stopless.pdf
Или в этом:
http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon12StallFree.pdf
Это забавная вещь в функциональном программировании, которая называется каррированием . По сути, Моисей Шенфинкель и последний Хаскелл Карри (хотя Шонфинкелинг прозвучит странно ...) пришли к идее, что вызов функции с несколькими аргументами, скажем f (x, y)
, аналогичен цепочке вызывает {g (x)} (y)
или g (x) (y)
, где g
- функция, которая производит другую функцию в качестве своего вывода.
В качестве примера возьмем функцию f (x: Int, y: Int) = x + y
. Вызов f (2,3)
, как и ожидалось, даст 5
. Но что происходит, когда мы каррируем эту функцию - переопределим ее как f (x: Int) (y: Int)
и назовем ее как f (2) (3)
. Первый звонок, f (2)
создает функцию, которая принимает целое число y
и добавляет к нему 2
-> поэтому f (2)
имеет тип Int => Int
и эквивалентен функции g (y) = 2 + y
. Второй вызов f (2) (3)
вызывает вновь созданную функцию g
с аргументом 3
, поэтому вычисляется как 5
, как и ожидалось.
Другой способ увидеть это - выполнить сокращение (функциональные программисты называют это бета-редукцией - это похоже на функциональный способ постепенного перехода по строкам) f (2) (3)
(обратите внимание, что следующий синтаксис Scala неверен).
f(2)(3) // Same as x => {y => x + y}
|
{y => 2 + y}(3) // The x in f gets replaced by 2
|
2 + 3 // The y gets replaced by 3
|
5
Итак, после всего этого разговора, f (x) (y)
можно рассматривать как просто следующее лямбда-выражение (x: Int) =>
Вы частично применяете функцию ModN. Частичное применение функций - одна из основных особенностей функциональных языков. Дополнительные сведения см. В этих статьях о стиле Currying и Pointfree .
В этом примере modN возвращает функцию, которая изменяет конкретное N. Это избавляет вас от необходимости делать следующее:
def mod2(x:Int): Boolean = (x%2) == 0
def mod3(x:Int): Boolean = (x%3) == 0
Две пары скобок ограничивают, где вы можете перестать передавать аргументы методу. Конечно, вы также можете просто использовать заполнитель для достижения того же самого, даже если метод имеет только один список аргументов.
def modN(n: Int, x: Int): Boolean = (x % n) == 0
val nums = List(1, 2, 3, 4, 5)
println(nums.filter(modN(2, _)))
println(nums.filter(modN(3, _)))