¡Hmm! ¡Un poco de arqueología!
Desde alrededor de 2004 lo he usado go
como nombre genérico para los bucles de trabajo recursivos de cola, cuando hago una transformación de trabajador / contenedor de una función recursiva. Empecé a usarlo ampliamente en bytestring
, por ejemplo
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
{-# INLINE foldr #-}
era de bytestring
agosto de 2005.
Esto se escribió en RWH y probablemente se popularizó a partir de ahí. Además, en la biblioteca de stream fusion , Duncan Coutts y yo comenzamos a hacerlo mucho.
De las fuentes de GHC
Sin embargo, el idioma se remonta más atrás. foldr
en GHC.Base se da como:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
que es probablemente donde aprendí el truco (pensé que esto era de la tesis de Andy Gill, pero no puedo encontrar ningún uso go
allí). No se da de esta forma en Gofer, así que creo que apareció por primera vez en la base de código de GHC.
Para 2001, Simon Marlow estaba usando go
algunos de los códigos a nivel de sistemas, por lo que podríamos echar la culpa en algún lugar de GHC, y esta pista nos lleva a la fuente de GHC , donde go
se usa ampliamente en funciones de trabajador:
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 y Glasgow
Al desenterrar versiones antiguas de GHC, vemos que en GHC 0.29 este idioma no aparece, pero en la serie GHC 3.02 (1998), el go
idioma aparece en todas partes. Un ejemplo, en Numeric.lhs
la definición de showInt
, con fecha 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# ->
let
r' = C# c# : r
in
if n' == 0 then r' else go n' r'
}}
esta es una implementación diferente a la dada en el informe H98 . Sin embargo, al profundizar en la implementación de "Numeric.lhs" , encontramos que no es la misma que la versión que se agregó a GHC 2.06 en 1997, y aparece un parche muy interesante de Sigbjorne Finne, en abril de 1998, que agrega un go
bucle a Numeric.lhs.
Esto dice que al menos en 1998, Sigbjorne estaba agregando go
bucles a la biblioteca "std" de GHC, mientras que simultáneamente, muchos módulos en el núcleo del compilador de GHC tenían go
bucles. Profundizando más, esta confirmación muy interesante de Will Partain en julio de 1996 agrega un bucle "go" en GHC , ¡aunque el código proviene de Simon PJ!
Así que voy a llamar a esto como un idioma de Glasgow inventado por personas en Glasgow que trabajaron en GHC a mediados de los 90, como Simon Marlow , Sigbjorn Finne , Will Partain y Simon Peyton Jones .
loop
.