         let n = QualifiedName(ast: headExpr.name)
         guard n.string != "_->_" else {
           assert(syntax.exprs.count == 3)
+          if let piParams = syntax.exprs[1] as? TypedParameterGroupExprSyntax {
+            return rollPi(piParams.parameters.map(self.scopeCheckParameter),
+                          self.scopeCheckExpr(syntax.exprs[2])).0
+          }
           return .function(self.scopeCheckExpr(syntax.exprs[1]),
                            self.scopeCheckExpr(syntax.exprs[2]))
         }

          args.append(elim)
        }

        let head: ApplyHead
        if self.isBoundVariable(n.name) {
          head = .variable(n.name)
        } else if let (fqn, _) = self.lookupLocalName(n.name) {
          head = .definition(fqn)
        } else if self.lookupFullyQualifiedName(n) != nil {
          head = .definition(n)
        } else {
          // If it's not a definition or a local variable, it's undefined.
          // Recover by introducing a local variable binding anyways.
          self.engine.diagnose(.undeclaredIdentifier(n), node: n.node)
          head = .variable(n.name)
        }

        return .apply(head, args.map(Elimination.apply))

      default:
        fatalError("Cannot yet handle this case")
      }

    }
  }

  private func formCompleteApply(_ n : FullyQualifiedName, _ args: [Expr]) -> Expr {
    let head: ApplyHead
    if self.isBoundVariable(n.name) {
      head = .variable(n.name)
    } else if let (fqn, info) = self.lookupLocalName(n.name) {
      switch info {
      case .constructor(_, _):
        return .constructor(fqn, args)
      default:
        head = .definition(fqn)
      }
    } else if self.lookupFullyQualifiedName(n) != nil {
      head = .definition(n)
    } else {
      // If it's not a definition or a local variable, it's undefined.
      // Recover by introducing a local variable binding anyways.
      self.engine.diagnose(.undeclaredIdentifier(n), node: n.node)
      head = .variable(n.name)
    }

    return .apply(head, args.map(Elimination.apply))
  }

  /// Scope check and validate an expression.
  private func scopeCheckExpr(_ syntax: ExprSyntax) -> Expr {
    switch syntax {
    case let syntax as NamedBasicExprSyntax:
      let n = QualifiedName(ast: syntax.name)
      return formCompleteApply(n, [])
    case _ as TypeBasicExprSyntax:
      return .type
    case _ as UnderscoreExprSyntax:
      return .meta
    case let syntax as ParenthesizedExprSyntax:
      return self.underScope { _ in
        return self.scopeCheckExpr(syntax.expr)
      }
    case let syntax as LambdaExprSyntax:
      return self.underScope { _ in
        let bindings = self.scopeCheckBindingList(syntax.bindingList)
