我想在程序的不同部分中多次调用类似rand((0, 1), N)
的东西(其中N
先前分配了一些整数)(将来我可能会更改的所有实例,例如,rand((-1, 1), N)
或[ C0])。如何创建一个引用该函数的变量,以对其进行评估?
我不想只写randn(N)
之类的东西,因为那样的话,每次随机值都是相同的,这是不希望的。
当然,我可以定义rand_thing = rand((0, 1), N);
并在需要写入rand_func = rand((0, 1), N);
时调用rand_func()
。我也可以做涉及rand((0, 1), N)
的事情,例如eval
,然后在我想写rand_ex = :(rand((0, 1), N));
时调用eval(rand_ex)
。但是,有没有办法我可以获取此功能,并且只写rand((0, 1), N)
来生成我的随机数?
这是一个特定的示例,它是一个更大的问题的一部分,该问题是否存在直接实现Mathematica的rand_thing
(SetDelayed
)功能的东西。如果我在Mathematica中使用:=
而不是rand_thing := RandomReal[];
,那么每次我写thing = RandomReal[];
时,我都会得到一个新的随机数。 (在Mathematica中,我不会在变量名下使用下划线,但是无论如何。)
如果无法描述我所描述的内容,那么对为什么在Mathematica中可能会出现类似rand_thing
的东西却在Julia中却无法做到的见解会有所帮助。这是语言上的根本区别吗?还是不同公约的问题?还是Julia可能很容易拥有延迟的set运算符,但到目前为止它还不是语言语法的一部分? (如果是这样,实现将是什么样子?)还是其他?
一个被引用的变量,将对该函数求值
正如您正确观察到的,被称为... 功能。
SetDelayed
并且不,除了返回该符号的值外,没有任何其他方法可以使符号rand_thing() = rand((0, 1), N)
的计算方式有所不同。只有更改评估方式后,您才能拥有它。
现在,在Mathematica中,评估的工作原理确实有所不同。那里基本上是一个重写系统。默认情况下,评估将以类似的方式工作-“如果看到名称rand_thing
,请查找其值,然后用该值替换x
,然后继续评估”。
x
(这是一个伪记号,我在随身环境中使用{} (x = 2; x)
~> {x = 2} x
~> {x = 2} 2
,{}
代表“求和”。]
但是如果~>
由x
定义,则更像是“查找SetDelayed
的定义,将其替换为定义,然后继续求值”:]
x
您可以在Julia中更改评估的唯一方法是使用{} (x := rand(N); x)
~> {x = :(rand(N))} x
~> {x = :(rand(N))} rand(N)
~> {x = :(rand(N))} 0.2342343
。但这并不比函数调用短。你必须写类似
macro
扩展到
@undelay x .+ 1
但我看不出有任何有利的理由。另外,您还必须找出哪些值是延迟的,哪些是正常值,这会使事情变得复杂。
您可以像这样构成语法
(rand(N)) .+ 1
尽管,但是您必须自己保护正确的作用域行为,对此我不知道有什么简单的解决方案。 (甚至)>
@delayed let x = rand(N) x .+ 1 end
可以作为宏,但是更麻烦。 )
[请注意,有一个名为@delayable begin
x := rand(N)
x .+ 1
end
的概念,它会沿您想要的方向前进-但它是一种数据结构,是对函数的语义抽象,并且不会使语法更容易。