朱莉娅中的延迟集合? (相当于SetDelayed或:=,来自Mathematica)

问题描述 投票:1回答:1

我想在程序的不同部分中多次调用类似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_thingSetDelayed)功能的东西。如果我在Mathematica中使用:=而不是rand_thing := RandomReal[];,那么每次我写thing = RandomReal[];时,我都会得到一个新的随机数。 (在Mathematica中,我不会在变量名下使用下划线,但是无论如何。)

如果无法描述我所描述的内容,那么对为什么在Mathematica中可能会出现类似rand_thing的东西却在Julia中却无法做到的见解会有所帮助。这是语言上的根本区别吗?还是不同公约的问题?还是Julia可能很容易拥有延迟的set运算符,但到目前为止它还不是语言语法的一部分? (如果是这样,实现将是什么样子?)还是其他?

julia wolfram-mathematica metaprogramming non-standard-evaluation
1个回答
1
投票

一个被引用的变量,将对该函数求值

正如您正确观察到的,被称为... 功能

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 的概念,它会沿您想要的方向前进-但它是一种数据结构,是对函数的语义抽象,并且不会使语法更容易。

© www.soinside.com 2019 - 2024. All rights reserved.