LINUX.ORG.RU

перегрузка операций против пользовательских инфиксных операций

 


2

3

В С++ можно перегружать операции. Нагрузить + смыслом выше крыши. Это, с одной стороны, хорошо - можно писать компактный код. С другой стороны, увеличивается степень неявности и вероятность получить 1+2=12.

Есть другой вариант - определённые пользователем операции. Выглядит это примерно так (позволю попробовать свой язык - ведь нужно ж наработывать стиль; думаю, все поймут)

фун СложитьСтрокиФункция(С - строка;остальные_аргументы(Хв) - однородный_список(строка));
  прменя Рез - строка = С, измнямя;
  цикл посписку(Сл,Хв)
    Рез = Рез -- Сл;
  кнецикл
кнецфун
  
инфиксная_операция(:имя СложитьСтроки,
                   :рлзаця СложитьСтрокиФункция,
                   :пртет "+");

печать("аффтор" СложитьСтроки " " СложитьСтроки "жжот");

Здесь «+» значит - «сделать приоритет как у операции плюс». Что не так с этим подходом и почему он не прижился?

★★★★★

cons = (:)
main = do let l = 1 `cons` (2 `cons` [])
          print l

А насчёт определения собственных операторов посмотри на Haskell.

Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 2)

фун, прменя, измнямя, кнецикл, кнецфун, :рлзаця, :пртет

Да и с веществами завязывай, читать такое невозможно.

Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 1)

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

Далее, операторы необходимо запоминать, так что их лучше вводить как можно меньше, только для самых центральных понятий DSL. Если применять их где попало, то язык рискует превратиться во write-only кашу. Разработчики решают просто не вводить эту возможность, чтобы избежать проблемы в зародыше; плюс, многие популярные языки обходятся без пользовательских операторов, что подкрепляет убеждения в том, что можно обойтись без них.

Далее, если операторы-слова слишком многословны для частоиспользуемых операций, так что нужны символы. ASCII небольшой, каракуль много не сделаешь, так что хочется Юникод. Правильная поддержка Юникода — это сложно и дорого. Плюс, каракули не гуглятся в отличие от слов.

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

Вон из популярных языков с пользовательскими операторами есть Swift и Scala. Смотри, как они там используются.

anonymous ()

прменя рлзаця кнецфун

ЛОР еще не видел такого упоротого пацака

anonymous ()

А по теме, не смог толком распарсить твой язык, но что-то подобное в SML.

anonymous ()
Ответ на: комментарий от Begemoth

Да и с веществами завязывай, читать такое невозможно.

Трать-тарарать. А это лучше что ли?

функция СложитьСтрокиФункция(С - строка;остальные_аргументы(Хв) - однородный_список(строка));
  переменная Рез - строка = С, изменяемая;
  цикл по_списку(Сл,Хв)
    Рез = Рез -- Сл;
  конец_цикл
конец_функция
  
инфиксная_операция(:имя СложитьСтроки,
                   :реализация СложитьСтрокиФункция,
                   :приоритет 123);

печать("аффтор" СложитьСтроки " " СложитьСтроки "жжот");
den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 1)

Почему «vs»? См. Algol68.

ABW ★★★★ ()
Ответ на: комментарий от anonymous

прменя рлзаця кнецфун

ЛОР еще не видел такого упоротого пацака

Как ты прав.

tailgunner ★★★★★ ()
Ответ на: комментарий от den73

Вот как это пишется на CL:

(defun сложить-строки-функция (s &rest xb)
  (let ((res s))
    (dolist (sl xb)
      (_f str+ s sl))
    res))

(defun сложить-строки (&rest args) (сложить-строки-функция))

(print (сложить-строки "аффтор" " " "жжот"))
И ещё я в л2 забыл оператор возврата, а тут он есть. Конечно, код л2 статически типизированный, но не катастрофична ли разница в размере кода? Инфиксные операторы в лиспе не нужны вовсе.

den73 ★★★★★ ()
Ответ на: комментарий от anonymous

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

На этот вопрос у меня есть ответ - будет интерфейс парсера, чтобы его можно было включать в утилиты и в IDE вместе со всеми расширениями.

Далее, операторы необходимо запоминать, так что их лучше вводить как можно меньше, только для самых центральных понятий DSL. Если применять их где попало, то язык рискует превратиться во write-only кашу.

Вот. Именно это меня и смущает.

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

