Racket 在这种情况下,我为什么需要评估lambda

Racket 在这种情况下,我为什么需要评估lambda,racket,Racket,以下代码是一个# 我不知道为什么会这样。我需要应用lambda表达式 #lang racket (require threading) (~>> 1 ((lambda (x) x)) ) 只有这样,它才会产生1,这是我所期望的线程包提供的宏,它将前面的表达式插入后面的表达式中。当它看到这样的模式时: #lang racket (require threading) (~>> a (f b _)) 它在第二个子表单中查找。,并将a插入表单中的(f b

以下代码是一个
#

我不知道为什么会这样。我需要应用lambda表达式

#lang racket
(require threading)
(~>> 1
     ((lambda (x) x))
)

只有这样,它才会产生
1
,这是我所期望的线程
包提供的宏,它将前面的表达式插入后面的表达式中。当它看到这样的模式时:

#lang racket
(require threading)
(~>> a
     (f b _))
它在第二个子表单中查找
,并将
a
插入表单中的
(f b a)
位置

更让人困惑的是有一个速记。如果
\
位于
~>
子表单的末尾,则可以忽略它。当它看到像
(fb)
这样没有
(fb)
的东西时,它会在末尾插入它,就好像你写了
(fb)
。这就是lambda案例中发生的情况,它将您的语法解释为等价于
(lambda(x)x)

插入
1
后的结果是
(lambda(x)x1)
。那不是你所期望的

你想要什么 从您对lambda函数的使用和期望来看,似乎不需要这种复杂的宏行为;您只希望它将它们作为函数应用。所需的线程形式只需将后面的表达式应用于前面表达式的结果,将
(~>a(fb))
转换为
((fb)a)
。这个更简单的版本由软件包提供

您可以将这个更简单的
~>
与一个简写的lambda包(如
fancy app
)结合起来,使这样的表达式看起来更漂亮

(require fancy-app)
(~> 1
    (+ _ 10)
    (expt _ 4)
    number->string
    (printf "~a seconds" _))
;=outputs> 14641 seconds

这种常见的混乱让我担心
线程
是一种不合适的功能,尤其是因为Racket允许像
这样的灵活应用程序
。您认为值得在
线程化
的文档中添加免责声明吗?我认为文档可能更清晰。从第一个示例看,它似乎将
(~>1 add1 sqrt)
转换为
(sqrt(add1))
,然后下一个带有
字节引用的示例没有太多解释。我不确定,您应该如何引入这样一个概念,即它以不同的方式对待带括号的表达式?好的,接下来的整个部分(第1.2节)用
bytes ref
解释了这个示例。也许这需要说得更清楚些?虽然有人简要地提到过,
f
相当于
(f)
这一点,也许需要更加突出?对于仅仅看了前几个例子的人来说,开头的
f
相当于
(f)
的解释是没有意义的。你需要弄清楚,在前两个例子中,它特别处理带括号的表达式。这很公平,是的。当我有时间的时候,我可以试着重写一些文档。
#lang racket
(require point-free)
(~> 1
    (lambda (x) x))
;=> 1
(~> 1
    (lambda (x) (+ x 10))
    (lambda (x) (expt x 4))
    number->string
    (lambda (x) (printf "~a seconds" x)))
;=outputs> 14641 seconds
(require fancy-app)
(~> 1
    (+ _ 10)
    (expt _ 4)
    number->string
    (printf "~a seconds" _))
;=outputs> 14641 seconds