Для языка, где «все является объектом» и ссылка на объект недоступна, например, Java и Scala, то каждый параметр функции является ссылкой, передаваемой по значению на некотором уровне абстракции ниже языка. Однако с точки зрения семантики языковой абстракции существует либо вызов по ссылке, либо вызов по значению, в зависимости от того, предоставляется ли функции копия ссылочного объекта. В этом случае термин «вызов по совместному использованию» охватывает как вызов по ссылке, так и вызов по значению на уровне абстракции языка. Таким образом, правильно сказать, что Java является вызовом по значению на уровне абстракции ниже семантики языка (т. Е. Сравнивать с тем, как она будет гипотетически переводиться в C или в байт-код для виртуальной машины), и в то же время говорить, что Java и Scala - это (за исключением встроенных типов) вызов по ссылке в семантике своей абстракции «все является объектом».
В Java и Scala некоторые встроенные типы (a / k / a примитив) автоматически передаются по значению (например, int или Int), и каждый определенный пользователем тип передается по ссылке (т.е. их нужно вручную копировать). передать только их значение).
Примечание. Я обновил раздел Википедии , чтобы сделать это более понятным.
Возможно, Википедия не понимает различий между передачей по значению и вызовом по значению? Я думал, что передача по значению является более общим термином, так как он применяется к выражениям присваивания, а также к применению функции. Я не удосужился попытаться сделать это исправление в Википедии, оставь это для других.
Нет разницы на уровне семантики, где "все является объектом" между вызовом по ссылке и вызовом по значению, когда объект неизменен. Таким образом, язык, который позволяет объявлять вызов по значению по сравнению с вызовом по ссылке (такой как Scala-подобный язык, который я разрабатываю), можно оптимизировать, задерживая копирование по значению до тех пор, пока объект не будет изменен.
Люди, которые проголосовали за это, по-видимому, не понимают, что такое "обмен вызовами".
Ниже я добавлю описание, которое я написал для моего языка Copute (который предназначен для JVM), где я обсуждаю стратегию оценки.
Даже с чистотой, полный язык Тьюринга (то есть, который допускает рекурсию) не является полностью декларативным, потому что он должен выбирать стратегию оценки. Стратегия оценки - это относительный порядок оценки времени выполнения между функциями и их аргументами. Стратегия оценки функций может быть строгой или нестрогой, что аналогично стремлению или ленивости соответственно, поскольку все выражения являются функциями. Eager означает, что выражения аргумента вычисляются до их функции; тогда как ленивый означает, что выражения аргумента вычисляются (один раз) в момент времени их первого использования в функции.
Стратегия оценки определяет компромисс между производительностью, детерминизмом, отладкой и операционной семантикой. Для чистых программ это не изменяет результат денотационной семантики, потому что с чистотой императивные побочные эффекты порядка оценки вызывают только неопределенность (то есть категорически ограничены) потреблением памяти, временем выполнения, задержкой и областями без завершения .
По сути, все выражения являются (составом) функций, то есть константы являются чистыми функциями без входов, унарные операторы являются чистыми функциями с одним входом, бинарные операторы являются чистыми функциями с двумя входами, конструкторы являются функциями и даже управляющими операторами (например, если , для, в то время как) можно моделировать с помощью функций. Порядок, в котором мы оцениваем эти функции, не определяется синтаксисом, например, Функция f (g ()) может с готовностью оценить g, затем f по результату g, или она может оценить f и только лениво оценивать g, когда его результат необходим в пределах f.
Первый (нетерпеливый) - это вызов по значению (CBV), а второй (ленивый) - это вызов по имени (CBN).CBV имеет вариант call-by-share, распространенный в современных языках ООП, таких как Java, Python, Ruby и т. Д., Где нечистые функции неявно вводят некоторые изменяемые объекты посредством ссылки.CBN имеет вариант вызова по требованию (также CBN), где аргументы функции оцениваются только один раз (что не совпадает с функциями запоминания).Call-by-потребность почти всегда используется вместо call-by-name, потому что это экспоненциально быстрее.Обычно оба варианта CBN появляются только с чистотой из-за диссонанса между объявленной иерархией функций и порядком оценки времени выполнения.
Языки обычно имеют стратегию оценки по умолчанию, а некоторые имеют синтаксис для принудительного принудительного принудительного применения.функция, которая будет оценена не по умолчанию.Языки, которые стремятся по умолчанию, обычно лениво оценивают операторы логического конъюнкции (a / k / a "и", &&) и дизъюнкции (a / k / a "или", ||), поскольку второй операнд не нуженв половине случаев, т.е. верно ||все == правда и ложь && что угодно == ложь.