Я вижу такой вариант использования. Написали а == б, потом поняли, что надо не ==, а equalp. Переписывание в виде equalp(а,б) сильно меняет вид кода и можно внести ошибку. Ошибка в сложном логическом выражении обычно стоит очень дорого. Вот и хочется сделать все эти equalp операторами сравнения. В лиспе их много (5, что ли) и всегда можно добавить новый.

Второй вариант использования - это арифметика. Есть сложение целых чисел ограниченных, неограниченных, плавающих одинарных, плавающих двойных, и BCD для бухгалтеров, сложение в линейной алгебре. Ошибка опять же дорого стоит. Повесить всё это на один и тот же плюс выглядит стрёмным. В ocaml вроде есть +. , но я уже перечислил 6 разных операций, а не два. Например, дурно пахнет, если умножение матриц и умножение матрицы на скаляр пишутся одинаково.

Делать всё это вызовами функций, как в лиспе - тоже радости мало.

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

Поправил пример. Теперь можно ставить новую операцию только в ряд с уже существующими. Новых приоритетов заводить нельзя. Где-нибудь такое пробовали уже? Что вышло?

den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 3)
Ответ на: комментарий от den73

swift, алгол 68, Хаскель - никто из них (пока) толком не взлетел. Более-менее взлетел только Пролог.

Ага, в свифте нашёл

infix operator ~> { associativity left precedence 150 }
den73 ★★★★★ ()
Ответ на: комментарий от den73

Кстати, планируемые приоритеты операций в моём языке:

* /
+ - --
< > <= >=
равно 
не
и
или
=

den73 ★★★★★ ()

Кстати, зачем ограничивать кириллицей круг людей, способных пользоваться языком? Чтобы меньше человек пострадало?

Deleted ()
Ответ на: комментарий от Deleted

Особой такой цели нет, но и тратить усилия на поддержание двух версий я не готов. Мало сделать ключевые слова, нужно же ещё всю рантайм-библиотеку, все сообщения об ошибках и всю документацию поддерживать двухязычной. Это совсем не мало дополнительной работы.

den73 ★★★★★ ()
Ответ на: комментарий от den73

Почему бы не сделать просто на английском?

Deleted ()

это какой-то ктулху фхтагн. лучше используй суахили, будет читабельнее.

Iron_Bug ★★★★ ()

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

anonymous ()
Ответ на: комментарий от anonymous

ЛОР еще не видел такого упоротого пацака

Он использует старый стандарт псевдокода, в котором только 6 значимых символов в идентификаторах.

proud_anon ★★★★★ ()
Ответ на: комментарий от den73

Лучше, если напрягает количество ключевых слов - см. на синтаксис Haskell.

Begemoth ★★★★★ ()

То-есть, в одном месте создал оператор, в другом месте (подключенной библиотеке от другого разработчика) уже не создашь/не перезагрузишь?

makoven ★★★★★ ()
Последнее исправление: makoven (всего исправлений: 1)

кнецфун

ну ладно

кнецикл

уже нарушение соглашения об именовании(если оно вообще есть), по идее должно быть кнеццикл

измнямя

ГОСПОДИ 228/10

прменя

пдлись вщесвми

f1u77y ★★★ ()
Последнее исправление: f1u77y (всего исправлений: 3)
Ответ на: комментарий от proud_anon

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

f1u77y ★★★ ()

прменя измнямя рлзаця пртет

С уму сйдешися, трбмя зъбану!

arturpub ★★ ()
Ответ на: комментарий от den73

В 100-500 раз. Увы, прямяня быстро разворачиваются только у тебя в голове.

По сабжу: грамматика становится сильно контекст-dependent, как для парсера, так и для человека.

arturpub ★★ ()

фун

совсем не фан. ай со сам щит.

anonymous ()
Ответ на: комментарий от anonymous

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

Это какую?

anonymous ()

измнямя

Забавно. Но лучше откажись от кириллицы. Не порть восприятие русского языка.

anonymous ()
Ответ на: комментарий от den73

напиши скрипт для транслита, и потом из транслита в англ по словарю

anonymous ()

слоговую азбуку, типа катаканы с хираганой — только промптом переведённую на русский.

чтобы зазвучало и слоги сохранялись.

anonymous ()
Ответ на: комментарий от makoven

То-есть, в одном месте создал оператор, в другом месте (подключенной библиотеке от другого разработчика) уже не создашь/не перезагрузишь?

