Haskell:为什么约定将辅助函数命名为“go"? [英] Haskell: why the convention to name a helper function "go"?

查看:24
本文介绍了Haskell:为什么约定将辅助函数命名为“go"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读 Haskell 材料或源代码时,我经常看到 go,但我从来没有对它感到满意 - (我猜它在我脑海中带有goto"的负面含义).我开始用 LYAH 学习 Haskell,这就是我在编写折叠时使用 accstep 的趋势.编写 go 的约定从何而来?

I see go a lot when reading Haskell material or source, but I've never been really comfortable about it - (I guess it has the negative connotation of "goto" in my mind). I started learning Haskell with LYAH, and that's where I picked up the tendency to use acc and step when writing folds. Where does the convention for writing go come from?

最重要的是,go 这个名字到底意味着什么?

Most importantly, what exactly is the name go supposed to imply?

推荐答案

嗯!一些考古学!

从 2004 年左右开始,在对递归函数进行工作器/包装器转换时,我使用 go 作为尾递归工作器循环的通用名称.我开始在 bytestring 中广泛使用它,例如

Since around 2004 I've used go as the generic name for tail-recursive worker loops, when doing a worker/wrapper transformation of a recursive function. I started using it widely in bytestring, e.g.

foldr :: (Word8 -> a -> a) -> a -> ByteString -> a
foldr k v (PS x s l) = inlinePerformIO $ withForeignPtr x $ ptr ->
        go v (ptr `plusPtr` (s+l-1)) (ptr `plusPtr` (s-1))
    where
        STRICT3(go)
        go z p q | p == q    = return z
                 | otherwise = do c  <- peek p
                                  go (c `k` z) (p `plusPtr` (-1)) q -- tail recursive
{-# INLINE foldr #-}

来自 2005 年 8 月的 bytestring.

was from bytestring in August 2005.

这是在 RWH 中写的,可能是从那里普及.另外,在流融合库中,Duncan Coutts 和我开始经常这样做.

This got written up in RWH, and probably was popularized from there. Also, in the stream fusion library, Duncan Coutts and I started doing it a lot.

来自 GHC 来源

这个习语可以追溯到更远的地方. 中的 code>foldr 为:

The idiom goes back further though. foldr in GHC.Base is given as:

foldr k z = go
      where
         go []     = z
         go (y:ys) = y `k` go ys

这可能是我找到窍门的地方(我以为这是来自 Andy Gill 的论文,但在那里找不到 go 的任何用途).它不是在 Gofer 中以这种形式给出,所以我认为这首先出现在 GHC 代码库中.

which is probably where I picked up the trick (I'd thought this was from Andy Gill's thesis, but can't find any use of go there). It isn't given in this form in Gofer, so I think this first appeared in the GHC code base.

到 2001 年,Simon Marlow 在一些系统级代码中使用了 go,因此我们可能会将责任归咎于 GHC,而这个线索将我们引向 GHC 源,其中 go 广泛用于worker函数:

By 2001, Simon Marlow was using go in some of the systems-level code, so we might place the blame somewhere in GHC, and this clue leads us to the GHC source, where go is widely used in worker functions:

myCollectBinders expr
  = go [] expr
  where
    go bs (Lam b e)          = go (b:bs) e
    go bs e@(Note (SCC _) _) = (reverse bs, e)
    go bs (Cast e _)         = go bs e
    go bs (Note _ e)         = go bs e
    go bs e                  = (reverse bs, e)

GHC 3.02 和格拉斯哥

挖掘GHC的旧版本,我们看到在GHC 0.29中没有出现这个习语,但是到了GHC 3.02系列(1998),go习语到处出现.一个例子,在Numeric.lhs中,在showInt的定义中,日期为1996-1997:

Digging up old versions of GHC, we see that in GHC 0.29 this idiom does not appear, but by GHC 3.02 series (1998), the go idiom appears everywhere. An example, in Numeric.lhs, in the definition of showInt, dated to 1996-1997:

showInt n r
  | n < 0     = error "Numeric.showInt: can't show negative numbers"
  | otherwise = go n r
    where
     go n r =
      case quotRem n 10 of                 { (n', d) ->
      case chr (ord_0 + fromIntegral d) of { C# c# -> -- stricter than necessary
      let
    r' = C# c# : r
      in
      if n' == 0 then r' else go n' r'
      }}

这是一种与 H98 报告中给出的 不同的实现.深入研究 "Numeric.lhs" 但是,我们发现它与 1997 年添加到 GHC 2.06 的版本不一样,Sigbjorne Finne 的一个非常有趣的补丁出现在 1998 年 4 月,向Numeric.lhs添加go循环./a>

this is a different implementation to the one given in the H98 report. Digging into the implementation of "Numeric.lhs", however, we find that it isn't the same as the version that was added to GHC 2.06 in 1997, and a very interesting patch from Sigbjorne Finne appears, in April 1998, adding a go loop to Numeric.lhs.

这表明至少在 1998 年,Sigbjorne 将 go 循环添加到 GHCstd"库中,同时,许多GHC 编译器核心中的模块go 循环.进一步挖掘,这个 1996 年 7 月来自 Will Partain 的非常有趣的提交添加了一个go"循环进入 GHC——不过代码来自 Simon PJ!

This says that at least by 1998, Sigbjorne was adding go loops to the GHC "std" library, while simultaneously, many modules in the GHC compiler core had go loops. Digging further, this very interesting commit from Will Partain in July 1996 adds a "go" loop into GHC -- the code comes from Simon PJ though!

所以我将称其为格拉斯哥习语,由 90 年代中期在格拉斯哥从事 GHC 工作的人发明,例如 西蒙·马洛Sigbjorn FinneWill Partin西蒙佩顿琼斯.

So I'm going to call this as a Glasgow idiom invented by people at Glasgow who worked on GHC in the mid 90s, such as Simon Marlow, Sigbjorn Finne, Will Partain and Simon Peyton Jones.

这篇关于Haskell:为什么约定将辅助函数命名为“go"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