Here's an unofficial overview of how names seem to have become.
let
let inspired by the world of functional programming. According to Wikipedia
the expression "let" associates a function definition with a limited scope
In FP languages like Haskell, you can use let to bind values to variables in a restricted area, like
aaa = let y = 1+2 z = 4+6 in y+z
Equivalent (albeit too complicated) code in Kotlin would be
fun aaa() = (1+2).let { y -> (4+6).let { z -> y + z } }
A typical use of let is to bind the result of some calculations to an area without “contaminating” the outer area.
creater.createObject().let { if (it.isCorrect && it.shouldBeLogged) { logger.log(it) } } // `it` is out of scope here
from
The with function is inspired by the construction of the with language in languages such as Delphi or Visual Basic (and possibly many others), where
A keyword with a keyword is the convenience provided by Delphi to reference elements of a complex variable, such as a record or object.
myObject.colour := clRed; myObject.size := 23.5; myObject.name := 'Fred';
can be rewritten:
with myObject do begin colour := clRed; size := 23.5; name := 'Fred'; end;
Equivalent Kotlin would be
with(myObject) { color = clRed size = 23.5 name = "Fred" }
To apply
apply was added to stdlib at a relatively late stage stage (M13). You can see this question from 2015, when the user requests just such a function and even offers to use the later used name "apply".
In the problems https://youtrack.jetbrains.com/issue/KT-6903 and https://youtrack.jetbrains.com/issue/KT-6094 you can see naming discussions. Alternatives such as build and init were proposed, but the name apply , proposed by Daniil Vodopyan, ultimately won.
apply is similar to with in that it can be used to initialize objects outside the constructor. That is why, in my opinion, apply can also be called with . However, since with was first added to stdlib, Kotlin developers decided not to violate the existing code and added it under a different name.
Oddly enough, the Xtend language provides the so-called with the => operator , which basically does the same thing as apply .
and
also was added to stdlib even later apply , namely in version 1.1. Again, https://youtrack.jetbrains.com/issue/KT-6903 contains a discussion. The function is basically similar to apply , except that instead of the lambda T.() -> Unit extension, a regular lambda (T) -> Unit is required.
Among the suggested names were "applyIt", "applyLet", "on", "tap", "touch", "peek", "make". But he also won because he does not encounter any keywords or other functions of stdlib, and his customs (more or less) are considered English sentences.
Example
val object = creater.createObject().also { it.initiliaze() }
reads a bit like
Creater, create an object and also initialize it!
Other stdlib features whose habits read a bit like English sentences include takeIf and takeUnless , which were also added in version 1.1.
run
Finally, the run function actually has two signatures. First fun <R> run(block: () -> R): R just accepts lambda and works . It is mainly used to assign the result of a lambda expression to a top-level property.
val logger = run { val name = System.property("logger_name") Logger.create(name) }
The second signature is fun <T, R> T.run(block: T.() -> R): R is an extension function that takes the lambda extension as a parameter and is apparently also called "run" for symmetry. It also “launches” lambda, but in the context of an expansion receiver
val result = myObject.run { intitialize() computeResult() }
I do not know any historical reasons for naming.