Data from functions:
(define (cons x y) (lambda (m) (m x y)))
(define (car z) (z (lambda (p q) p)))
(define (cdr z) (z (lambda (p q) q)))
(define (cons x y) (lambda (m) (m x y)))
(define (car z) (z (lambda (p q) p)))
(define (cdr z) (z (lambda (p q) q)))
Then if you really want to go down the rabbit hole, there's SKI, which is lambda calculus without a lambda operator, just 3 named, curried functions(S, K and I, but I is techically definable in terms of S and K). Any function that can be expressed in lambda calculus can be expressed in terms of calling these various functions with eachother as arguments.
Assuming LAMBDA is automatically curried, to save myself some typing:
(define (k x y)
x)
(define (s x y z)
((x z) (y z)))
(define (i x)
x)
Alternatively, I can be defined as follows: (define i (s k k))
SKI is implemented in the Unlambda esolang, with some additional functions defined for IO and convenienceIf variable environments are implemented as hash tables, you're just making a pair out of a hash table. In other words, it's basically equivalent to:
function cons(x, y) {
return { "first": x, "second": y };
}
function car(x) { return x["first"]; }
function cdr(x) { return x["second"]; }