Вот в C++ любят делать кастомные операторы и вполне неплохо все продумано. Хотя список возможных операторов не такой уж большой, по сравнению с тем же Haskell (там можно даже >>== делать и прочие изрвраты).
В Java изначально отказались от операторов кастомных — ибо нефиг. Мало ли какой смысл ты вкладываешь в += или в << — лучше понятная и однозначная функция с читабельным именем.
В C# том же вроде и есть перегрузка, но настолько ущербная что смысла в ней нет, можно сказать что ее нет. И практически не используется.
И вопрос — вы любите эти значки разные или же лучше буквы?
=сначала спроси у GPT=
Re: Спец. символы (операторы) вместо функций - любите?
S>И вопрос — вы любите эти значки разные или же лучше буквы?
Некоторые вон даже begin end пишут вместо "значков разных"
Друга ищи не того, кто любезен с тобой, кто с тобой соглашается, а крепкого советника, кто полезного для тебя ищет и противится твоим необдуманным словам.
Re: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Shmj, Вы писали:
S>И вопрос — вы любите эти значки разные или же лучше буквы?
Так это смотря для чего. Если по логике работы объекта есть подобие взятия по индексу, пусть какому-нибудь ассоциативному или еще неочевидному, почему бы и не использовать "[]" Наверно операция аналогичная по смыслу сложению к чему-то применима, хотя конкретного примера из работы что-то не припоминаю. Ну и остальные еще экзотичнее, но вдруг. Только ради того чтобы закорючку поставить вместо слова конечно не нужно, глупо и вредно.
Но вроде как Кэпом послужил
Re: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Shmj, Вы писали:
S>Вот в C++ любят делать кастомные операторы и вполне неплохо все продумано. Хотя список возможных операторов не такой уж большой, по сравнению с тем же Haskell (там можно даже >>== делать и прочие изрвраты).
- Гиви, ты памыдоры лубиш?
— Ест лублу, а так — нэт!
Все хорошо в меру. В C++ можно перегрузить оператор запятая. То-то новички будут удивляться, если придать этому оператору нетривиальный смысл. Много ли кто вообще знает, что в Си и C++ запятая — это оператор?
Re[2]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, pagid_, Вы писали:
_>Наверно операция аналогичная по смыслу сложению к чему-то применима, хотя конкретного примера из работы что-то не припоминаю.
Конкатенация строк.
Re: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Shmj, Вы писали:
S>И вопрос — вы любите эти значки разные или же лучше буквы?
В общем случае — не люблю.
Есть ситуации, где перегрузка уместна. Самый очевидный пример: вместо BigDecimal.add() писать +. Т.е. для объектов, которые представляют из себя числа.
В С++ считаю сделано максимально отвратительно. Какое отношение битовый сдвиг имеет к вводу-выводу — я никогда не понимал и не пойму.
Про хаскель не помню. Но скорей всего мне это тоже не понравится. Я дитя западной цивилизации, мне привычны слова, а не иероглифы.
Pzz>Все хорошо в меру. В C++ можно перегрузить оператор запятая. То-то новички будут удивляться, если придать этому оператору нетривиальный смысл. Много ли кто вообще знает, что в Си и C++ запятая — это оператор?
Неновичков это тоже может удивить
Re[3]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Pzz, Вы писали:
_>>Наверно операция аналогичная по смыслу сложению к чему-то применима, хотя конкретного примера из работы что-то не припоминаю.
Pzz>Конкатенация строк.
На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается, а это достаточно частый юз-кейс. А если бы для конкатенации строк использовался отдельный оператор, например как в Lua, было бы проще: print("a + b = " .. a + b).
Ещё лучше использовать интерполяцию строк: print("a + b = \(a + b)"). С ней оператор сложения строк не нужен вообще. Любая операция вида a concatenate b заменяется на "\(a)\(b)".
Re[2]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>В С++ считаю сделано максимально отвратительно. Какое отношение битовый сдвиг имеет к вводу-выводу — я никогда не понимаю и не пойму.
Почему именно битовый сдвиг? Это у тебя просто привычка такая. А так: вполне логично сдвинуть (вдвинуть) в поток, выдвинуть из потока
vsb>Про хаскель не помню. Но скорей всего мне это тоже не понравится. Я дитя западной цивилизации, мне привычны слова, а не иероглифы.
Математику, видимо, тоже не любишь. Кстати, современную математику в основном разработала западная цивилизация, если что
Re[3]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, пффф, Вы писали:
vsb>>В С++ считаю сделано максимально отвратительно. Какое отношение битовый сдвиг имеет к вводу-выводу — я никогда не понимаю и не пойму.
П>Почему именно битовый сдвиг? Это у тебя просто привычка такая. А так: вполне логично сдвинуть (вдвинуть) в поток, выдвинуть из потока
Потому, что C++ это надстройка над C. В которой у сочетания символов << есть вполне определённое значение — битовый сдвиг. И без перегрузки оператора в С++ у этого сочетания символов ровно такое же значение.
Я не вижу в этом ничего логичного. Для меня логично писать print. Никто в юниксе ничего никуда не сдвигает.
vsb>>Про хаскель не помню. Но скорей всего мне это тоже не понравится. Я дитя западной цивилизации, мне привычны слова, а не иероглифы.
П>Математику, видимо, тоже не любишь. Кстати, современную математику в основном разработала западная цивилизация, если что
К программированию математика не имеет никакого отношения.
Re[4]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>Потому, что C++ это надстройка над C. В которой у сочетания символов << есть вполне определённое значение — битовый сдвиг. И без перегрузки оператора в С++ у этого сочетания символов ровно такое же значение.
В C у каждого оператора ровно одно значение
vsb>Я не вижу в этом ничего логичного. Для меня логично писать print. Никто в юниксе ничего никуда не сдвигает.
Очень даже в юниксе сдвигают. '<' — перенаправление ввода из файла, '>' — перенаправление вывода в файл с перезаписью, '>>' — перенаправление вывода в файл с дозаписью в конец. Как могли эти юниксоиды использовать сишечный битовый сдвиг? Кто это придумывал, сами на сишечке писали, если что
vsb>>>Про хаскель не помню. Но скорей всего мне это тоже не понравится. Я дитя западной цивилизации, мне привычны слова, а не иероглифы.
П>>Математику, видимо, тоже не любишь. Кстати, современную математику в основном разработала западная цивилизация, если что
vsb>К программированию математика не имеет никакого отношения.
Очень даже имеет.
Re[4]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается, а это достаточно частый юз-кейс. А если бы для конкатенации строк использовался отдельный оператор, например как в Lua, было бы проще: print("a + b = " .. a + b).
Это, наверное, очень индивидуально. Я ни разу в жизни не сделал такую описку. А кто-то может делает постянно.
Re[3]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, пффф, Вы писали:
Pzz>>Все хорошо в меру. В C++ можно перегрузить оператор запятая. То-то новички будут удивляться, если придать этому оператору нетривиальный смысл. Много ли кто вообще знает, что в Си и C++ запятая — это оператор?
П>Неновичков это тоже может удивить
А чтобы было еще интереснее программировать, операторы ||, && и запятая имеют гарантии порядка исполнения, слева направо. Т.е., выражение p != NULL && *p != 0 безопасно, оно сначала проверит указатель на NULL и только потом полезет в память, на которую он указывает.
Но это пока они не перегружены. А перегруженные эти операторы теряют гарантии порядка исполнения, и будут исполняться в том порядке, в котором компилятору сегодня показалось удобно.
Re[2]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, mike_rs, Вы писали: _>далеко не всегда функция может заменить оператор. см. lvalue / rvalue
В языках с поддержкой ссылок функция возвращает lvalue ровно так же, как и кастомный оператор.
Я вот по невежеству своему не знаю таких языков, в которых бы одновременно была перегрузка операторов и не было бы ref типов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Shmj, Вы писали:
S>И вопрос — вы любите эти значки разные или же лучше буквы?
Смотря какой код пишется.
Алгебраический стиль написания кода подразумевает построение цепочек выражений. Запись этих цепочек в виде префиксных функций получается очень громоздкой.
"Мало ли какой смысл" — это страшилка для новичков. На практике операторы очень редко перегружаются неожиданным образом, и ещё реже — контринтуитивным.
Затраты на обучение тому, что + обозначает конкатенацию строк, а [] — доступ к словарю по ключу, с лихвой окупаются экономией времени на разбор кода.
Что понятнее?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, mike_rs, Вы писали: _>>далеко не всегда функция может заменить оператор. см. lvalue / rvalue S>В языках с поддержкой ссылок функция возвращает lvalue ровно так же, как и кастомный оператор.
а вот тут уже на первый план выходит компактность записи и удобство использования.
std::cout << "some data: " << a << "eeg: " << b << functionCallI() << " done";
запиши без перегруженного оператора <<, чисто на функциях?
Re[4]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается, а это достаточно частый юз-кейс.
Как минимум, не нужно делать перегрузку operator+, где один операнд-string-like, а другой — не string-like (а также не делать operator std::sring() "для удобства"). C++ — не JS, стоит пользоваться системой типов разумно.
тогда код станет print("a + b = " + to_string(a + b)) или fmt::print("a + b = {}", a + b) и ошибку совершить будет сильно сложнее.
Re[3]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Pzz, Вы писали:
Pzz>Конкатенация строк.
Очевидное дело, но вряд ли мне придется выбирать использовать для этого + или нет, библиотек строк написано столько, что городить свою не планирую. А других языках чаше всего часть синтаксиса самого языка.
Re[4]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, mike_rs, Вы писали:
_>std::cout << "some data: " << a << "eeg: " << b << functionCallI() << " done"; _>запиши без перегруженного оператора <<, чисто на функциях?
С этим аргументом я и сам согласен.
З.Ы. Для таких конструкций всё же интерполяция имхо лучше:
Здравствуйте, vsb, Вы писали:
vsb>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается,
В смысле а и b не строки? ну привет девочке, которая решила уйти в проститутки.
vsb>а это достаточно частый юз-кейс. А если бы для конкатенации строк использовался отдельный оператор, например как в Lua, было бы проще: print("a + b = " .. a + b).
Нет. Просто неявного преобразования в строки быть не должно.
Но если ты про мусорную динамику, то в ней никакой перегрузки операторов (темы топика) быть не должно.
Re[2]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>В общем случае — не люблю.
В общем случае прикольная возможность и если использовать к месту — просто хорошая.
vsb>Есть ситуации, где перегрузка уместна. Самый очевидный пример: вместо BigDecimal.add() писать +. Т.е. для объектов, которые представляют из себя числа.
+1 vsb>Какое отношение битовый сдвиг имеет к вводу-выводу — я никогда не понимал и не пойму.
А с этим на 146% согласен. Ненавижу.
Re[5]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, pagid_, Вы писали:
vsb>>а это достаточно частый юз-кейс. А если бы для конкатенации строк использовался отдельный оператор, например как в Lua, было бы проще: print("a + b = " .. a + b). _>Нет. Просто неявного преобразования в строки быть не должно. _>Но если ты про мусорную динамику, то в ней никакой перегрузки операторов (темы топика) быть не должно.
Во многих языках плюс перегружен для сложения строк. В Java той же. Динамика тут не причём. На мой взгляд это неправильно. Сложение это сложение, а конкатенация это конкатенация. В Lua, SQL для конкатенации строк сделали отдельный оператор и это мне нравится больше.
Здравствуйте, vsb, Вы писали:
Pzz>>Конкатенация строк.
vsb>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается
А что ожидается? Что сложение без скобок будет происходить справа налево? Поднимите руку, у кого ещё такие ожидания.
Но неявные типопреобразования это, конечно, зло. Этот код должен кидать исключение независимо от того, что там — ES object или Variant. К огромному сожалению, стандартные реализации того и другого этого не делают.
К конкатенациям именно строк через плюс я отношусь нейтрально. Если вырвать ядовитые клыки нестрогой типизации (неявных типопреобразований), такая конкатенация не сможет причинить много вреда. А от её запрета польза тоже неочевидна: дурак всегда сможет вызвать .concatenate() вместо .format().
>Ещё лучше использовать интерполяцию строк: print("a + b = \(a + b)")
Вот интерполяция — это точно то, чем пользоваться в больших проектах ни в коем случае нельзя. Почему? Потому что возникает лишняя связь между текстом и кодом, и текст становится нельзя вынести в ресурсы и отдать пруфридеру/копирайтеру/юзабилисту. К сожалению, всякие %s или {0} или {sum} тоже создают нехорошие связи, но если подставлять выражение, связь возникнет с каждой входящей в него переменной, а это гораздо хуже. Отрефакторишь, поменяешь a на o, и приплыли.
Здравствуйте, mike_rs, Вы писали:
_>а вот тут уже на первый план выходит компактность записи и удобство использования. _>std::cout << "some data: " << a << "eeg: " << b << functionCallI() << " done";
_>запиши без перегруженного оператора <<, чисто на функциях?
А потом приходит менеджер по продажам и говорит: у нас логи (в т.ч. debug output) должны быть локализованы, чтобы мы могли делать региональные скидки и держать в узде внедренцев. Знаешь, как тебе будет удобно потом бегать по всей кодебазе и заменять это на нормальное форматирование?
Re[4]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Pzz, Вы писали:
Pzz>операторы ||, && имеют гарантии порядка исполнения
Именно для этого они и введены (удвоены). Собственно, тут дело даже не столько в порядке, сколько в полноте.
А вот в ЯП, где эти операторы не делятся на одинарные и двойные (чаще всего со словами and и or), управлять полнотой/порядком приходится через какую-нибудь задницу, например, через директивы компилятору.
Re[5]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Alekzander, Вы писали:
Pzz>>операторы ||, && имеют гарантии порядка исполнения
A>Именно для этого они и введены (удвоены). Собственно, тут дело даже не столько в порядке, сколько в полноте.
А ж не про это говорю. А про то, что они теряют свою магию, если переопределены.
Re[6]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Pzz, Вы писали:
Pzz>>>операторы ||, && имеют гарантии порядка исполнения
A>>Именно для этого они и введены (удвоены). Собственно, тут дело даже не столько в порядке, сколько в полноте.
Pzz>А ж не про это говорю. А про то, что они теряют свою магию, если переопределены.
Я просто дополнил.
Re[5]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, Alekzander, Вы писали:
vsb>>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается
A>А что ожидается? Что сложение без скобок будет происходить справа налево?
Ожидается использование другого оператора для конкатенации строк, у которого приоритет низкий, что позволит писать "a + b = " .. a + b
Re[6]: Спец. символы (операторы) вместо функций - любите?
Здравствуйте, vsb, Вы писали:
vsb>>>На мой взгляд это плохое применение оператора сложения. Из-за него код print("a + b = " + a + b) не будет работать, как ожидается
A>>А что ожидается? Что сложение без скобок будет происходить справа налево?
vsb>Ожидается использование другого оператора для конкатенации строк, у которого приоритет низкий, что позволит писать "a + b = " .. a + b
Как по мне, отдельный оператор это лечение симптомов (потенциальные ошибки при конкатенации), а не болезни (нестрогая типизация ака неявные преобразования типов).
Если a и b строки, приоритет не будет иметь значения.
Если a и b не строки, независимо от того, что это за язык и какая там типизация (статическая или динамическая), print("a + b = " + a + b) должно не компилироваться или кидать исключение. Потому что это не только источник бесплатных ошибок программиста ("не будет работать, как ожидается"), но и способ затруднить локализацию, а ещё это дыра в безопасности (литералы в коде -> нельзя запретить Юникод в сорцах -> BiDi-инъекции).
P.S. Конечно, речь идёт про ЯП общего назначения. Есть ЯП для процессинга текста, там конкатенация — гражданин первого класса среди операций, и под неё выделена аж точка, если правильно помню.
Здравствуйте, Alekzander, Вы писали:
A>Как по мне, отдельный оператор это лечение симптомов (потенциальные ошибки при конкатенации), а не болезни (нестрогая типизация ака неявные преобразования типов).
И в каком языке нет неявных преобразований типов? Я таких языков не знаю ни одного. И практически во всех ЯВУ есть неявное преобразование числа в строку при подобных операциях, кроме совсем уж низкоуровневых.
У меня чёткого мнения по этому поводу нет и я даже скорей согласен с этим, но как-то на практике все остальные не согласны.
Здравствуйте, vsb, Вы писали:
A>>Как по мне, отдельный оператор это лечение симптомов (потенциальные ошибки при конкатенации), а не болезни (нестрогая типизация ака неявные преобразования типов).
vsb>И в каком языке нет неявных преобразований типов? Я таких языков не знаю ни одного. И практически во всех ЯВУ есть неявное преобразование числа в строку при подобных операциях, кроме совсем уж низкоуровневых.
Из языков с динамической типизацией мне нравится TIS.
var charcodeA = 'A'; // integer equal to UNICODE
// codepoint of 'A'
var letterA = "A";
var charA = String.fromCharCode(65);
// letterA and charA are strings
// but unicodeA is an integer:
letterA == charA // == true
charcodeA == charA // == false, different types
// Similarly...
var number5 = 5;
var char5 = "5"; // note, string
// This comparison does not trigger
// type conversion:
number1 == char1; // == false
По-моему, это гораздо лучше, чем тройное равно.
А вот пример из реального проекта, где собирается длинная строка:
for (var result in results)
{
var resText = result.htmlEscape();
html += String.printf("<div.item role='menu-item' command='%s' text='%s'><div.icon.search></div><div.title>%s</div></div>",
"MYAPP-search:" + resText, resText, resText);
}
String.printf
( format, [value1[, value2[, ...[, valueN]]]]) : string
Static method. Returns string formatted by the rules of sprintf C/C++ function.
Additional format types:
%v and %V — these format types accept any value as an argument and produce source code representation of the value suitable for later parsing by eval() method. Thus if value is an array of values it will be printed as "[element1, element2, element3... elementN]" and object (instance of Object class) will be printed as "{key1:value1, key2:value2,..., keyN:valueN}". %v produces one line output and %V tries to produce human readable output with line feeds and tabulations.
Use it if you need to serialize objects in AJAX/JSON fashion.
%S — this format type converts its argument into string and outputs it with HTML escapement. So characters like '<' will be converted to "<" sequences in the output.
Я на нём давно не писал, и слегка подзабыл, насколько глубока его строгость. Вроде бы, при попытке сложить строку с числом он кидал исключение, но я сейчас скачал интерпретатор, чтобы проверить, и он этого не делает. Надо будет разобраться, или я запомнил неправильно, или язык поменялся. Но в любом случае, наличие String.printf и обязательный учёт типа при сравнении — это уже большие шаги вперёд по сравнению с ES.
Из языков со статической типизацией я, наоборот, не знаю ни одного такого, чтобы в нём были неявные типопреобразования. Чтобы код, например, на C++ просто скомпилировался, надо вводить строковый класс с явно прописанными операторами сравнения и сложения.
vsb>У меня чёткого мнения по этому поводу нет и я даже скорей согласен с этим, но как-то на практике все остальные не согласны.
Разве не очевидно, что это легаси?
Изначально, когда, например, JS ещё был языком сценариев для хоумпаг, считалось, что ценно свойство не падать, а как-то хромать, даже если у нас по факту несовпадение типов. И пусть результат всех удивит, зато программа НЕ УПАЛА!
При профессиональном применении ценно, когда программа падает как можно раньше, а скрытая ошибка не доходит до прода.
TypeScript это мошенничество, у него нет контроля над рантаймом. Он лечит какие-то очевидные случаи, и такой ценой, которую платить не хочется — введением транспиляции в интерпретируемый язык. Да и динамическая типизация это очень удобно в своих областях (типа UI). Но сам факт появления TypeScript говорит о том, что недостаток строгости ощущается как потребность. Нельзя говорить, что "все остальные не согласны".
И, кроме того, чтобы они были согласны, надо их убеждать. Выше (и в этом комментарии, и выше по ветке) я это как раз и делаю.
Здравствуйте, mike_rs, Вы писали:
_>а вот тут уже на первый план выходит компактность записи и удобство использования. _>std::cout << "some data: " << a << "eeg: " << b << functionCallI() << " done"; _>запиши без перегруженного оператора <<, чисто на функциях?
std::cout.write("some data: ", a, "eeg: ", b, functionCallI(), " done");
Компактность сравнима, удобство чтения и записи, по-моему, даже чуть выше.
Исторически примеров полно — write/writeln в Паскале, write в Фортране (бесформатный вариант), print в Бейсике... или современный print в Python.
C++ поддерживает шаблонизацию функций многих аргументов, пройдёт без проблем.
Единственное существенное что отличает те исторические примеры — вставляются ли пробелы между аргументами кодом этой print(). Во всех перечисленных, AFAIR, это надо было явно отменять, если хотелось самому этим рулить.