unfunction()

    Unfunction lets you see through layers of abstraction by showing function calls as if they were written inline. Simply click an underlined function or type. Works with TypeScript.

    Notation

    TypeScript NotationOur Notation
    { name: string,
    age: number,
    [otherField: string]: boolean }
    namestring
    agenumber
    otherFieldboolean
    string[]indexstring
    function doubleNum(x) {
    return x * 2
    }
    let y = doubleNum(5)
    function doubleNum(x) {
    return x * 2
    }
    let y = doubleNum(5)

    Examples

    These examples all run through our interpreter! You can modify them by scrolling down.

    Simple Example

    A simple example you can play around with.

    function fibonacci(n: number): number {
    if (n <= 1) {return n}return fibonacci(n - 1) + fibonacci(n - 2)
    }
    let z = fibonacci(5)
    Substitution

    Complication #1: We need to parameterize inlined function call arguments so that the expansion doesn't show redundant function calls.

    function twoTimesNum(x: number) {
    return x * 2
    }
    function squareNum(x: number) {
    return x * x
    }
    let z = squareNum(twoTimesNum(5))
    Closures

    Complication #2: Closures with implicit dependencies. We track implicit parameters and show them clearly when you expand them.

    let taxRate = 0.2let addTax = (price: number) → {return price + price * taxRate}return addTax(100)
    Limitations

    Complication #3: It's NP-hard to track the narrowest possible types of first-class functions with implicit parameters, like f here. TS itself does not do this at all, and this is the reason why TS itself with async/await type checking.

    We have no solution to this case, but are OK with this, because it is relatively rare and impossible to solve in general.

    type User =
    namestring
    agenumber
    function doThingsToUser(user: User, ...fns:
    index(User)undefined
    ) {
    for (const f of fns) {f(user)}
    }
    function setUserName(user: User) {
    user.name = 'Bob'
    }
    let user = { name: 'Max', age: 99 }
    doThingsToUser(user, setUserName)
    TypeScript to make expandable below:
    function fibonacci(n: number): number {
    if (n <= 1) {return n}return fibonacci(n - 1) + fibonacci(n - 2)
    }
    let z = fibonacci(5)
    See it on real code!