Size: a a a

Compiler Development

2021 June 27

AT

Alexander Tchitchigi... in Compiler Development
Это решается просто:

foo(a, b, c) = bla a b c.
foo(a, b) = foo(a, b, 42).

Теперь третий аргумент foo по умолчанию -- 42.
источник

AK

Andrei Kurosh in Compiler Development
Некоторые проблемы остаются - например, таким образом функцию с переменным числом аргументов можно вызывать только по полному имени, а если ее передать куда-то по значению - то уже нельзя
источник

K

Kir in Compiler Development
там можно добавить перегрузку без этого аргумента, или перегрузку, работающую с кортежем определённой формы
источник

AT

Alexander Tchitchigi... in Compiler Development
Это да. С другой стороны, я нигде вообще не видел вызов анонимной функции с аргументами по умолчанию. 🤷‍♀
источник

AK

Andrei Kurosh in Compiler Development
Мне очень странно приводить поведение javascript в качестве примера для других нормальных языков, но тем не менее:

function foo(a = 1, b = 2, c = 3) {
 console.log(a, b, c);
}

function test(f) {
 f();
 f(11);
 f(11, 22);
 f(11, 22, 33);
}

test(foo);


выводит

1 2 3
11 2 3
11 22 3
11 22 33
источник

AT

Alexander Tchitchigi... in Compiler Development
Я знаю, что так можно сделать -- я никогда не видел чтобы (и не представляю зачем бы) так делали в реальном коде.
источник

[

[BRM]White Rabbit in Compiler Development
Довод за отсутствие аргументов-по-умолчанию в лямбдах:
Внутри одной функции ты точно знаешь, какой функционал должна иметь переданная лямбда и в следствие чего тебе не понадобится этот функционал
источник

[

[BRM]White Rabbit in Compiler Development
Ну и + это сильно усложняет типизацию
источник

AK

Andrei Kurosh in Compiler Development
Так в моем примере даже лямбд не было. Мы просто передали существующую функцию как значение
источник

[

[BRM]White Rabbit in Compiler Development
Надо подразумевать, что код внутри функции не знает, лямбда снаружи или другая функция
источник

AK

Andrei Kurosh in Compiler Development
Разумеется, код внутри не должен ничего знать про содержимое лямбды, которую ему передают
источник

AK

Andrei Kurosh in Compiler Development
Вот кстати более насущный пример:

function handleIteration(elem, index = undefined) {
   console.log(index ? elem + " at " + index : elem);
}

function iterateArray(array, handler) {
   for(var i = 0; i < array.length; i++)
       handler(array[i], i);    // 2 аргумента - индекс есть
}

function iterateInfinite(factory, handler) {
   while(result = factory())
       handler(result);    // 1 аргумент - индекса нет
}


Было бы удобно передавать один и тот же обработчик в разные функции
источник

МБ

Михаил Бахтерев... in Compiler Development
Можно понаписать комбинаторов, которые каррируют и подставляют нужные аргументы. Если язык хорошо поддерживает лямбды, то это делается на уровне библиотеки.
источник

K

Kir in Compiler Development
Плюсую
источник

a

alez in Compiler Development
А как их написать, можете пример привести? Функции с переменчивой арностью невыразимы на лямбдах
источник

K

Kir in Compiler Development
Просто. Берётся язык, которого все фунции унарные, например хаскелль.

foo a b c = a + b * c
foo' = foo 1
источник

a

alez in Compiler Development
Мне интересно увидеть такой пример как Андрей показал выше - где функция передается как аргумент и вызывается на разном количестве аргументов. Хаскель брать нечесно так как там есть вариадики)
источник

K

Kir in Compiler Development
За вариадики в хаскелле бьют стулом обычно, здесь используют перегруженную константу def, в которую суют поля, отличающиеся от таковых по умолчанию. Щас пример найду
источник

K

Kir in Compiler Development
{-# language NamedFieldPuns #-}


data Opts = Opts { i :: Int, s :: String }

instance Default Opts where
 def = Opts 42 "foo"

foo :: Opts -> Bar
foo (Opts { s, i }) = ...

bar = foo def { s = "bar" }
источник

a

alez in Compiler Development
Если я правильно понял, то это равносильно передаванию n-тупла/рекорда вместо n аргументов. Так все умеют
источник