朱莉娅有延迟设置吗? (相当于 := 来自 Mathematica)
Is there delayed set in Julia? (equivalent of := from Mathematica)
我想在程序的不同部分多次调用类似 rand((0, 1), N)
的东西(之前分配了 N
一些整数)(我将来可能会更改所有出现的地方,因为例如,rand((-1, 1), N)
或 randn(N)
)。我怎样才能创建一个变量,只要它被引用,就会计算这个函数?
我不想只写类似 rand_thing = rand((0, 1), N);
的东西,因为那样随机值每次都是相同的,这是不希望的。
当然我可以定义rand_func = rand((0, 1), N);
,想写rand((0, 1), N)
的时候调用rand_func()
。我还可以做涉及 eval
的事情,比如 rand_ex = :(rand((0, 1), N));
,然后在我想写 rand((0, 1), N)
时调用 eval(rand_ex)
。但是,有没有一种方法可以获得此功能并且只写 rand_thing
来生成我的随机数?
这是一个具体的例子,它是一个更大问题的一部分,即是否有某些东西可以直接实现 Mathematica 的 SetDelayed
(:=
) 的功能。如果我在 Mathematica 中使用 rand_thing := RandomReal[];
而不是 thing = RandomReal[];
,那么每次我写 rand_thing
我都会得到一个新的随机数。 (在 Mathematica 中,我不会使用下划线作为变量名,但无论如何。)
如果我所描述的是不可能的,那么对为什么像 SetDelayed
这样的东西在 Mathematica 中是可能的而不是在 Julia 中的一些见解将不胜感激。这是语言的根本区别吗?或者这是不同约定的问题?或者也许 Julia 可以很容易地拥有一个延迟的集合运算符,但到目前为止它还不是语言语法的一部分? (如果是这样,实现会是什么样子?)还是其他?
(首先让我说一下,我对 Wolfram 语言的唯一了解就是它基于术语重写。)
a variable that, whenever it is referenced, evaluates this function
被称为...一个 函数 ,正如您正确观察到的那样。
rand_thing() = rand((0, 1), N)
不,除了返回该符号的值之外,没有其他方法可以对符号进行求值 rand_thing
。如果你改变评估的工作方式,你只能拥有它。
现在,在 Mathematica 中,求值的方式确实有所不同。你基本上有一个重写系统。默认情况下,评估的工作方式类似——"if you see a name x
, look up the value of it an replace x
by that value, and continue evaluation"。
{} (x = 2; x)
~> {x = 2} x # update environment
~> {x = 2} 2 # replace x
(这是伪符号,我使用 {}
表示携带环境,~>
代表 "evaluates to"。)
但是如果 x
是由 SetDelayed
定义的,它更像是 "look up the definition of x
, replace it by the definition, and continue evaluating":
{N = 42} (x := rand(N); x)
~> {N = 42, x = :(rand(N))} x # update environment
~> {N = 42, x = :(rand(N))} rand(N) # replace x
~> {N = 42, x = :(rand(N))} rand(42) # replace N
~> {N = 42, x = :(rand(N))} [0.2342343, ...] # evaluate call
在 Julia 中更改求值的唯一方法是使用 macro。但这并不比函数调用短;你必须写类似
的东西
@undelay x .+ 1
扩展到
(rand(N)) .+ 1
但我看不出有任何有利的理由。另外,您还必须弄清楚哪些值是延迟的,哪些是正常值,这使事情变得复杂。
你可以编写像
这样的语法
@delayed let x = rand(N)
x .+ 1
end
尽管如此,但您必须自己注意保持正确的范围行为,对此我不知道一个简单的解决方案。 (即使
@delayable begin
x := rand(N)
x .+ 1
end
可以作为宏,但更麻烦。 )
请注意,有一个叫做 thunk 的概念,它朝着您想要的方向发展——但它是一种数据结构,是对函数的语义抽象,并且不会使语法更简单。
我想在程序的不同部分多次调用类似 rand((0, 1), N)
的东西(之前分配了 N
一些整数)(我将来可能会更改所有出现的地方,因为例如,rand((-1, 1), N)
或 randn(N)
)。我怎样才能创建一个变量,只要它被引用,就会计算这个函数?
我不想只写类似 rand_thing = rand((0, 1), N);
的东西,因为那样随机值每次都是相同的,这是不希望的。
当然我可以定义rand_func = rand((0, 1), N);
,想写rand((0, 1), N)
的时候调用rand_func()
。我还可以做涉及 eval
的事情,比如 rand_ex = :(rand((0, 1), N));
,然后在我想写 rand((0, 1), N)
时调用 eval(rand_ex)
。但是,有没有一种方法可以获得此功能并且只写 rand_thing
来生成我的随机数?
这是一个具体的例子,它是一个更大问题的一部分,即是否有某些东西可以直接实现 Mathematica 的 SetDelayed
(:=
) 的功能。如果我在 Mathematica 中使用 rand_thing := RandomReal[];
而不是 thing = RandomReal[];
,那么每次我写 rand_thing
我都会得到一个新的随机数。 (在 Mathematica 中,我不会使用下划线作为变量名,但无论如何。)
如果我所描述的是不可能的,那么对为什么像 SetDelayed
这样的东西在 Mathematica 中是可能的而不是在 Julia 中的一些见解将不胜感激。这是语言的根本区别吗?或者这是不同约定的问题?或者也许 Julia 可以很容易地拥有一个延迟的集合运算符,但到目前为止它还不是语言语法的一部分? (如果是这样,实现会是什么样子?)还是其他?
(首先让我说一下,我对 Wolfram 语言的唯一了解就是它基于术语重写。)
a variable that, whenever it is referenced, evaluates this function
被称为...一个 函数 ,正如您正确观察到的那样。
rand_thing() = rand((0, 1), N)
不,除了返回该符号的值之外,没有其他方法可以对符号进行求值 rand_thing
。如果你改变评估的工作方式,你只能拥有它。
现在,在 Mathematica 中,求值的方式确实有所不同。你基本上有一个重写系统。默认情况下,评估的工作方式类似——"if you see a name x
, look up the value of it an replace x
by that value, and continue evaluation"。
{} (x = 2; x)
~> {x = 2} x # update environment
~> {x = 2} 2 # replace x
(这是伪符号,我使用 {}
表示携带环境,~>
代表 "evaluates to"。)
但是如果 x
是由 SetDelayed
定义的,它更像是 "look up the definition of x
, replace it by the definition, and continue evaluating":
{N = 42} (x := rand(N); x)
~> {N = 42, x = :(rand(N))} x # update environment
~> {N = 42, x = :(rand(N))} rand(N) # replace x
~> {N = 42, x = :(rand(N))} rand(42) # replace N
~> {N = 42, x = :(rand(N))} [0.2342343, ...] # evaluate call
在 Julia 中更改求值的唯一方法是使用 macro。但这并不比函数调用短;你必须写类似
的东西@undelay x .+ 1
扩展到
(rand(N)) .+ 1
但我看不出有任何有利的理由。另外,您还必须弄清楚哪些值是延迟的,哪些是正常值,这使事情变得复杂。
你可以编写像
这样的语法@delayed let x = rand(N)
x .+ 1
end
尽管如此,但您必须自己注意保持正确的范围行为,对此我不知道一个简单的解决方案。 (即使
@delayable begin
x := rand(N)
x .+ 1
end
可以作为宏,但更麻烦。 )
请注意,有一个叫做 thunk 的概念,它朝着您想要的方向发展——但它是一种数据结构,是对函数的语义抽象,并且不会使语法更简单。