在Julia中是否有延迟集?(相当于Mathematica中的:=)

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

我想叫这样的东西 rand((0, 1), N) (有 N 之前分配的某个整数)在程序的不同部分多次出现(所有出现的次数,我可能在将来会改为,例如。rand((-1, 1), N)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). 然而,有没有一种方法可以让我得到这个功能,并且只编写 rand_thing 来生成我的随机数?

这是一个具体的例子,它是一个更大的问题的一部分,即是否有一些东西直接实现了 SetDelayed (:=)。如果我做了 rand_thing := RandomReal[]; 而不是 thing = RandomReal[]; 在Mathematica中,每次我写下了 rand_thing 我得到一个新的随机数。(在Mathematica中,我不会用下划线来表示变量名,但不管怎样)。

如果我所描述的是不可能的,那么就请您深入了解一下为什么类似于 SetDelayed 在Mathematica中可以实现,但在Julia中却不可以。这是语言上的根本区别吗?还是习惯不同的问题?或者Julia可以很容易地拥有一个延迟集运算符,但到目前为止它还不是语言语法的一部分?(如果是这样,实现起来会是什么样的?)或者是其他什么?

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

(首先我要说的是,我对Wolfram语言的唯一了解是,它是基于术语重写的。)

一个变量,每当它被引用的时候,就会评估这个函数。

被称为......一个 函数,正如你所观察到的那样。

rand_thing() = rand((0, 1), N)

而且,没有办法对一个符号进行评价。rand_thing,除了返回该符号的值之外,还可以有其他行为。 只有改变评估的工作方式,您才能得到这种结果。

现在,在 Mathematica 中,评估的工作方式确实不同。 在Mathematica中,您基本上有一个重写系统。 默认情况下,评估的工作方式与此类似 -- "如果您看到一个名字为 x,查找它的价值,并替换 x 的值,并继续评估"。

{} (x = 2; x) 
  ~> {x = 2} x   # update environment
  ~> {x = 2} 2   # replace x

(这是个伪注解,我在这里用的是 {} 携带的环境和 ~> 代表 "评估到")。)

但如果 x 被定义为 SetDelayed,它更像是 "查一查 "的定义。x,用定义代替它,然后继续评估"。

{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中改变评价的唯一方法是使用一个叫做 宏观. 但这并不比函数调用短,你必须写一些类似于

@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.