В лиспе есть понятие «родовая функция», т.е. функция с множественной диспатчеризацией. Примерно то же, что в С++ - виртуальная, только по нескольким параметрам. В любом месте, где можно использовать обычную функцию, можно использовать и обобщённую. Если хочешь сделать оператор, к-рый можно перекрыть, его можно реализовать родовой функцией:

рдвая_функця СложитьЧтоТоФункция(С;остлные_аргменты(Хв));
И дальше только определяй для неё методы. Как-то так:
метд СложитьЧтоТоФункция(С - стрка;остлные_аргменты(Хв) - списк);
// первый аргумент - строка
кнецметд

Можно ещё сделать, чтобы символы «+» могли быть из разных пакетов. Тогда будет и перегрузка, и невозможность перепутать, и свобода в выборе имён.

Например:

пкет
  псевдонимы ц = врженя/цлчислне,п = врженя/плавще;
кнецпкет

И далее

2 ц:+ 2
2.5 п:+ 2.5

Но всё равно набора спец.букв недостаточно - хотя бы для стандартных операций эквивалентности в лиспе их нужно 4 штуки.

den73 ★★★★★ ()
Ответ на: комментарий от proud_anon

Принцп скрщеня слов опсан здесь: https://bitbucket.org/budden/l2/src/default/doc/клчвые-слва-вранты.md?filevie... И давайте его не будем обсуждать здесь, тема совсем не про то. Ну и вообще, тут пока идут постоянные эксперименты. Слово фун является исключением из общего правила, хотя его следует убрать.

den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Лучше, если напрягает количество ключевых слов - см. на синтаксис Haskell.

Не понял, к чему это. Если это к системе сокращений, то проблема не в количестве слов, а в том, что Русские слова длиннее Английских.

Если к приоритетам операций, то можешь привести пример и аргументировать его? Из описания языка не всегда очевидно, что является преимуществом, а я на Хаскеле никогда не писал.

den73 ★★★★★ ()

Мужик, твой язык настолько совершенен, что уже пофигу, перегрузка или пользовательские операторы. Что ты нас, убогих-то, пытаешь?

anonymous ()
Ответ на: комментарий от arturpub

Увы, прямяня быстро разворачиваются только у тебя в голове.

Любой ЯП нужно сначала учить, а потом уже будет быстрота. Зато потом язык с короткими словами будет читаться и писаться быстрее.

den73 ★★★★★ ()
Ответ на: комментарий от den73

— «Вопрос: что у нея… гм… у нея внутре за лпч?» Лэпэчэ… Кэпэдэ, наверное? Что еще за лэпэчэ?
— Лампочка, значит, — сказал старичок, хихикая и потирая руки. — Кодируем помаленьку.

anonymous ()
Ответ на: комментарий от den73

Любой ЯП нужно сначала учить, а потом уже будет быстрота. Зато потом язык с короткими словами будет читаться и писаться быстрее.

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

Извини, не удержался.

anonymous ()
Ответ на: комментарий от anonymous

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

А птом будм псать прграмы так же быстро, как пасы ...

В шкосолесе мысы госовосорисилиси наса восот тасакосом ясазысыкесе, носо эсэтосо прасактисичесескиси бесеспосолесезносо. А вот скрщеня прдумне мною, дстатчно плезны. Я сегодня написал человеку СМСку на этом языке - мне понравилось. Правда, забыл спросить, понял ли он меня.

den73 ★★★★★ ()
Ответ на: комментарий от anonymous

Станислав Лем — Экстелопедия. Про метаязыки забавно и очень похоже на то что ден втирает.

deep-purple ★★★★★ ()
Ответ на: комментарий от den73

упячка какая-то

и щачло попяченное

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

                        Редьярд Киплинг (1865-1936),
                        "Как было написано первое письмо."
                        (пер. К. Чуковского).
ABW ★★★★ ()
Ответ на: комментарий от den73

Этот вариант, видимо, и придётся принять, и пойти на такой риск.

пкет
  псвднимы ц = врженя/цлчислне,п = врженя/плавще;
кн

И далее

пчать(2 ц:+ 2); // целочисленное сложение
пчать(2.5 п:+ 2.5); //плавающее

Просто потому, что я не понимаю, в чём проблема. В конце концов, плюсы с перегрузкой операторов существуют, а этот вариант уж не хуже.

den73 ★★★★★ ()
Ответ на: комментарий от den73

