///|
// Follow Go's dependency walker order: direct, thunk, then special children.
// Its desugared object walk omits assertions; preserve that observed contract.
fn dependency_children(expr : Expr) -> Array[Expr] {
  let children = []
  let optional = fn(value : Expr?) {
    if value is Some(value) {
      children.push(value)
    }
  }
  let clauses = fn(items : Array[Clause]) {
    for item in items {
      match item {
        For(_, e) | When(e) => children.push(e)
      }
    }
  }
  match expr.kind {
    Literal(_)
    | NumberLiteral(_)
    | Var(_)
    | ImportFile(_, _)
    | ImportBinary(_)
    | StandardFunction(_)
    | StandardValue(_) => ()
    Local(bindings, body) => {
      children.push(body)
      for { value: e, .. } in bindings {
        children.push(e)
      }
    }
    Func(params, body) => {
      children.push(body)
      for { default_value: e, .. } in params {
        optional(e)
      }
    }
    If(a, b, c) => {
      children.push(a)
      children.push(b)
      children.push(c)
    }
    Call(target, args, _) => {
      children.push(target)
      for (_, e) in args {
        children.push(e)
      }
    }
    Arr(items) => children.append(items)
    Obj(fields, locals, _, _) => {
      for field in fields {
        children.push(field.key)
      }
      for field in fields {
        children.push(field.value)
      }
      for { value: e, .. } in locals {
        children.push(e)
      }
    }
    ArrayComp(body, items) => {
      clauses(items)
      children.push(body)
    }
    ObjectComp(key, body, items, locals) => {
      clauses(items)
      children.push(key)
      children.push(body)
      for { value: e, .. } in locals {
        children.push(e)
      }
    }
    Index(a, b) | Binary(_, a, b) => {
      children.push(a)
      children.push(b)
    }
    Slice(a, b, c, d) => {
      children.push(a)
      optional(b)
      optional(c)
      optional(d)
    }
    Unary(_, a) | Fail(a) => children.push(a)
    Assert(a, msg, body) => {
      children.push(a)
      optional(msg)
      children.push(body)
    }
  }
  children
}