Hmm! Etwas Archäologie!
Seit ungefähr 2004 verwende ich go
als generischen Namen für schwanzrekursive Worker-Schleifen, wenn ich eine Worker / Wrapper-Transformation einer rekursiven Funktion durchführe. Ich habe angefangen, es weit verbreitet zu verwenden bytestring
, z
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 #-}
war von bytestring
im August 2005.
Dies wurde in RWH geschrieben und wahrscheinlich von dort populär gemacht. Außerdem haben Duncan Coutts und ich in der Stream-Fusion- Bibliothek viel damit begonnen.
Aus den GHC-Quellen
Die Redewendung geht jedoch weiter zurück. foldr
in GHC.Base wird angegeben als:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
Hier habe ich wahrscheinlich den Trick aufgegriffen (ich hatte gedacht, dass dies aus Andy Gills These stammt, kann dort aber keine Verwendung go
finden). Ist es nicht in dieser Form in Gofer angegeben, daher denke ich, dass dies zuerst in der GHC-Codebasis erschien.
Bis 2001 verwendete Simon Marlow einen go
Teil des Codes auf Systemebene, sodass wir die Schuld möglicherweise irgendwo in GHC platzieren. Dieser Hinweis führt uns zur GHC-Quelle , go
die in Worker-Funktionen weit verbreitet ist:
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 und Glasgow
Wenn wir alte Versionen von GHC ausgraben, sehen wir, dass in GHC 0.29 dieses Idiom nicht vorkommt, aber in der GHC 3.02-Serie (1998) erscheint das go
Idiom überall. Ein Beispiel Numeric.lhs
in der Definition von showInt
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'
}}
Dies ist eine andere Implementierung als die eine als im H98-Bericht angegeben . Wenn wir uns jedoch mit der Implementierung von "Numeric.lhs" befassen , stellen wir fest, dass es nicht mit der Version übereinstimmt, die 1997 zu GHC 2.06 hinzugefügt wurde, und im April 1998 erscheint ein sehr interessanter Patch von Sigbjorne Finne, der a hinzufügt go
Schleife zu Numeric.lhs.
Dies besagt, dass Sigbjorne zumindest 1998 go
Schleifen zur GHC "std" -Bibliothek hinzufügte , während gleichzeitig viele Module in dem GHC Compiler Kern hatten go
Schleifen. Dieses sehr interessante Commit von Will Partain im Juli 1996 fügt GHC eine "Go" -Schleife hinzu - der Code stammt jedoch von Simon PJ!
Ich werde dies als eine Glasgow-Sprache bezeichnen , die von Leuten in Glasgow erfunden wurde, die Mitte der 90er Jahre an GHC gearbeitet haben, wie Simon Marlow , Sigbjorn Finne , Will Partain und Simon Peyton Jones .
loop
stattdessen meine Funktion auf .