Wolfram mathematica 使用嵌套插槽(#)

Wolfram mathematica 使用嵌套插槽(#),wolfram-mathematica,Wolfram Mathematica,假设我想构造一个 Array[#1^#2 == 3 &, {3, 3}] 现在我想用一个变量替换“3”。我可以这样做,例如: f[x_] := Array[#1^#2 == x &, {x, x}] In[75]:= x = 5; Function[Evaluate[x],x^2] During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] s

假设我想构造一个

Array[#1^#2 == 3 &, {3, 3}] 
现在我想用一个变量替换“3”。我可以这样做,例如:

f[x_] := Array[#1^#2 == x &, {x, x}]  
In[75]:= 
x = 5;
Function[Evaluate[x],x^2]

During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] should 
  be a symbol or a list of symbols. >>
Out[76]= Function[5,x^2]
问题是:有没有办法只使用插槽和&作为函数表示法?

如何

Map[Last, #] & /@ Array[#1^#2 == #3 &, {#, #, #}] &[3]

可怕的丑陋元素提取,非常有趣的是,
Map[Last,#]&
给出了与
Last/@
不同的结果。这是因为
Map
&
具有不同的属性吗?

我想您知道文档中是怎么说的

使用显式名称设置嵌套 纯函数(例如):

函数[u,函数[v,f[u,v]]][x]

无论如何,这里是我能想出的最好的方法,而不必遵循上述建议:

f[x_] := Array[#1^#2 == x &, {x, x}]
g = Array[With[{x = #}, #1^#2 == x &], {#, #}] &
g
在功能上与原始的
f
相同,但实际上并不比推荐的更好

h = Function[x, Array[#1^#2 == x &, {x, x}]]

这并不是最初问题的答案,但我注意到很多人对
#0
感兴趣,所以我举了几个非常重要的例子,希望它们会有用

关于嵌套函数应该使用带命名参数的函数的说法:虽然这通常是正确的,但应该始终记住,纯函数(通常)的词法作用域在Mathematica中是模拟的,并且可以被打破。例如:

In[71]:= 
Clear[f,g];
f[fun_,val_]:=val/.x_:>fun[x];
g[fn_,val_]:=f[Function[{x},fn[#1^#2==x&,{x,x}]],val];
g[Array,3]

During evaluation of In[71]:= Function::flpar: Parameter specification {3} in  
   Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>
During evaluation of In[71]:= Function::flpar: Parameter specification {3} in 
   Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>

Out[74]= Function[{3},Array[#1^#2==3&,{3,3}]][3]
这种行为与规则替换的侵入性有关,也就是说,
rule
RuleDelayed
不关心作用域构造中的名称之间可能存在的名称冲突,这些名称可能存在于受规则应用程序约束的表达式中,而规则中的模式变量名称可能存在冲突。更糟糕的是,
g
f
分开服用时效果完全好。正是当它们混合在一起时,才会发生这种纠缠,这仅仅是因为我们不幸运地在
f
的主体中使用了与纯函数相同的模式变量
x
。这使得这种bug很难捕捉,而这种情况在实践中有时确实会发生,因此我建议不要将带有命名参数的纯函数作为参数传递到通过模式定义的高阶函数中

编辑:

对词法范围的模拟进行了一些扩展。我的意思是,例如,当我创建一个纯函数(这是一个词法作用域构造,将其主体中的变量名绑定到所传递参数的值)时,我希望在创建一个函数之后,我不能更改这个绑定。这意味着,无论我在哪里使用
函数[x,body-that-dependens-on-x]
,我都应该能够将其视为带有输入参数和结果输出的黑盒。但是,在Mathematica中,
函数[x,x^2]
(例如)也是一个表达式,因此可以像任何其他表达式一样进行修改。例如:

f[x_] := Array[#1^#2 == x &, {x, x}]  
In[75]:= 
x = 5;
Function[Evaluate[x],x^2]

During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] should 
  be a symbol or a list of symbols. >>
Out[76]= Function[5,x^2]
或者更简单(我先前警告的要点):

我被这最后的行为痛苦地咬了几次。这种行为也被他在第页帖子底部的@Florach注意到了——显然他也有类似的经历。根据Mathematica在冲突期间如何重命名变量的确切知识,还有其他打破范围的方法,但这些方法在实践中危害相对较小。一般来说,我认为,如果坚持用Mathematica表达式表示的透明度水平,这些事情是无法避免的。对于纯函数(以及通常的词法作用域构造),它似乎“过于透明”,但另一方面,它也有它的用途,例如,我们可以在运行时伪造一个纯函数,如下所示:

In[82]:= Block[{x},Function@@{x,Integrate[HermiteH[10,y],{y,0,x}]}]

Out[82]= Function[x,-30240 x+100800 x^3-80640 x^5+23040 x^7-2560 x^9+(1024 x^11)/11]
在定义时,积分只计算一次(也可以使用
求值
)。所以,这看起来像是一种折衷。通过这种方式,函数抽象更好地集成到Mathematica中,但正如@Frarach所指出的,它是有漏洞的。或者,它本可以是“防水的”,但也许是为了减少暴露的代价。这显然是一个设计决定。

也许

Array[#1^#2 &, {#, #}] /. i_Integer :> i == # &[3]


用[{x=#1},数组[#1^#2==x&,{x,x}]]&
怎么样?

这让我看到了
插槽(+1)的文档。阶乘的递归纯函数定义:
f=If[#1==1,1,#1#0[#1-1]]&
非常巧妙@西蒙:是的。那#0也让我担心:D@Simon,我以前从未仔细阅读过插槽文档。
#0
确实很麻烦,而且可能非常有用。@belisarius解决方案必须使用
数组
?我认为函数
可以满足您当前的需求吗?@dbjohn例如,相当于
f[x]:=Sort[x,#1>#2Last@x&]
例如
f[{7,3,2}]={7,2,3}
是的,我知道文档:D。尽管如此,我想对内部参数和外部参数使用相同的变量值的地方似乎容易被黑客攻击。@belisarius:事实上,我没有注意到是你问的问题。很抱歉下一次我将包括一个易于识别的示例:DMap[Last,#]&/@==(Last/@)&/@!=最后,Leonid感谢您的精彩解释和示例。我认为这是一个张贴它的好地方,也许你也可以在那里发表其他想法。@belisarius谢谢,我不知道这样的东西放在哪里。你认为把这篇文章放到那里并从这里链接是个好主意吗?如果是的话,我该如何重新定位帖子?我是否应该将其删除并张贴在那里?@Leonid我想你可以将其张贴在那里,并在这里留下一个答案,基本上是第一段和指向另一个答案的指针。我(希望是“我们”)想在工具包中收集有用的食谱和澄清概念。我相信你会帮上大忙的!还请注意,在我们收集索引的问题中,如果您已经拥有编辑权限,请随时维护i