Repository: HigherOrderCO/Bend
File: src/fun/transform/resugar_list.rs (Rust)

Code before:
          if let Term::Ref { nam } = fun.as_mut() {
            if nam == builtins::LCONS {
              let l = build_list_num_scott(tail.as_mut(), vec![std::mem::take(head)]);
              match l {
                Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
                // Was not a list term, keep as-is.
                Err(mut l) => {
                  *head = l.pop().unwrap();
                  assert!(l.is_empty())
                }
              }
            }
          }
        }
      }

      for child in self.children_mut() {
        child.resugar_lists_num_scott();
      }
    })
  }

  /// Converts scott-encoded lists ending with List/Nil to list literals.
  fn resugar_lists_scott(&mut self) {
    maybe_grow(|| {
      // Searc      h for a List/Cons pattern in the term and try to build a list from that point on.
      // If successful, replace the term with the list.
      // If not, keep as-is.

      // Nil: List/nil
      if let Term::Ref { nam } = self {
        if nam == builtins::LNIL {
          *self = Term::List { els: vec![] };
        }
      }
      // Cons: @* @c (c <term> <term>)
      if let Term::Lam { tag: Tag::Static, pat, bod } = self {
        if let Pattern::Var(None) = pat.as_mut() {
          if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_mut() {
            if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
              if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
                if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
                  if let Term::Var { nam: var_app } = fun.as_mut() {
                    if var_lam == var_app {
                      let l = build_list_scott(tail.as_mut(), vec![std::mem::take(head)]);
                      match l {
                        Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
                        // Was not a list term, keep as-is.
                        Err(mut l) => {
                          *head = l.pop().unwrap();
                          assert!(l.is_empty())

Review comment (suggestion):
```suggestion
      // Search for a List/Cons pattern in the term and try to build a list from that point on.
```

Code after:
          if let Term::Ref { nam } = fun.as_mut() {
            if nam == builtins::LCONS {
              let l = build_list_num_scott(tail.as_mut(), vec![std::mem::take(head)]);
              match l {
                Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
                // Was not a list term, keep as-is.
                Err(mut l) => {
                  *head = l.pop().unwrap();
                  assert!(l.is_empty())
                }
              }
            }
          }
        }
      }

      for child in self.children_mut() {
        child.resugar_lists_num_scott();
      }
    })
  }

  /// Converts scott-encoded lists ending with List/Nil to list literals.
  fn resugar_lists_scott(&mut self) {
    maybe_grow(|| {
      // Search for a List/Cons pattern in the term and try to build a list from that point on.
      // If successful, replace the term with the list.
      // If not, keep as-is.

      // Nil: List/nil
      if let Term::Ref { nam } = self {
        if nam == builtins::LNIL {
          *self = Term::List { els: vec![] };
        }
      }
      // Cons: @* @c (c <term> <term>)
      if let Term::Lam { tag: Tag::Static, pat, bod } = self {
        if let Pattern::Var(None) = pat.as_mut() {
          if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_mut() {
            if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
              if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
                if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
                  if let Term::Var { nam: var_app } = fun.as_mut() {
                    if var_lam == var_app {
                      let l = build_list_scott(tail.as_mut(), vec![std::mem::take(head)]);
                      match l {
                        Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
                        // Was not a list term, keep as-is.
                        Err(mut l) => {
                          *head = l.pop().unwrap();
                          assert!(l.is_empty())