On this page:
Qi:   An Embeddable Flow-Oriented Language
8.11.1

Qi: An Embeddable Flow-Oriented Language

 (require qi) package: qi-lib

An embeddable, general-purpose language to allow convenient framing of programming logic in terms of functional flows. A flow is a function from inputs to outputs, and Qi provides compact notation for describing complex flows.

Tired of writing long functional pipelines with nested syntax like this?

(map f (filter g (vector->list my-awesome-data)))

Then Qi is for you!

(~>> (my-awesome-data) vector->list (filter g) (map f))

But wait, there’s more: Qi isn’t just a turbo-charged threading language. It supports multiple values and a suite of other operators for describing computations:
(define-flow average
  (~> (-< + count) /))

Start by getting your bearings. For an overview of the language, continue to Introduction and Usage. For a thorough orientation, watch the original video from RacketCon 2021.

    1 Using These Docs

    2 Introduction and Usage

      2.1 Overview

      2.2 Installation

      2.3 Using Qi

      2.4 Relationship to the Threading Macro

    3 Tutorial

      3.1 Interactive Tutorial

        3.1.1 Installation

        3.1.2 Setup

          3.1.2.1 DrRacket

          3.1.2.2 Emacs

          3.1.2.3 Vim

        3.1.3 Starting the Tutorial

      3.2 Online Tutorial

    4 Language Interface

      4.1 Using Qi from the Host Language

        4.1.1 Core

        4.1.2 Threading

        4.1.3 Conditionals

        4.1.4 Lambdas

        4.1.5 Definitions

      4.2 Using the Host Language from Qi

        4.2.1 Using Racket Values in Qi Flows

        4.2.2 Using Racket to Define Flows

        4.2.3 Using Racket Macros as Flows

      4.3 Using Qi with Another DSL

        4.3.1 Using Qi Directly

        4.3.2 Using a Macro Bridge

        4.3.3 Writing a Qi Dialect

    5 The Qi Language

      5.1 Basic

      5.2 Predicates

      5.3 Boolean Algebra

      5.4 Routing

      5.5 Conditionals

      5.6 Loops

      5.7 Exceptions

      5.8 Higher-order Flows

      5.9 Binding

        5.9.1 Variable Scope

      5.10 Identifiers

      5.11 Literals

      5.12 Templates and Partial Application

      5.13 Utilities

      5.14 Language Extension

    6 Qi Macros

      6.1 Defining Macros

      6.2 Using Macros

        6.2.1 Racket Version Compatibility

      6.3 Adding New Language Features

        6.3.1 Write Yourself a Maybe Monad for Great Good

        6.3.2 Translating Foreign Macros

      6.4 Writing Languages in Qi

        6.4.1 Embedded Languages

        6.4.2 Hosted Languages

        6.4.3 Embedding a Hosted Language

          6.4.3.1 Exercise: Pattern Matching

    7 Field Guide

      7.1 Writing Flows

        7.1.1 Start by Drawing a Circuit Diagram

        7.1.2 Use Small Building Blocks

        7.1.3 Carry Your Toolbox

        7.1.4 Be Intentional About Effects

      7.2 Debugging

        7.2.1 Using Side Effects

        7.2.2 Using a Probe

        7.2.3 Using Fixtures

        7.2.4 Common Errors and What They Mean

          7.2.4.1 Expected Number of Values Not Received

          7.2.4.2 Wildcard Not Allowed as an Expression

          7.2.4.3 ~@ Not Allowed as an Expression

          7.2.4.4 Bad Syntax

          7.2.4.5 Use Does Not Match Pattern

          7.2.4.6 Expected Identifier Not Starting With Character

          7.2.4.7 Identifier’s Binding is Ambiguous

          7.2.4.8 Not Defined as Syntax Class

          7.2.4.9 Too Many Ellipses in Template

          7.2.4.10 Syntax: Unbound Identifier

          7.2.4.11 Undefined

          7.2.4.12 Compose: Contract Violation

          7.2.4.13 List Arity Mismatch

          7.2.4.14 Fancy-app Arity Mismatch

          7.2.4.15 Application: Not a Procedure

        7.2.5 Gotchas

          7.2.5.1 null is Not a Literal

          7.2.5.2 There’s No Escaping esc

          7.2.5.3 Mutable Values Defy the Laws of Flows

          7.2.5.4 Order of Effects

      7.3 Effectively Using Feedback Loops

        7.3.1 Control Values and Data Values

        7.3.2 Input Tracing

        7.3.3 Keeping It Tidy

      7.4 Idioms and Transforms

        7.4.1 Nested Applications are Sequential Flows

        7.4.2 Converting a Function to a Closure

          7.4.2.1 Basic Recipe

          7.4.2.2 Definition vs Invocation Inputs

        7.4.3 Converting a Macro to a Flow

        7.4.4 Bindings are an Alternative to Nonlinearity

    8 Principles of Qi

      8.1 What is a Flow?

      8.2 Values, Paths and Flows

      8.3 Values are Not Collections

      8.4 Counting Flows

      8.5 Flowy Logic

      8.6 Phrases

      8.7 Identities

      8.8 Flows and Arrows

    9 When Should I Use Qi?

      9.1 Hadouken!

        9.1.1 Super Smush Numbers

        9.1.2 Root-Mean-Square

      9.2 The Science of Deduction

        9.2.1 Compound Predicates

        9.2.2 abs

        9.2.3 Range

        9.2.4 Length

      9.3 Don’t Stop Me Now

      9.4 Curbing Curries and Losing Lambdas

      9.5 The Value in Values

      9.6 Making the Switch

      9.7 The Structure and Interpretation of Flows

      9.8 Using the Right Tool for the Job

    10 Input Methods

      10.1 Unicode Support

      10.2 DrRacket

      10.3 Vim/Emacs

        10.3.1 Keybindings

        10.3.2 Indentation