Search code examples
typesfunctional-programmingsmlsmlnj

Function which applies its argument to itself?


Consider the following SML function:

fn x => x x

This produces the following error (Standard ML of New Jersey v110.72):

stdIn:1.9-1.12 Error: operator is not a function [circularity]
  operator: 'Z
  in expression:
    x x

I can sort of see why this isn't allowed -- for one, I'm not really sure how to write down what its type would be -- but it's not completely nonsensical; for instance, I could pass the identity function to it and get it back.

Is there a name for this function? (Is there a way to express it in SML?)


Solution

  • There is no way to express this function in a language with an ML-like type system. Even with the identity function it wouldn't work, because the first x and the second in x x would have to be different instances of that function, of type (_a -> _a) -> (_a -> _a) and _a -> _a, respectively, for some type _a.

    In fact, type systems are designed to forbid constructs like

    (λx . x x) (λx . x x)
    

    in the untyped lambda calculus. In the dynamically typed language Scheme, you can write this function:

    (define (apply-to-self x) (x x))
    

    and get the expected result

    > (define (id x) x)
    > (eq? (apply-to-self id) id)
    #t