Параметры функции в Юлии - PullRequest
       11

Параметры функции в Юлии

0 голосов
/ 23 сентября 2018

Кто-нибудь знает причины, по которым Джулия выбрала схему функций, в которой параметры, заданные в качестве входных данных, не могут быть изменены?Это требует, если мы все равно хотим его использовать, чтобы пройти очень искусственный процесс, представляя эти данные в виде смешной таблицы с одним элементом.

Ада, которая имела такое же ограничение, была оставленав 2012 году он был перепроектирован для удовлетворения пользователей.Небольшое ключевое слово (как в Ada) вполне может указывать на необходимость сохранения изменений параметра на выходе.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

"Кто-нибудь знает причины, по которым Джулия выбрала схему функций, в которой параметры, заданные в качестве входных данных, не могут быть изменены?"спросил Schemer

Ваш вопрос неправильный, потому что вы принимаете неправильные вещи.

  1. Параметры являются переменными

Когда вы передаете вещи в функцию, частоэти вещи являются значениями, а не переменными.

например:

function double(x::Int64)
  2 * x
end

Теперь, что происходит, когда вы вызываете его, используя

double(4)

В чем смысл функцииизменить его параметр х, это бессмысленноКроме того, функция не знает, как она вызывается.

Кроме того, Джулия построена для скорости.

Функцию, которая изменяет свой параметр, будет сложно оптимизировать, посколькувызывает побочные эффекты.Побочным эффектом является то, что процедура / функция изменяет объекты / вещи вне ее области действия.

Если функция не изменяет переменную, являющуюся частью ее вызывающего параметра, вы можете быть в безопасности, зная.

  1. значение переменной не будет изменено
  2. результат функции можно оптимизировать до постоянной
  3. без вызова функции не будет нарушаться поведение программы

Эти три фактора делают ФУНКЦИОНАЛЬНЫЙ язык быстрым, а НЕ ФУНКЦИОНАЛЬНЫМ - медленным.

Кроме того, когда вы переходите в параллельное программирование или многопоточное программирование, вы абсолютно НЕ ХОТИТЕ переменную, у которой изменилось значениебез вас (программиста) об этом знать.

"Как бы вы реализовали предложенный макрос, функцию F (x), которая возвращает логическое значение и изменяет c на c: = c + 1. F можетиспользоваться в следующем фрагменте кода Ada: c: = 0; F (c) Loop ... End Loop; "спросил Schemer

Я бы написал

function F(x)
  boolean_result = perform_some_logic()
  return (boolean_result,x+1)
end

flag = true
c = 0
(flag,c) = F(c)
while flag
  do_stuff()
  (flag,c) = F(c)
end

"К сожалению, нет, потому что, и я должен был сказать, что c должен снова принять значение 0, когда F возвращает значение False (cувеличивается до тех пор, пока Loop живет и возвращается к 0, когда он умирает. "сказал Schemer

Тогда я написал бы

0 голосов
/ 23 сентября 2018

Из моего опыта работы с Юлией полезно понять разницу между значением и привязкой.

Значения

Каждое значение в Юлии имеет конкретный тип и местоположение в памяти.Значение может быть изменяемым или неизменным.В частности, когда вы определяете свой собственный составной тип, вы можете решить, должны ли объекты этого типа быть изменяемыми (mutable struct) или неизменяемыми (struct).

Конечно, у Джулии есть встроенные типы, и некоторые изони являются изменяемыми (например, массивы), а другие являются неизменяемыми (например, числа, строки).Конечно, есть компромисс между дизайном.С моей точки зрения, два основных преимущества неизменяемых значений:

  1. , если компилятор работает с неизменяемыми значениями, он может выполнить много оптимизаций для ускорения кода;
  2. пользователь может быть уверен, чтопередача неизменяемого в функцию не изменит его, и такая инкапсуляция может упростить анализ кода.

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

julia> x = Ref(1)
Base.RefValue{Int64}(1)

julia> x[]
1

julia> x[] = 10
10

julia> x
Base.RefValue{Int64}(10)

julia> x[]
10

Вы можете передавать такие значения в функцию и изменять их внутри.Конечно, Ref вводит другой тип, поэтому реализация метода должна быть немного другой.

Переменные

Переменная - это имя, связанное со значением.В общем, за исключением некоторых особых случаев, таких как:

  1. повторное связывание переменной из модуля A в модуле B;
  2. переопределение некоторых констант, например, попытка переназначения имени функциис нефункциональным значением;
  3. связывание переменной, имеющей указанный тип допустимых значений, со значением, которое не может быть преобразовано в этот тип;

вы можете привязать переменную кукажите любое значение, которое вы хотите.Перепривязка выполняется в большинстве случаев с использованием = или некоторых специальных конструкций (например, в операторах for, let или catch).

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

Если, дляНапример, мы хотели вызвать как:

x = 10
f(x)

изменить привязку переменной x невозможно, потому что f даже не знает о существовании x.Он только получает свою стоимость.В частности, как я уже отмечал выше, добавление такой функции нарушило бы правило, согласно которому module A не может перепривязывать переменные из модуля B, поскольку f может быть определено в модуле, отличном от того, гдеx определено.

Что делать

На самом деле достаточно легко работать без этой функции из моего опыта:

  1. То, что я обычно делаю, это простовернуть значение из функции, которую я назначаю переменной.В Julia это очень просто из-за синтаксиса распаковки кортежей, например, x,y,z = f(x,y,z), где f может быть определено, например, как f(x,y,z) = 2x,3y,4z;
  2. Вы можете использовать макросы, которые раскрываются перед выполнением кода и, таким образом, могут иметьэффект, изменяющий привязку переменной, например macro plusone(x) return esc(:($x = $x+1)) end и теперь пишущий y=100; @plusone(y), изменит привязку y;
  3. Наконец, вы можете использовать Ref, как обсуждалось выше (или любую другую изменяемую оболочку- как вы отметили в своем вопросе).
...