diff --git a/theories/utils/list.v b/theories/utils/list.v
index 1767faa4a4daf98eb063578779ed6c33f95bc351..26885df64e52c0041e2d9bb2d65596cd327eebe8 100644
--- a/theories/utils/list.v
+++ b/theories/utils/list.v
@@ -54,36 +54,34 @@ Definition llength : val :=
     | SOME "p" => #1 + "go" (Snd "p")
     end.
 
-Definition lsnoc : val :=
-  rec: "go" "l" "x" :=
+Definition lapp : val :=
+  rec: "go" "l" "k" :=
     match: "l" with
-      SOME "p" => (lcons (Fst "p") ("go" (Snd "p") "x"))
-    | NONE => lcons "x" NONE
+      NONE => "k"
+    | SOME "p" => lcons (Fst "p") ("go" (Snd "p") "k")
     end.
 
+Definition lsnoc : val := λ: "l" "x", lapp "l" (lcons "x" (lnil #())).
+
 Definition ltake : val :=
   rec: "go" "l" "n" :=
-  if: "n" ≤ #0
-  then NONEV
-  else match: "l" with
-         SOME "l" => lcons (Fst "l") ("go" (Snd "l") ("n"-#1))
-       | NONE => NONEV
-       end.
+    if: "n" ≤ #0 then NONEV else
+    match: "l" with
+      NONE => NONEV
+    | SOME "l" => lcons (Fst "l") ("go" (Snd "l") ("n"-#1))
+    end.
 
 Definition ldrop : val :=
   rec: "go" "l" "n" :=
-    if: "n" ≤ #0 then "l"
-    else match: "l" with
-         SOME "l" => "go" (Snd "l") ("n"-#1)
-       | NONE => NONEV
-         end.
+    if: "n" ≤ #0 then "l" else
+    match: "l" with
+      NONE => NONEV
+    | SOME "l" => "go" (Snd "l") ("n"-#1)
+    end.
 
-Definition lsplit_at : val :=
-  λ: "l" "n",
-  (ltake "l" "n", ldrop "l" "n").
+Definition lsplit_at : val := λ: "l" "n", (ltake "l" "n", ldrop "l" "n").
 
-Definition lsplit : val :=
-  λ: "l", lsplit_at "l" ((llength "l") `quot` #2).
+Definition lsplit : val := λ: "l", lsplit_at "l" (llength "l" `quot` #2).
 
 Section lists.
 Context `{heapG Σ}.
@@ -164,13 +162,21 @@ Proof.
   rewrite (Nat2Z.inj_add 1). by iApply "HΦ".
 Qed.
 
+Lemma lapp_spec vs1 vs2 :
+  {{{ True }}} lapp (llist vs1) (llist vs2) {{{ RET (llist (vs1 ++ vs2)); True }}}.
+Proof.
+  iIntros (Φ _) "HΦ".
+  iInduction vs1 as [|v1 vs1] "IH" forall (Φ); simpl.
+  { wp_rec. wp_pures. by iApply "HΦ". }
+  wp_rec. wp_pures. wp_apply "IH". iIntros (_). by wp_apply lcons_spec.
+Qed.
+
 Lemma lsnoc_spec vs v :
   {{{ True }}} lsnoc (llist vs) v {{{ RET (llist (vs ++ [v])); True }}}.
 Proof.
-  iIntros (Φ _) "HΦ".
-  iInduction vs as [|v' vs] "IH" forall (Φ).
-  { wp_rec. wp_pures. wp_lam. wp_pures. by iApply "HΦ". }
-  wp_rec. wp_apply "IH"; iIntros (_). by wp_apply lcons_spec=> //.
+  iIntros (Φ _) "HΦ". wp_lam. wp_apply (lnil_spec with "[//]"); iIntros (_).
+  wp_apply (lcons_spec with "[//]"); iIntros (_).
+  wp_apply (lapp_spec with "[//]"); iIntros (_). by iApply "HΦ".
 Qed.
 
 Lemma ltake_spec vs (n : nat) :