Давно эта мысль крутилась на кончике сознания, но только сейчас начала оформляться, поэтому спешу поделиться, пока на соскочила.
Я понял наконец, с полной ясностью, хотя, вроде и так понимал, что когда мы пишем что-то вроде function(x){xxx}, запись эта, сама по себе, это никакая не «функция» и не «подпрограмма», и даже не программа. Это, всего-лишь, правило для вычислителя, правило для подстановки. Это значит, что когда в наш черный ящик придет некий символ нужно заменить его по тому правилу, которое написано. Сама функция, в смысле, действие, от нас скрыто. Мы просто знаем, что вычислитель «сделает это», как он этобудет делать, нас не волнует. А вопрос о том, «придут» ли эти символы внутри текста программы (т.е. мы сразу их подставим), или потом, в интерактивном режиме, является второстепенным.
Это навело меня на мысль. Всплывает вопрос, а зачем мы пишем аргументные места явным образом? Ведь если для вычислителя нужно просто задать правило подстановок, то можно «договориться» с ним, что я буду писать просто (xxx), например, ((xxx)a) вычислиться в (aaa). Единственная роль аргументных мест тут, это указать порядок подстановок, например, function(x y){y x}, но мы этот порядок можем разруливать просто правильным порядком подачи аргументов. На этом роль «функциональной записи» заканчивается, у нас функция превращается просто в «правило», или «формулу», если угодно.
Очевидно, что никаких функций, выраженных непосредственно в синтаксисе, попросту не существует. Текст программы — это просто текст, не более, что там считать функциями, что данными, а что еще чем-то, находится всегда на совести абстрактного вычислителя, и он от нас всегда скрыт. Как «на самом деле» происходит подстановка, мы не знаем, и никогда не узнаем. Мы можем реализовать даже это, написав исполнитель, но мы не «видим» это, мы никогда не «видим» настоящие функции.