Перед сном прочитал две страницы из «Основных концепций языков программирования», 5-е издание, и понял, что лисп - это всё же мерседес среди языков программирования. Операции можно перекрывать, можно при этом сохранять проверку типов, а можно полиморфизм навести. Именно за счёт пространств имён. Расплатой за это является необходимость всегда писать скобки.

den73 ★★★★★ ()
Ответ на: комментарий от den73

А ты просто выбери за дефолтный язык - английский, а не русский. Как сделано во всех нормальных языках программирования, кроме очень узкоспециализированных (1С) или учебных (Кумир). В любом случае для полноценного занятия этой деятельностью (программирование) нужно знать международный язык, ибо на нём материалов гораздо больше, чем на родном.

KivApple ★★★★★ ()
Ответ на: комментарий от KivApple

1. Если тебе хочется - разработай свой язык, в котором по дефолту английский.

2. Тема про перегрузку операций.

den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

остлные_аргменты

переименовать как «ещё». и вообще, подобрать синонимы покороче, пооднозначней, попонятнее.

псевдонимы и пакеты с переименованием — имхо, ОК подход. ну, то есть: не нравится кому-нибудь семантическая упячка и фейлы в денотате — он импортирует пакет/пишет макросы для переименования при импорте стдрнх смвлв опрцй езыговыхъ мдлй и обзывает их как ему угодно.

пусть хоть в партию ПДРС вступают, его дело — в его личном модуле. глвне, в стд пктх бдт прдкъ.

английские синонимы проще в том, что там с падежами и склонениями проблем нет. проще парсер получается. русский парсер с правильной морфологией по идее должен падежи и склонения/спряжения учитывать: хотя бы обрезать суффиксы и окончания, и искать задом наперёд оставшиеся приставки+корни, или просто корни, в словаре корней (задом наперёд, инкрементально)

спряжения и склонения вообще толком нигде не поддерживаются, хотя вру: был такой язык Nadesico, японский типа Gellish English — пиджин специально для упрощённого NLP, text mining-a (ср. например BDD подход и спеки на ествественном языке в Cucumber, например).

там можно было писать типа foo of bar = bar.foo = (slot-value 'foo bar) и т.п.

причем эти типа склонения 'of' были разные, их было много, и они были однозначно понятны из контекста (операции разных объектов, разных DSL).

в японском это проще, когда отдельными словами. в лиспе получается отдельными выражениями.

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

вот всё равно какой-то язык должен получиться, чтобы было понятно, что `остлные_аргменты` или там `остлные_аргменты` употребимо только в списке формальных параметров при определении, а не где-то ещё.

язык абстрактного синтаксиса, где проверка семантики (типа семантических или если простые, синтаксических предикатов, типа как в ANTLR) — это проверка на WFF, корректно сформулированные выражения на этом языке.

правда, чего там придираться к конкретному синтаксису «вступайте в партию ПДРС!» если он может быть любой. вопрос в абстрактном и семантике.

anonymous ()
Ответ на: комментарий от anonymous

многозначность, полисемия

foo of bar

кстати, из естественного языка это можно перевести как foo o'bar или «foo, bar-ов сын» (ср. до отчеств: Иван сын Петров), а можно и как «foo из рода bar», то есть: в первом случае объекты, экземпляры, переменные и динамические типы — а во втором, типы классов, родовые функции и т.п., которые в идеале с ограничениями могут разрешиться в статический тип (типа как в C++ non-virtual метод вычисляется в конкретный метод, или вирутальный — через VTable, относительно простой lookup-table с дважды косвенностью, а сама таблица считается CTFE). ну или как в vala например public static void main разрешается не в метод, а в функцию, например: stdout.printf(«asd:%s»,s); => UFCS переписывается в printf(stdout,«asd:%s»,s), где stdout — статический объект, синглтон (может даже, вычисленный CTFE тип, enum например).

из естественного языка тут однозначно понятно эту разрешимость по контексту, по словоупотреблению. в неестественном прогязыке — надо контекст задавать вручную, либо позаботиться везде слова разные ставить (что хорошо в случае простой однозначной грамматики типа LL(1), но плохо в смысле композиции языковых модулей).

например, в META II эта композиция может быть любая, а в OMeta и т.п. в сторону nanopass framework — это фактически объекты, языковые модули, метаязык языковых модулей, написаный на себе самом.

а вообще да, отчего-то кажется что ты изобретаешь CGOL (алгольный синтаксис с трансляцией в лисп из 90х). может, проще просто к нему русские синонимы прикрутить?

или чего-то не хватает в CGOL ?

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.