4

Could you please explain how it works.

In particular: where do a,c,n,s,z come from? And how to convert this to regular functions and their calls?

x=10
y=5
abs( (lambda a: lambda z, c, n: a(a, z, c, n)) (lambda s, z, c, n: z if n == 0 else s(s, z*z+c, c, n-1)) (0, 0.02*x+0.05j*y, 10) )

It was even longer, but I figured out the rest of it.

print('\n'.join([''.join(['*'if abs((lambda a: lambda z, c, n: a(a, z, c, n))(lambda s, z, c, n: z if n == 0 else s(s, z*z+c, c, n-1))(0, 0.02*x+0.05j*y, 40)) < 2 else ' ' for x in range(-80, 20)]) for y in range(-20, 20)]))

This monster expression outputs a pseudo-graphic Mandelbrot fractal to the console.

mousetail
  • 7,009
  • 4
  • 25
  • 45
Ivar Wine
  • 43
  • 4

1 Answers1

4

This function (lambda a: lambda z, c, n: a(a, z, c, n)) can be rewritten as

def apply_function_to_itself(funk):
    def inner(arg1, arg2, arg3):
        funk(funk, arg1, arg2, arg3)
        
    return inner

This is a functional thing that calls a function with itself as the first argument. This is necessary for recursion in functional languages but in python there is usually a better way.

This function (lambda s, z, c, n: z if n == 0 else s(s, z*z+c, c, n-1)) can be rewritten as this:

def transform_n_times(funk, value, c, n):
    if n==0:
        return arg1
    else:
        return funk(funk, value * value + constant, constant, n-1)

We know from the previous function that funk === call_if_n_is_not_0, so this is a recursive function that will apply a operation n times before stopping.

So basically combined we can rewrite it like this:

def transform_n_times(value, constant, n):
    for i in range(n):
        value arg1 * arg1 + arg2
    return value

Much simpler.

Understanding the entire program

The entire code could be written like this:


def apply_function_to_itself(funk):
    def inner(arg1, arg2, arg3):
        funk(funk, arg1, arg2, arg3)
        
    return inner

def transform_n_times(funk, value, constant, n):
    if n==0:
        return arg1
    else:
        return funk(funk, value * value + constant, constant, n-1)

abs(apply_function_to_itself(call_if_n_is_not_0)(0, 0.02*x+0.05j*y, 10))

Or like this. We can get rid of the apply_function_to_itself entirely but keep the recursion like this:

def transform_n_times(value, constant, n):
    if n==0:
        return arg1
    else:
        return transform_n_times(funk, value * value + constant, constant, n-1)

abs(transform_n_times(0, 0.02*x+0.05j*y, 10))

Or we can delete the recursion entirely and just use a loop:

constant = 0.02*x+0.05j*y
value = 0
n = 10
for i in range(n):
    a1 = value * value + constant
abs(value)

The basic equation behind the mandlebrot set is f(x) = x^2+c which matches this.

mousetail
  • 7,009
  • 4
  • 25
  • 45
  • 1
    I think it is worth to mention that ` z*z+c` is the basic iteration of the Mandelbrot set: if it stays bounded (`< 2` in the comprehension that OP mentioned) the point is part of the set, thus an `*`, otherwise it is not. – nonDucor Jun 28 '22 at 07:05