Skip to content

Commit ab39c72

Browse files
committed
Compiler: make List.append tailrec
1 parent f69d918 commit ab39c72

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

compiler/lib/stdlib.ml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ module List = struct
9696

9797
let slow_map l ~f = rev (rev_map ~f l)
9898

99+
let max_non_tailcall =
100+
match Sys.backend_type with
101+
| Sys.Native | Sys.Bytecode -> 1_000
102+
| Sys.Other _ -> 50
103+
99104
let rec count_map ~f l ctr =
100105
match l with
101106
| [] -> []
@@ -128,7 +133,11 @@ module List = struct
128133
f2
129134
::
130135
f3
131-
:: f4 :: f5 :: (if ctr > 1000 then slow_map ~f tl else count_map ~f tl (ctr + 1))
136+
::
137+
f4
138+
::
139+
f5
140+
:: (if ctr > max_non_tailcall then slow_map ~f tl else count_map ~f tl (ctr + 1))
132141

133142
let map l ~f = count_map ~f l 0
134143

@@ -175,8 +184,39 @@ module List = struct
175184
| `Snd y -> loop t fst (y :: snd))
176185
in
177186
loop t [] []
187+
188+
let tail_append l1 l2 = rev_append (rev l1) l2
189+
190+
let rec count_append l1 l2 count =
191+
match l2 with
192+
| [] -> l1
193+
| _ -> (
194+
match l1 with
195+
| [] -> l2
196+
| [ x1 ] -> x1 :: l2
197+
| [ x1; x2 ] -> x1 :: x2 :: l2
198+
| [ x1; x2; x3 ] -> x1 :: x2 :: x3 :: l2
199+
| [ x1; x2; x3; x4 ] -> x1 :: x2 :: x3 :: x4 :: l2
200+
| x1 :: x2 :: x3 :: x4 :: x5 :: tl ->
201+
x1
202+
::
203+
x2
204+
::
205+
x3
206+
::
207+
x4
208+
::
209+
x5
210+
::
211+
(if count > max_non_tailcall
212+
then tail_append tl l2
213+
else count_append tl l2 (count + 1)))
214+
215+
let append l1 l2 = count_append l1 l2 0
178216
end
179217

218+
let ( @ ) = List.append
219+
180220
module Nativeint = struct
181221
include Nativeint
182222

0 commit comments

Comments
 (0)