Comments 66
Статью не читай — сразу комментируй!
$x = 1;
$y = 2;
$arr = [
($x) => $x * $y, // дословная копипаста из примера
];
// что мы получим в итоге?
$arr == [1 => 2]; // сейчас будет этот вариант
$arr == [0 => callable]; // так хотите?
А вот от этого $arr = [(($x) => $x * $y)()] — первый.
А теперь подумайте и скажите, по какому контексту транслятор сможет отличать пару от лямбды, кроме случаев, когда ключ — константа?
$arr == [0 => 2];
Как минимум — это ломает обратную совместимость. Такой вариант нельзя было впихнуть в 7.4 из-за этого.
2) для читаемости. Т.е. Collection читается хуже, чем Collection<User>
1) При указании типа аргумента/возврата — этот тип жестко прописывается в атрибутах функции на этапе компиляции и проверяется достаточно дешево. Для дженериков придется полностью переделывать механизм проверки, что однозначно не в лучшую сторону повлияет на производительность.
IDE же отлично работает с phpdoc комментариями User[] $users
.
2) Не очень удачный пример для языка с убертипом array
Не то, чтоб я был против дженериков, но объем работы для их добавления, по моему скромному мнению, не сопоставим с полезным выхлопом.
Да мне кажется, дженерики тоже можно на этапе компиляции проверять. Просто запрещать передавать переменные без указания типа. Типизация же, зачем они нужны. Если надо, можно сделать функцию-обертку, которая будет принимать типизированные аргументы и передавать дальше в дженерик. Чтобы обертки не плодить, можно какой-нибудь оператор типизации придумать, типа $x as User
или (User)$x
, рантайм-проверка будет в нем происходить.
Ну да, фейсбук, википедия, вконтакт, Baidu, tumblr, digg, совсем мертвый. И это если не считать всякие вордпрессы и опенкарты.
// так сделано в Rust, но читабельность спорна
|$x| => $x * $y
Спорное утверждение :-)
array_map(function($x) {return $x*$x;}, $arr);
против
array_map(fn($x) => $x*$x, $arr);
Прям глаз радуется.
Да и в любом случае это не совсем сахар — таки замыкание по умолчанию.
array_map(function($x) {
return $x * $x;
}, $arr);
Честно? — Совсем не раздражает. Это сугубо субъективно, — не имеет смысла обсуждать. Факт в том, что вводя миллион правильных способов сделать одно и тоже — мы получим то, что весь миллион способов будет использоваться. Соответственно для интеграции нового программиста в язык — ему нужно будет учить весь миллион способов.
Обратите внимание, мой изначальный комментарий вообще никак не задевает именно стрелочные функции. Я говорю о вреде самой тенденции роста синтаксического сахара в языке. Решения принимаемые голосованием не обязательно являются верными.
Язык развивается, к людям приходит понимание, что некоторые изначальные решения были так себе и можно сделать лучше и удобнее. Необходимость поддерживать обратную совместимость — это бич любого уважающего себя языка, сильно затрудняющий его развитие, но не являющийся поводом совсем его не развивать.
Синтаксический сахар, когда он уместен — это крайне полезная и правильная вещь. Посмотрите, например, на успех Kotlin, где сахарок возведен фактически в абсолют. Что касается PHP, то чистого сахара в нем еще поискать надо. Так, на вскидку, только краткий синтаксис массивов вспоминается, скажите еще, что его зря вводили.
Попробуйте прочитать заново мои комментарии. В них написано ровно то, что написано, а не то что вы себе придумали.
Про легаси вы совершенно не попали, — никто старый синтаксис лямбд или массивов не собирается объявлять устаревшим, это были решения не «так себе», как вы выразились.
Так-то вариант с foreach вполне адекватен:
foreach($arr as &$x) $x *= $x;
unset($x);
Если избавиться от unset, то по количеству символов будет даже короче стрелочной функции. И тут возникнет вопрос, а нужны ли стрелочные функции…
// нереализуемо, путаница с получением свойств объектаВсегда было интересно, почему в одних языках могут сделать одинаковую работу с внутренностями объекта (независимо от того, указатель это или объект сам), например через точку, а в других языках приходится придумывать несколько разных вариантов?
($x) -> $x * $y
А в данном случае, что, реально может быть свойство с именем `$x * $y`?
И да, это вполне рабочий код:
class Test{
public $test = 2;
public function __toString(){
return 'test';
}
}
$x = new Test;
$y = 1;
$result = ($x) -> $x * $y;
var_dump($result);
Разве не у всех подобное есть в продакшне? =)
чтобы было свойство $x * $y — нужно использовать фигурные скобкиА, ну да, я что-то протупил.
class Test{
public function __get($attr){
return '5';
}
public function __toString(){
return '2';
}
}
$x = new Test;
$y = 1;
$result = ($x) -> {$x * $y}; // Notice: Object of class Test could not be converted to int
var_dump($result); // 5
$result = Collection::from([1, 2])
->map(fn($v) => $v * 2)
->reduce(fn($tmp, $v) => $tmp + $v, 0);
И чем это лучше чем
$result = 0;
for ($v = 1; $v < 3; $v++)
$result += $v * 2;
Вообще ничем, лишние слова map, reduce, Collection, fn, лишний синтаксис, fn, =>, и компактнее код совсем не стал. Нафига козе боян. Простой и понятный язык превращают непонятно во что, только потому что модно, и в других языках есть.
$result = 0;
for ($v = 1; $v < 3; $v++)
$result += $v * 2;
И чем это лучше чем
$result = 6;
Вообще ничем, лишний for, ++ и *, и компактнее код совсем не стал.
Collection::fromOneAndTwo()
->mapQuadFunctionThenReduceToSum()
Вопрос лишь в том, когда пора остановиться. Нельзя плодить сущности безнаказанно.
Вот опять — вроде отличная идея, а реализация вносит еще больше хаоса в и без того сумбурный язык. Теперь есть два синтаксиса для анонимных функций: один (как я понял) только для выражений, автоматически захватывает scope и использует одно ключевое слово (fn
), другой — для утверждений, захватывает явно и использует другое ключевое слово — function
. Оккам смотрит на это решение с недоумением.
Еще очень удивило "слишком сложно для текущего парсера". С каких пор это весомая причина для того, чтобы отказаться от хорошего, проверенного решения в дизайне языка?
ИМХО.
так сделано в языке Hack; но слишком сложно для текущего парсера
Вообще-то нет, LALR всё это позволяет. Аргументация была другой, что это дополнительные нагрузки на lookahead парсинг (т.е. неоднозначность грамматики), тогда как PHP чувствителен к скорости парсинга, а значит профитнее добавлять префикс, вместо суффикса.
`fn&($x) => $x;`
объясните плз
положу это здесь может кому понадобится:
www.php.net/manual/ru/language.references.return.php
Жесть, ну и синтаксис.
Напоминает МАКРО-11, где можно было
mov 10,r0
— помещает в регистр PC+10mov #10,r0
— помещает в регистр 10mov @10,r0
— помещает в регистр значение по адресу PC+10mov @#10,r0
— помещает в регистр значение по адресу 10
и плюс ещё кучу вариантов комбинаций этого с другими символами при переносе из регистра в регистр/память с преинкрементом, предекрементом, постинкрементом и постдекрементом.
Довольно логичный синтаксис, кстати. Куда лучше всех этих word ptr [...]. Хотя я бы 10 и #10 поменял местами.
В PHP 7.4 войдут стрелочные функции (сокращенная запись анонимных функций)