Комментарии 59
В Perl это нужно, поскольку к одной переменной можно обращяться и как к скаляру, и как к массиву, и как к хешу (с разным эффектом). Но никто не мешает вместо префикса использовать функции. Просто с префиксом короче.
// данные:
$city = 'spb';
// структура:
$City = [
'slug' => 'spb',
'name' => 'Санкт-Петербург'
];
Этого более чем достаточно. А автор перемудрил имхо.
Если и рассматривать подобную дифференциацию переменных, то не через имена, а через синтаксис языка. Например, через разные конструкции инициализации.
В статически типизированных языках оно уже есть: объявление типа переменной как раз и выполняет подобную задачу.
php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict
Нет смысла делать все языки абсолютно одинаковыми. Зачем нужны 20 разных, но одинаковых языков? Для статической типизации берется другой язык. Это быстрее и надёжнее, чем переделывать php. Тем более, что type hinting там сделан хорошо, кому надо — пользуются.
Честно говоря, я работаю с очень большим проектом на PHP и постоянно приходится генерировать комментарии у переменных для того, чтобы IDE нормально подсказывала. Эдакий костыльный контроль типов. Это очень надоедает.
«Если человек г… н, то как его не называй (прим.: имеется ввиду по имени) — он все равно им останется» (с) — поэтому неважно, как вы называете переменные (с какого символа начинаются, имеется ввиду), главное уметь с ними правильно работать. А есть еще передача параметров в функции, передача по ссылке, динамические параметры/вызов функции ($class->$$property) и пр.
Не совсем понял вообще смысл статьи. Также вы говорите о RFC для PHP...?! Чтобы такой подход утвердить? Спрос не ударит в нос, как говорится, но зачем?
Это данные, структурированные определенным образом — как и массив или строка. Да даже целое число имеет свою структуру хранения в памяти (порядок байт) — хотя это обычно от программиста на ЯВУ скрыто.
Идея вполне ничего но что делать с этим
class ComboBreaker implements Iterator, ArrayAccess, Countable, Serializable{
protected $position = 0;
protected $items = [];
public function __construct($array = null)
{
$this->position = 0;
if (!is_null($array)) {
$this->items = $array;
}
}
public function rewind()
{
$this->position = 0;
}
public function current()
{
return $this->items[$this->position];
}
public function key()
{
return $this->position;
}
public function next()
{
++$this->position;
}
public function valid()
{
return isset($this->items[$this->position]);
}
public function offsetExists($offset)
{
return isset($this->items[$offset]);
}
public function offsetGet($offset)
{
return $this->offsetExists($offset) ? $this->items[$offset] : null;
}
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->items[] = $value;
} else {
$this->items[$offset] = $value;
}
}
public function count()
{
return count($this->items);
}
public function offsetUnset($offset)
{
unset($this->items[$offset]);
}
public function __toString()
{
return 'combo breaker';
}
public function __invoke(){
echo $this->position;
}
public function serialize()
{
return serialize($this->items);
}
public function unserialize($data)
{
$this->items = unserialize($data);
}
}
Я ещё о том, что например объект это не тип данных, потому что это не данные, это отдельная сущность, которая уже в свою очередь может содержать данные. Со структурами также.
Допустим, есть метод
function someMethod(int $first, array $second) {
....
}
У обоих аргументов явно указаны типы данных. Для чего еще необходимо менять $second на *second? Чтобы понять, что это массив? Это уже известно
Хм… кажется я где-то уже видел…
честно говоря, я думаю, что это попытка троллинга. :)
Что касается использования дополнительных символов (крышки и прочее)… В том же PHP все привыкли использовать $<имя> и при необходимости определяют тип того, что за этой переменной(ссылкой) закреплено. И лучше не менять вот так вот, сразу. Можно упоминать тип данных в имени переменной, но это как правило временное решение (избавляются при возможности).
Скоро завезут, что можно будет в переменную указывать тип нормальными словами, мол array / boolean. А не это вот всё.
В целом, всё так, но за доллар обидно.
Эти самые "$" — одно из мощнейшёих средств метапрограммирования в языке и на несколько порядков повышает его читаемость.
Ну и вообще сам дизайн языка, почти полностью, реализован так, что он довольно простой, но при этом по любой одной строчке можно понять куда идёт обращений, в каком контексте, какие данные содержит и проч. Я не могу припомнить ни одного языка, который содержал бы похожий уровень читаемости.
Простой пример:
$some->method($a + $b);
// Сразу понятно:
// 1) $some - объект
// 2) method - метод объекта
// 3) В качестве аргумента int или float
Ну и для сравнения аналог на JS:
some.method(a + b);
// 1) some может быть функцией, классом, константой, переменной... Да вообще чем угодно, хоть символом.
// 2) method - это метод, вызываемый у этой функции или прототипа (или ещё у чего угодно).
// 3) a + b - это может быть как строка (потому что конкатентация), так и число (сложение) или вообще NaN.
Так что на доллар не надо "бочку гнать", это очень крутая фича =)
А их нельзя — они зарезервированы давно и используются. По-этому подобная идея из поста физически невозможна (если уж исключать из аргументации то, что это не только визуальный мусор, который ничего не улучшает, но и наоборот, ухудшает и урезает возможности языка).
^
— оператор бинарной исключающей дизъюнкции (если я ничего не перепутал, не пользовался никогда).
%
— оператор деления по модулю.
*
— оператор умножения.
Например, символ — может быть бинарным оператором вычитания либо унарным минусом, в зависимости от контекста.
(не критика, просто заметка на полях)
А переменные используются только в унарных выражениях?
Ну, мол, что должно быть в таком коде?
const A = [1];
*A = [3];
var_dump([2]**A);
В C++ к слову есть унарные операторы * и & наравне с бинарными.
Совершенно не понял, что Вы пытались вложить в код выше.
Пример того почему зарезервированные операторы не могут быть переиспользованы. На второй строчке объявление массива с предложенным синтаксисом от автора поста, а на третьей — конфликт: Либо умножение второй строчки на значение, либо возведение в степень константы из первой строки.
Так что ваше замечание про "префиксность" какое-то совсем непонятное.
В C++ выражение
a**b
совершенно корректно: a * (*b)
, вторая звёздочка — разыменование указателя b."*" — это умножение.
"**" — это возведение в степень.
«A**B» — это A в степени B и одновременно перемножение на массив, если бы что-то такое было в языке, что предлагает топикастер.
Я же говорю совсем о другом: на «повторное» использование операторов в разных грамматических контекстах ничему не противоречит и не может быть основанием для утверждений такого рода, как
А их нельзя — они зарезервированы давно и используются.
Нельзя не потому, что они уже используются другого (то есть технически невозможно), а потому, что внесённое в статье предложение — дичь по своей сути.
Приведённый пример на С++ нужен только для иллюстрации вариантов использования одного и того же символа в разных операторах (для минуса таких форм вообще 4: унарный минус, бинарный минус, в составе преинкремента и постинкремента).
Кстати, в PHP нет оператора возведения в степень (**)
Кстати, в PHP нет оператора возведения в степень
Предлагаю ознакомиться основами языка: http://php.net/manual/ru/language.operators.arithmetic.php
Нельзя не потому, что они уже используются другого (то есть технически невозможно), а потому, что внесённое в статье предложение — дичь по своей сути.
Как раз таки почти что технически невозможно. Вывод опкодов производится во время раннего статического связывания. Более того — оптимизация этих самых опкодов, частичный DCE и редьюсинг операций (приведение N опкодов в один) — тоже производится до выполнения программы. А выполняется непосредственно уже опкод. Так что операции должны явно указывать на то, что происходит в программе. Отсюда и невозможность определить во время обхода AST является ли это степенью существующей константы или просто переменной. Ну и плюс не стоит забывать о том, что в пыхе линковка полностью ленивая и динамическая, что требует опять же исполнения кода для того, что бы понять окружение в котором оно работает.
Так что техническое решение данной проблемы — это хардкод без вывода типов и реализуется на уровне приоритетов в лексере, что в свою очередь полностью ломает обратную совместимость за счёт того, что данный оператор уже используется и зарезервирован. И добавление ещё какой-то другой логики полностью ломает существующий код.
Надеюсь так понятнее?
Приведённый пример на С++ нужен только для иллюстрации вариантов использования одного и того же символа в разных операторах (для минуса таких форм вообще 4: унарный минус, бинарный минус, в составе преинкремента и постинкремента).
А в PHP минус в двух вариантах. Унарный и бинарный, который однозначно определяется на уровне грамматики. А декремент — это уже другой оператор, т.к. обозначает совершенно иное.
При наличии оператора ** всё сказанное совершенно верно.
Про обратную совместимость — тоже полностью согласен.
Но говорил выше я про несколько иное, в контексте абстрактного языка, а не о конкретно PHP с его грамматикой и идеологией.
В любом случае, дискуссию на этом можно завершить.
О переменных в программировании