Skip to content

Instantly share code, notes, and snippets.

@danking
Created July 17, 2020 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danking/2b6a9b7e2248b2f62877a7b8cddf9bee to your computer and use it in GitHub Desktop.
Save danking/2b6a9b7e2248b2f62877a7b8cddf9bee to your computer and use it in GitHub Desktop.

I realized I started using lambda without explaining what that is. My apologies.

In math class you probably defined functions by writing something like the following:

f(x) = x * 2

This defines a function named f which takes a value x and returns twice that value, 2 * x.

In Python we would write this as:

def f(x):
    return x * 2

In math and in programming, we can have functions that take functions as arguments. For example:

g(h, x) = h(h(x))

The function g has two parameters: another function h and a value x. It applies h to x twice. Let's look at what happens when we apply g to f, from above, and 10:

g(f, 10) = f(f(10))
         = f(10 * 2)
         = f(20)
         = 20 * 2
         = 40

We can write the same thing in Python:

def g(h, x):
    return h(h(x))

g(f, 10)

OK, so what's this got to do with lambda? Well, mathematicians and programmers often want to define a new function without giving it a name, like f. These functions are usually used only once as an argument to another function. In math a function without uses the greek symbol lambda and in Python we use the word lambda.

In math we write λ VARIABLE. BODY:

λ x. x * 2

In Python we write lambda VARIABLE: BODY:

lambda x: x * 2

Instead of writing this:

g(f, 10)

We could write this:

g(λ x. x * 2, 10)

In Python that looks like:

g(lambda x: x * 2, 10)

So, in our inner_product example we could have written this:

def compare_two_genotypes(Xim, Xjm):
    return hl.int((Xim == 1) & (Xjm == 1))

def add(l, r):
    return l + r

shared_hets = X.T.inner_product(
    X,
    compare_two_genotypes,
    add,
    hl.float(0),
    hl.agg.sum
)

And maybe we should have! Using long names helps us understand the code. Here's the lambda version again:

shared_hets = X.T.inner_product(
    X,
    lambda Xim, Xjm: hl.int((Xim == 1) & (Xjm == 1)),
    lambda l, r: l + r,
    hl.float(0),
    hl.agg.sum
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment