Pull to refresh

Comments 66

PHP 7.1 решает это:

list('name', 'age', 'location') = $myNamedArray;

А куда эти значения сохранятся? В переменные, названия которых совпадают со значениями этих строк?
UFO just landed and posted this here
О, так стало понятнее!
Интересно, а выражение в качестве имени поддерживается, или только константные строки?

$name = $random > 0.5 ? "a" : "b"
list($name => $value) = ["a" => 1, "b" => 2];
UFO just landed and posted this here
ИМХО: статья не правильная была выбрана для перевода.

> Note the syntax isn’t the usual double pipe || operator that we associate with or, rather a single pipe | character.

> You might argue that every function should return something, if only a boolean to indicate successful execution, but that’s another discussion for another day.

На самом деле крутата вот в чем:


['name' => $name, 'age' => $age] = ['name' => 'Sergey', 'age' => 24]; 
echo $name; // Sergey
echo $age; // 24

называется это "деструктуризация", есть в куче языков и тд.

Что-то я не увидел в спецификации, что будет, если запрашиваемый ключ в исходном массиве отсутствует: list('foo' => $bar) = array('bar' => 'foo');
UFO just landed and posted this here

Да, крутое применение деструктуризации

Не проще ли использовать
extract($myNamedArray);

? Аж с 4-й версии можно.

А теперь попробуем с другими ключами:


['lat' => $latitude, 'lng' => $longitude] = ['lat' => 39.465596, 'lng' => -86.858536];

printf('My Coordinates: %.6f, %.6f', $latitude, $longitude); // My Coordinates: 39.465596, -86.858536

Или еще интереснее:


['foo' => $bar] = ['foo' => 'hello', 'bar' => 'my', 'buz' => 'friend'];

echo $bar; // hello
echo $foo; // ошибка, нет такой переменной
UFO just landed and posted this here
И «|» с «or» у меня он не ассоциируется, ассоциируется с бинарным «или», который тоже есть в PHP.
Спасибо за обзор!
Еще nullable types (https://wiki.php.net/rfc/nullable_types) добавили, которого многие ждали
Сложилось впечатление, что началось движение в сторону более строгой типизации.
«Возвращаемый тип void»
«Выброс предупреждения при невалидных строках в арифметике»
Возможно, это поможет избежать некоторые неоднозначности связанные с автоматическим преобразованием типов.
PHP — идеальный пример социокультурной инверсии в программировании. Сначала придумали одно, а потом началась бесконечная гонка за модными тенденциями из всех остальных языков программирования:

  • Изначально — структурный язык, со второй попытки добавили ООП, потом лямбда-функции, где необходимо явно указывать замыкания
  • Изначально — динамическая нестрогая типизация, потом четыре раза робко добавляли неполноценные ограничения, и это не считая изменений в 7.1
  • Изначально — язык, встраемый в шаблон. Потом сделали опциональным закрывающий тег, а теперь и открывающий предлагают убрать.
  • Опции register_globals и magic_quotes_gpc — сначала использовались во всех туториалах и самоучителях, потом объявлены опасными и удалены

Направление движения, безусловно, верное. Но с таким багажом неудачных дизайн-решений и легаси светлого будущего можно ждать бесконечно.
>Но с таким багажом неудачных дизайн-решений и легаси светлого будущего можно ждать бесконечно.
Это были не неудачные решения, это был маленький язык, который и был нужен сообществу. Если бы в 90х php изначально был бы как php7 сейчас, то вряд ли кто-то он был бы нужен — его бы никто не понял. Но теперь язык развился, сообщество развилось. Когда-то register_globals и magic_quotes_gpc были нужны, а сейчас — язык стал взрослее. Это нормально.
Когда-то register_globals и magic_quotes_gpc были нужны

это как раз таки неудачное решение. Надеялись что будет хорошо но по итогу вышло плохо, хотя часть проблем это решало несомненно.

UFO just landed and posted this here

На lambda functions a.k.a. arrow functions, я так понимаю, забили?


Печалька.

там большой холивар на пустом месте родился… так что решили для 7.1 не делать. Может в 7.2...


Есть реализация одного из предложений в yay (препроцессор для PHP) но мне не нравится...

// Results in 10
$total = 'I ate 3 bananas yesterday' + 'and I ate 7 bananas today';

Это неправда. Тут будет предсказуемый 0.

А вот
$total = '3 bananas yesterday' + '7 bananas today';

вернет 10.
Голосовать не могу, но именно так. +1
Спасибо, верно подмечено
$total = '3 bananas yesterday' + '7 bananas today';

<sarcasm>
Ожидаемый результат — строка "10 bananas tomorrow"!
</sarcasm>
[$a, $b, $c] = [1, 2, 3];


Господи! Я десять лет этого ждал!
Заранее прошу не кидаться помидорами, — но стоит ли таких оваций этот кусочек синтаксического сахара
относительно list($a, $b, $c) = array(1, 2, 3) ещё седого PHP 4,
или относительно list($a, $b, $c) = [1, 2, 3] PHP 5.4+?

Я бы так возликовал, если б в PHP реализовали вроде такой штуки:
public function foobar($a, $b)
{
	__int64 $result;
	__asm {
		MOV EAX, $a
		ADD EAX, $b
		MOV $result, EAX
	}
	$result = parent::after_foobar($result);
	$log->write("foobar called with result $result");
	return $result;
}

Я бы так возликовал, если б в PHP реализовали вроде такой штуки:


Ассемблерные вставки в динамическом языке программирования?) Нет уж спасибо.
Ну а почему нет? Раз уж такая пьянка пошла, что void появился, да и в статье доходчиво описывается, как замечательно эволюционирует PHP. И то, что это интерпретируемый язык (ну почти, скорее псевдо-некомпилируемый), ещё далеко не исключает ассемблерные вставки.

Никто не заставляет использовать эту возможность, конечно.
И даже не говорит, что куски асма отправлять прямо в проц как есть, реализовать решительно все команды и дать возможность писать байткодом, — нет. Речь об контролируемых PHP и компилируемых из псевдоасма в опкоды/асм вставках.

Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки, никакой фантастики в такой смеси. Это имело место быть потому, что многого «продвинутого» интерпретатор сам не умел, не мог предоставить любопытствующему программеру — взять CPUID, перейти в режим VESA аж 800х600 и 256 цветов, читать порты и т.д.

Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.? Без необходимости привлечения для написания кастомного php-экстеншна, который потом до кучи придётся поддерживать?
А разве ассемблерные вставки поддерживать легче чем расширение на C?
Зачем их потребуется поддерживать и как-то изменять в коде, скажем, некой PHP-функции, если начиная с PHP X.X и выше всё это однозначным образом поддерживается из коробки? Один раз написал и оставь в покое.

В варианте с Си, кроме того, что это другой язык а также требуются дополнительные стыковочные компетенции написания расширений, нужно не только тот же кусок асма написать (не скрою, что на Си это делать роднее и приятнее), но и попадаешь в зависимость от этой самой «стыковки». Написал расширение для 7.0, работает. Но возьми сменись в 7.3 несовместимо что-то в работе расширений — лишний головняк, вообще с асмом и твоим алгоритмом не связанный.
кроме того, что это другой язык


А ассемблер не другой язык?
вообще с асмом и твоим алгоритмом не связанный.


сменил процессор с x86-64 на arm и появился свой головняк.
В случае сильно разных процессоров, естественно, нужен разный код.

Однако сервер с нужным железом из облака (или collocation) можно просто выбрать такой, какой тебе нужен. Как правило (уже много лет как, сейчас и в обозримом будущем) это окажется тот или иной Intel Xeon. Впрочем, можно AMD-шный взять — по части устоявшихся технологий со стажем они предоставляют единообразный набор команд. Да, x86-64 для очень многих целей достаточно.

Ассемблер конечно другой язык. Но в одном случае языков нужно два, а в другом три, плюс элементы космической стыковки.

Вообще-то нынче все в облаке и вы не знаете на каком железе крутится ваше ПО. Все за несколькими слоями абстракций. И это хорошо.


Повторюсь. Писать ассемблерные вставки в 2016-ом году нужно чувакам из области алготрейдинга, где счет идет на милисекунды. Но там как бы не используют языки со сборщиками мусора, если вы меня поняли.


В целом же intel для этих ребят уже предоставляет возможность мувнуть алгоритмы на уровень железа за счет использования FPGA что намного круче ассемблерных вставок.

В облаке можно быть по разному, в том числе и заведомо выбирая тип и даже частоту проца. К тому же всегда можно выбрать вариант физически выделенного сервера / кластера, где ты точно знаешь свои ресурсы.
Алготрейдинг — читал про это, но не занимался, пока, такими вещами.

У всего свои плюсы и минусы, бесспорно.
Лично меня очень печалит тот факт, что за несколькими слоями абстракций, зависимостей разного степени качества, за обложенными подушками, костылями и железными конями современными разработчиками конечное железо производит полезную работу на уровне 1%, если не меньше, от того, что могло выдать в случае олдскул-гик подхода.

FPGA кстати, и вообще идея программирования в железе, действительно очень интересное направление.

Так, давайте вернемся с небес на землю. Мы говорим про PHP:


  • умирающая модель выполнения.
  • блокирующее API, то есть 100% утилизация CPU уже не светит.
  • сборка мусора, машралинг.

Итого, мы не получаем ровным счетом никакого профита от возможностей писать на ассемблере. Намного проще нужный функционал написать на Си или еще лучше на Rust и использовать в крайнем случае в качестве расширения PHP. В Node.js есть целые готовые библиотеки для rust что бы упростить этот процесс. Для PHP в целом тоже не так все сложно.


Как результат стоимость поддержки таких решений будет на порядок ниже и у нас будет четкое разделение ответственности. Тестировать такие вещи так же намного проще.

Давайте, на землю можно. Главное не проскочить под землю в ад. )

Боюсь спросить о профите синтаксического сахара [$a, $b, $c] = [1, 2, 3] перед list, ну да не суть.

Да, модель выполнения с постоянной инициализацией-деинициализацией огромного слоя выполняемого кода в PHP на каждый запрос я тоже считаю злом, — тем, чего не должно быть в работе приложения-сервиса на сервере. И прочие минусы PHP сто раз подмечены.
Но всё же, статья о будущем, о PHP 7.1 и дальнейших планах. Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.

И в общем случае, вы неправы насчёт отсутствия профита. Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.

Тестирование, как я вижу, будет стоить ровно одинаково, а поддержка же не потребуется, поскольку наборы команд как были так и останутся, ровно как и предлагаемая нативная поддержка от языка.

А за дискуссию спасибо. На самом деле, я скорее на той стороне, которую вы занимаете. Но тем не менее, нововведение было бы любопытным и возможно полезным, а отсекающих причин не видно по большому счёту.

Пожалуй, я на этой ноте закруглюсь, с пожеланием разработчикам творческих побед.
Боюсь спросить о профите синтаксического сахара


Не бойтесь) Честно — это просто причесывание синтаксиса ради единообразия. Что бы синтаксис PHP больше походил на другие языки. Да, чуть потеряем самобытность, но все же это приятнее читается. И да, это мелочи.
Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.


Я где-то к этому призывал? Если бы я так думал я бы уже давно писал на каком Go но нет, я все еще топчусь с PHP. Что до умирающей модели, есть уже кучи проектов вроде того же php-pm дабы невилировать эти издержки. Да и с асинхронщикой в PHP не все так плохо.
Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.


Вы можете сделать расширение на Си, и там использовать ассемблерные вставки. Рядовому похапэшнику это всеравно не под силу и это значит что у нас рядом где-то есть сишник.
а отсекающих причин не видно по большому счёту.


На самом деле отсекающая причина простая. Вы сейчас можете это сделать без этой фичи? Можете. Это нужно 90% пользователей PHP? Нет. Это стоит того что бы инвестировать в это время вместо того что бы LLVM к opcache прикрутить или илнайнинг? Нет. И главное! Это дает разработчику возможность стрелять из гаубицы по своим ногам? Еще как.

Ну то есть это та же причина по которой в PHP нет из коробки потоков. Просто потому что в контексте WEB они ооочень редко нужны. И даже если брать экстенешн pthreads он сильно нас ограничивает в том как мы можем себя покалечить (в частности нет возможности шарить переменные между потоками неявно хоть оно все в одном адресном пространстве и крутится). Чем больше возможностей отстрелить ногу — тем больше их отстрелят.
А за дискуссию спасибо.


Вам так же!)
Раз уж такая пьянка пошла, что void появился


void запрещает возвращение значения из функции. Приведу вам пример когда это может быть полезным: к примеру вы делаете критически важную часть системы — бизнес логику. В рамках этого вы делаете интерфейсы для инфраструктурных сервисов, которые будут реализовывать джуниоры. И что бы запретить им возвращение значений из методов мутирующих состояние я могу просто на уровне интерфейса это запретить, и это будет отрабатывать на этапе парсинга, так что CI-ка отловит это даже если мы не покрывали тестами этот кусок кода. Ну а джуниор потом прослушает лекцию на тему почему методы мутирующие состояния должны быть void.
ну почти, скорее псевдо-некомпилируемый


Это интерпритируемый и называется, не выдумывайте.
ещё далеко не исключает ассемблерные вставки.


Еще как исключает. В этом просто нет смысла.
Никто не заставляет использовать эту возможность, конечно.


в контексте PHP, используюегося в основном в контексте умирающей модели выполнения, который тратит немыслемое количество ресурсов на бутстраппинг приложения при каждом запросе… давать возможность делать ассемблерные вставки выглядит поменьше мере глупо.
Речь об контролируемых PHP и компилируемых из псевдоасма в опкоды/асм вставках.


А зачем? Я вот могу написать все нужные алгоритмы на C/Rust и просто использовать это добро в PHP в качестве доп модуля. В итоге я получаю и векторизацию вычислений, и все что захочу. И при этом портируемость, стоимость поддержки будет явно ниже чем в случае ассемблерных вставок, ну и т.д.
Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки


А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.
Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.?


Повторюсь, потому что рано или поздно это за нас будет делать интерпритатор. Сам будет запаковывать данные в вектора, сам будет заниматься векторизацией и т.д. К сожалению пока этому препятствует динамическая система тиепов. Даже в javascript векторизацию можно делать только в рамках simd API. Да даже в java с этим не так хорошо потому что есть такая штука как боксинг.

А сейчас поскольку PHP не умеет так, вы можете это делать на каком rust и использовать его в PHP.
Немножко занудного определения:
Интерпрета́ция — пооператорный (покомандный, построчный) анализ, обработка и тут же выполнение исходной программы или запроса (в отличие от компиляции, при которой программа транслируется без её выполнения)


Извините уж, и это давно не тайна, но современный PHP лишь условно интерпретатор. На самом деле он компилятор.
Да. А именно:
PHP читает PHP файл, транслирует, компилирует в opcode, и выполняет скомпилированное.

Керосину в эту нашу библиотеку может плеснуть разве что eval, который is evil и который рекомендуется избегать по очевидной его мешаемости для статического анализа, трансляции и компилировании в опкод «интерпретатором» PHP.

В частности, этап сгенерённых опкодов можно кэшировать всякими Zend Opcode+ / php-apc и т.д., что позволяет PHP пропускать этап трансляции и сразу приступать к выполнению ранее скомпилированной опкодной версии сурса.

Еще как исключает. В этом просто нет смысла.

Кстати, в своём комментарии выше вы сами противоречите естественной логике. Как исключать может, почему, и тем более если привели конкретный пример где интерпретатор и асм прекрасно уживаются — видно мне не понять такого полёта мысли.

А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.

О да. Теперь программированием, разработкой, сеньёр-девелопментом и т.п. занимаются, наконец-то, не какие-то там извращенцы, а настоящие профессионалы.

Вообще, глядя на современные тенденции, можно скоро не удивляться заявлениям, что «The Hello World», не требующий
— установки менее трёх сервисных сред,
— от двадцати пяти зависимостей,
— обязательное и широкополосное подключение к интернету для отправки персональных данных в корпорацию добра для заботы о вас,
— а также не менее чем четырёхядерный проц
— и полтара гигабайта доступной под этот «The Hello World» оперативки
— e.t.c
так вообще шляпа и пережиток каменного века. )

Верю, будущее индустрии будет иным.

Я хоть и не джуниор, но с радостью послушал бы лекцию о том, почему мутирующие состояние объекта методы должны возвращать void.

Не должны а желательно что бы они ничего не возвращали.


Давайте для начала заменим термины: вызов метода — сообщения между объектами.


Сообщения могут быть трех типов:


  • Запросы — сферический примером могут служить геттеры. Они возвращают нам значения но никогда не мутируют состояние. Только чтение.
  • Команды — опять же сферический пример — сеттеры. Они не возвращают значений а только меняют состояние.
  • Смешанные — классический пример — pop для стэка. Он одновременно возвращает вершину стэка и одновременно изменяет состояние стэка. Этот тип сообщений приходится использовать что бы добиться атомарности.

Собственно из этого мы можем сделать вывод. Если у нас нет необходимости делать атомарно чтение + запись (а на самом деле это крайне редкий кейс) то лучше разделить ответственность на чтение и запись на два отдельных метода. Сделав это мы получаем возможность по разному комбинировать это добро и нам становится намного проще тестировать поведение объектов.

Ну вот на счет сеттеров я не совсем согласен.
Я вот предпочитаю цепочки вызовов, и часто пишу что-то вроде:


$object = (new SomeClass())
    ->setSomething1($a)
    ->setSomething2($b)
    ->setSomething3($c);

И получается что это сеттеры, которые меняют состояние объекта, и возвращают ссылку на этот же самый объект.

текучий интерфейс это не совсем то же самое. Это не возвращение значений, это возвращение самого себя для удобства.


p.s. я так не делаю обычно, просто потому что редко пишу сеттеры.

UFO just landed and posted this here

А почему нет?


[$b, $a] = [$a, $b]

  1. красивее чем list($b, $a) = [$a, $b];
  2. читабельнее чем list($b, $a) = [$a, $b];
  3. короче чем list($b, $a) = [$a, $b].
И вообще, всем рекомендую этот доклад Дмитрия: интересный рассказ, как удалось добиться такого прироста производительности, много сишного кода, хардкор, все как вы любите. Слушал его на CodeFest'е, это был самый технический доклад из всех, на которых я успел там побывать.
Можно повлиять на те или иные изменения

нельзя) Только через процесс обсуждения в php-internals и RFC.

try {
    // to do something
} catch (MyException | AnotherException $e) {
    // Handle these exceptions
} catch (Exception $e) {
    // Handle this in a different way
}

Всегда думал что эти вещи должны решать интерфейсы
UFO just landed and posted this here
UFO just landed and posted this here
Почему же нельзя? Я на оба повесил бы что-то вроде ClosingFileAndLoggableExceptionInterface
С одной стороны удобный сахар, а с другой Union Types по сути поощряет лень и расшатывает в некотором смысле ООП.
Имхо, неоднозначное улучшение.
UFO just landed and posted this here
Ну, чтобы держать свой код в чистоте, для такого случая пришлось бы адаптеры создавать на все используемые библиотечные классы, в адаптерах перехватывать и в своё приложение уже выбрасывать по своему типизированные, обобщённые. ООП головного мозга, короче =)

И пришлось бы в каком-то адаптере делать такое:


// ...
} catch (DoctrineException | TwigException $exception) {
    throw new MyUnifiedException('something went wrong', $exception);
}

То есть мы просто наплодим сущностей и при этом останемся с тем что было. А если мы и так говорим про какой-то адаптер (инверсия зависимостей, все такое, мы напрямую в нашем коде не зависим от сторонних зависимостей), то к чему это все...

Я бы не совмещал эксепшены из рахных сфер, вообще в идеале должны быть у каждой библиотеки свои корневые ексепшены и все остальные наследуются от них, тогда можно будет нормально ловить все эксепшены от твитера отдельно, от фейсбука отдельно, от доктрины отдельно. А для того чтоб просто логировать, есть корневой ексепшн пхп
Структурная типизация — это хорошо, гораздо удобнее и гибче «классической». Представив интерфейс в виде множества требований к классу, можно делать некоторые удобные вещи, например объединять сторонние классы своим интерфейсом, или создавать объединения \ пересечения типов.

Проблема тут в том, что операции над типами — это фундаментальный функционал системы типизации как таковой. Если это добавлять, то сразу во всех местах, где используются типы. Реализовать только частный случай в блоке try, но не реализовать в типах аргумента функции — это раскладывание граблей. Будущие поколения разработчиков будут на них наступать и плеваться.
А можете объяснить на конкретном примере, как это должно быть реализовано через интерфейсы? Сам использую конструкции вида try {} catch () {} catch () {}..., которые мне не очень нравятся

иерархия типов. Вот и весь ответ.

Обьединяйте нужне вам ексепшены в интерфейсы, если нужно что-то сделать общее при нескольких исключениях, если нет доступа к конкретному интерфейсу, всегда можно наслеваться от него и дальше см. пункт 1 — интерфейсы.
А когда уже будет нормальная перегрузка? Я уже хочу джаву в пхп.

В языках с динамической типизацией ad-hoc полиморфизм идет из коробки. Если еще добавят дженерики и объединения типов — вообще лепота будет. Перегрузка методов не нужна.

Nullable сделали, void сделалии, есть ли надежда, что появится ковариантность???

точно не в версии 7.1 и боюсь что не в 7.2… хотя кто его знает...


можно последить за RFC, но как-то за пол года ничего нового по ней нет. Там все еще есть несколько открытых вопросов и все такое...

Sign up to leave a comment.

Articles