based on: https://developer.android.com/develop/ui/compose/kotlin

Default Arguments

In Kotlin, function calls are much easier to read, as function calls are self documented, where parameters must be specified

//Simple function
fun drawSquare(
    sideLength: Int,
    thickness: Int = 2,
    edgeColor: Color = Color.Black
) 
{
	// Code
}

//Function call estentially self-documents itself:
drawSquare(sideLength = 30, thickness = 5, edgeColor = Color.Red)

High Order Functions & Lambda Expressions

A higher-order function is a function that takes functions as parameters, or returns a function.

Button(
    // ...
    onClick = myClickFunction
)
// Takes in function as a parameter

max(strings, { a, b -> a.length < b.length })
// b is a lambda expression, which is a function taken as a parameter, which makes max a high order function

Trailing Lambdas

A couple of rules for this:

All three function signatures are the same

// Within parenthesis
Column(
    modifier = Modifier.padding(16.dp),
    content = {
        Text("Some text")
        Text("Some more text")
        Text("Last text")
    }
) 

/*
BUT you can do outside of paranthesis to make it easier to read.
*/

// If other parameters exist:
Column(modifier = Modifier.padding(16.dp)) {
    Text("Some text")
    Text("Some more text")
    Text("Last text")
}

// If the only parameter (VERY COMMON):
Column {
    Text("Some text")
    Text("Some more text")
    Text("Last text")
}

Scopes and receivers

Some methods and properties are only available in a certain scope.

Row {
    Text(
        text = "Hello world",
        /* 
		       This Text is inside a RowScope so it has access to
		       Alignment.CenterVertically but not to
		       
           Alignment.CenterHorizontally, 
           which would be availabl in a ColumnScope. 
        */
        modifier = Modifier.align(Alignment.CenterVertically)
    )
}

Column{
		Text(
        text = "Hello world",
        modifier = Modifier.align(Alignment.CenterHorizontally)
    )
}

Sometimes, when defining a high-level function signature, if your lambda expression operates within a specific receiver context (common in some API calls), the lambda is restricted to that receiver scope.

This means the lambda has access only to the properties and functions of the receiver type, and cannot directly access elements outside of that scope unless they are explicitly passed in.

Box(
    modifier = Modifier.drawBehind {
        // The lambda operates inside the receiver 'DrawScope'
        drawRect(/*...*/)  
        // Inside the lambda, you can call functions and access properties available in DrawScope
    }
)