Hừ! Khảo cổ học nào đó!
Kể từ khoảng năm 2004, tôi đã sử dụng go
làm tên chung cho các vòng lặp worker đệ quy đuôi, khi thực hiện chuyển đổi worker / wrapper của một hàm đệ quy. Tôi bắt đầu sử dụng nó rộng rãi trong bytestring
, ví dụ:
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 #-}
là từ bytestring
tháng 8 năm 2005.
Điều này đã được viết trong RWH , và có lẽ đã được phổ biến từ đó. Ngoài ra, trong thư viện tổng hợp luồng , Duncan Coutts và tôi đã bắt đầu làm việc đó rất nhiều.
Từ các nguồn GHC
Mặc dù vậy, thành ngữ còn đi xa hơn. foldr
trong GHC.Base được đưa ra là:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
đó có lẽ là nơi tôi đã chọn ra mẹo (tôi đã nghĩ rằng đây là từ luận án của Andy Gill, nhưng không thể tìm thấy bất kỳ công dụng nào go
ở đó). Nó không được đưa ra dưới dạng này trong Gofer, vì vậy tôi nghĩ nó xuất hiện lần đầu tiên trong cơ sở mã GHC.
Đến năm 2001, Simon Marlow đã sử dụng go
trong một số mã cấp hệ thống, vì vậy chúng ta có thể đổ lỗi ở đâu đó trong GHC và manh mối này dẫn chúng ta đến nguồn GHC , nơi go
được sử dụng rộng rãi trong các hàm worker:
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 và Glasgow
Đào lại các bản GHC cũ, chúng ta thấy trong GHC 0.29 không thấy xuất hiện thành ngữ này, nhưng đến loạt bài GHC 3.02 (1998) thì go
thành ngữ này xuất hiện khắp nơi. Một ví dụ, trong Numeric.lhs
định nghĩa của showInt
, từ năm 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'
}}
đây là cách triển khai khác với cách được đưa ra trong báo cáo H98 . Tuy nhiên, đi sâu vào việc triển khai "Numeric.lhs" , chúng tôi thấy rằng nó không giống với phiên bản đã được thêm vào GHC 2.06 vào năm 1997 và một bản vá rất thú vị từ Sigbjorne Finne xuất hiện, vào tháng 4 năm 1998, thêm một go
vòng lặp tới Numeric.lhs.
Điều này nói rằng ít nhất vào năm 1998, Sigbjorne đã thêm go
các vòng lặp vào thư viện "std" GHC, trong khi đồng thời, nhiều mô-đun trong lõi trình biên dịch GHC có go
các vòng lặp. Tìm hiểu sâu hơn, cam kết rất thú vị này từ Will Partain vào tháng 7 năm 1996 thêm một vòng lặp "go" vào GHC - tuy nhiên, mã đến từ Simon PJ!
Vì vậy, tôi sẽ gọi đây là một thành ngữ Glasgow được phát minh bởi những người tại Glasgow, những người làm việc trên GHC vào giữa những năm 90, chẳng hạn như Simon Marlow , Sigbjorn Finne , Will Partain và Simon Peyton Jones .
loop
để thay thế.