Hmm! Certains l'archéologie!
Depuis 2004, j'ai utilisé go
comme le nom générique de la queue-récursive travailleur boucles, dans le cas d'un travailleur/wrapper transformation d'une fonction récursive. J'ai commencé à l'utiliser largement en bytestring
, par exemple
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 #-}
a partir de bytestring
en août 2005.
C'est écrit dans la GEPLUIE, et a probablement été popularisée à partir de là. Aussi, dans le cours d'eau de fusion de la bibliothèque, Duncan Coutts et j'ai commencé à faire beaucoup.
À partir du GHC sources
L'idiome remonte plus loin cependant. foldr
dans GHC.La Base est donnée sous la forme:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
ce qui est probablement là où j'ai pris le truc (je pensais que c'était de Andy Gill de la thèse, mais ne peut pas trouver toute utilisation de go
). Il n'est pas donné dans cette forme, en bonne à tout faire, donc je pense que c'est d'abord apparu dans le GHC base de code.
En 2001, Simon Marlow a l'aide d' go
dans certains des systèmes de code de niveau, de sorte que nous pourrions placer le blâme quelque part dans GHC, et cette idée nous conduit à la GHC source, où l' go
est largement utilisé dans les travailleur fonctions:
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 et Glasgow
Déterrer de vieilles versions de GHC, nous voyons que dans GHC 0.29 cet idiome n'apparaît pas, mais par GHC 3.02 de la série (1998), l' go
idiome s'affiche partout. Un exemple, en Numeric.lhs
, dans la définition de l' showInt
, daté de 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'
}}
c'est une mise en œuvre différente de celle donnée dans le H98 rapport. Creuser dans la mise en œuvre de "Numérique.lhs", cependant, nous trouvons que ce n'est pas la même que la version qui a été ajouté à GHC 2,06 en 1997, et un très intéressant patch de Sigbjorne Finne apparaît, en avril 1998, l'ajout d'un go
boucle Numérique.de gauche.
Cela indique qu'au moins, en 1998, Sigbjorne a été l'ajout d' go
boucles pour le GHC "std" de la bibliothèque, tandis que, simultanément, de nombreux modules dans le GHC compilateur de base a go
boucles. En creusant un peu, ce très intéressant s'engager dans Partain, en juillet 1996, ajoute un "go" en boucle dans GHC , le code vient de Simon PJ!
Donc, je vais l'appeler cela comme un Glasgow langage inventé par des gens à Glasgow qui a travaillé sur le GHC dans le milieu des années 90, tels que Simon Marlow, Sigbjorn Finne, Sera Partain et Simon Peyton Jones.