LINUX.ORG.RU

итак, боремся с грустными смайликами

 , ,


2

5

В С любой оператор должен заканчиваться точкой с запятой. Это порождает грустные смайлики ");" и «};» и я попытаюсь от них избавиться. Я изначально сомневался, нужны ли точки с запятой, и вот теперь появился против них ещё серьёзный аргумент.

Практически я имел дело с двумя языками, где нет точек с запятой - это tcl/tk и язык определения макросов в C. Перенос на новую строку осуществляется с помощью «\». Это выглядит и ощущается как голимая кустарщина. И это неудобно.

Длинные строки, требующие переноса, возникают тогда, когда у функции много аргументов. Других вариантов я не могу придумать.

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

Удачно ли golang обходится без точек с запятой? Удобно ли это, понятно ли? Стоит ли так делать в новом языке?

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

Я пока придумал только одну вещь на замену «\». Сделать правило, что если в строке есть несбалансированная открывающая круглая скобка, то следующая строка является продолжением предыдущей, и так до тех пор, пока скобка не будет сбалансирована. Так, по сути, сделано в лиспе.

★★★★★

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

Ответ на: комментарий от MKuznetsov

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

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

SQL. В принципе, неплохой язык. Как он работает? Пункты разделяются ключевыми словами, точнее, начинаются с ключевых слов select from, inner join, having. Но это не ЯП общего назначения.

Как и препроцессор Си

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

Ну, можно не так экстремально (set <var> = <expr>), а просто строго разделять присваивание и сравнение, т.е., например, как в Си (= и == чтобы не сильно отпугивать), но выражение <var> = <expr> не должно возвращать ничего, т.е. не быть expr. Возможно, тогда можно будет парсить как SQL без точек-с-запятой.

korvin_ ★★★★★
()

Есть ещё Lua, где нет точек с запятой, но перенос строк не важен. Для этого надо соответствующую грамматику иметь.

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

Ты так не считаешь?

Мне не нравится голанг, но не из-за синтаксиса.

PolarFox ★★★★★
()

Golang'овский перенос как конец оператора - удобно.

Deleted
()

Длинные строки, требующие переноса, возникают тогда, когда у функции много аргументов. Других вариантов я не могу придумать.

Ещё бывает long_name1(longName2(longName2(...(longNameN(x))))...);

Сделать правило, что если в строке есть несбалансированная открывающая круглая скобка, то следующая строка является продолжением предыдущей, и так до тех пор, пока скобка не будет сбалансирована. Так, по сути, сделано в лиспе.

Делай как в Tcl: несбалансированная любая скобка или кавычка.

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

Возможно, тогда можно будет парсить как SQL без точек-с-запятой.

Слабо верю в реальность такого счастья. lvalue/place может быть довольно кудрявым.

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

Есть ещё Lua, где нет точек с запятой, но перенос строк не важен.

Как это нет? http://www.lua.ru/doc/8.html

Конечно, тут уже и sql привели для примера, но я вспомнил, что в языке хранимых процедур MS SQL вызов процедуры тоже требует ключевого слова:

exec процедура параметр1, ..., параметрN
Без этого ключевого слова сразу теряется однозначность. Например,
процедура1
процедура2
Что это? Это может быть
процедура1();
процедура2();
А может быть
процедура1(процедура2);
Но ключевое слово для вызова процедуры - это кустарщина ещё хуже собак в переменных.

den73 ★★★★★
() автор топика

2 den73: сколько разработчиков участвует в создании твоего языка? Тебе не кажется что развивать язык нужно учитывая просьбы пользователей языка? Кто знает, может те кто будут его пробовать и писать средние программы найдут его непригодным и молча перейдут на другой язык.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от monk

несбалансированная любая скобка или кавычка.

Что мне не нравилось в tcl? А вот что:

$btext configure -wrap [dict get $opts -wrap] \
    -xscrollcommand [list $w.sx set] \
    -yscrollcommand [list $w.sy set] \
    -foreground $COLOR(stdin) \
    -background $COLOR(bg) \
    -insertbackground grey \
    -font $::tkcon::OPT(font) -borderwidth 1 -highlightthickness 0 \
    -blockcursor 1  \
    -undo 1
Тут мы и подходим к содержательной части темы.

den73 ★★★★★
() автор топика

Перенос на новую строку осуществляется с помощью

а зачем вообще нужен ручной перенос на новую строку, если есть word-wrap?

anonymous
()
Ответ на: комментарий от den73
eval [join {
$btext configure -wrap [dict get $opts -wrap]
    -xscrollcommand [list $w.sx set]
    -yscrollcommand [list $w.sy set]
    -foreground $COLOR(stdin)
    -background $COLOR(bg)
    -insertbackground grey
    -font $::tkcon::OPT(font) -borderwidth 1 -highlightthickness 0
    -blockcursor 1
    -undo 1}]
monk ★★★★★
()
Ответ на: комментарий от proud_anon

а чё там иметь? в том же С/С++ типичная строка выглядит как один из из следующих вариантов:

а) объявление

б) присваивание (=, +=, етк)

в) вызов ф-ции.

г) управляющие конструкции типа if,while

но объявление можно сделать так: аuto x(1), y(" "), z(MyClass(1, 1.0, ""). т.е. с использованием вывода типа можно в случае объявления полагаться на ключевое слово.

с присваиванием тоже ясно: если парсер находит нечто вида x = 2 + y, то, очевидно, переменная слева от знака присваивания является началом новой строки

про ф-ции выше написали.

с управляющими конструкциями аналогично как с ф-циями

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

* z(MyClass(1, 1.0, ""))

кстати можно и так:

z = MyClass(1, 1.0, "")

а можно x = int(), если непосредственную инициализацию хочется отложить.

для указателей можно что-то вроде: f = int*(nullptr)

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

Например, как я в коде отличу переменную от метода без параметров? например, в С вызов метода без параметров записывается так: greet() но не так: greet

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

Вывод типов предаёт дополнительную степень неявности.

вывод типов — отличная штука. потому, что писать всё время MyClass x = new MyClass() — идиотизм.

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

но дело не только в этом.

допустим у нас есть


class SuperMegaPuperClassNameWith100500SymbolsInName
{

};

и есть SuperMegaPuperClassNameWith100500SymbolsInName func();

auto x = func();

во-первых, замучаешься вводить SuperMegaPuperClassNameWith100500SymbolsInName вместо auto, во-вторых, если программист захочет поменять имя класса SuperMegaPuperClassNameWith100500SymbolsInName на SuperGigaPuperClassNameWith100500SymbolsInName, всё привет, привет ручная работа, ну или авторефракторинг с помощью внешних утилит, корректность результатов исполнения которых всё-равно, вероятно, придётся проверять вручную.

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

Выглядит опасным с точки зрения возникновения всяких неоднозначностей.

например?

Программист может в результате опечатки что-то пропустить или написать лишнее.

например?

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

в итоге получится «Не-Хмурый С» без смайликов, но мало кому понятный :-)

Это ты — тот анонимус со смайликами в соседних тредах?

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

Подобное я считаю большой ошибкой и никогда в свой язык такое не включу.

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

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

DarkEld3r ★★★★★
()

Практически я имел дело с двумя языками, где нет точек с запятой...

В OpenEuphoria тоже нет.

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

Вот это — работающий (хотя и плохо читаемый) код

Да, и легко написать осмысленный код, имеющий не тот смысл, который ты подразумеваешь. Вот цитата из какого-то введения:

ОЧЕНЬ ЧАСТО ОШИБКИ ВОЗНИКАЮТ ИЗ-ЗА ТОГО, ЧТО ПРОГРАММИСТ ЗАБЫЛ НАПИСАТЬ КЛЮЧЕВОЕ СЛОВО LOCAL ПЕРЕД ПЕРВЫМ ПРИСВАИВАНИЕМ ЛОКАЛЬНОЙ ПЕРЕМЕННОЙ И ЗАТЕР ТАКИМ ОБРАЗОМ ГЛОБАЛЬНУЮ. СЛЕДИ ЗА ОБЛАСТЬЮ ВИДИМОСТИ ТВОИХ ПЕРЕМЕННЫХ

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

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

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

Вот это уже осмысленное применение.

В смысле, в чём проблему видишь?

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

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

В лиспе это делается без синтаксического мусора. Значит, синтаксический мусор здесь не нужен.

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

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

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

Большой перерыв. Сегодня точно не вернусь.

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

ОЧЕНЬ ЧАСТО ОШИБКИ ВОЗНИКАЮТ ИЗ-ЗА ТОГО, ЧТО ПРОГРАММИСТ ЗАБЫЛ НАПИСАТЬ КЛЮЧЕВОЕ СЛОВО LOCAL

Это известная проблема, да. Лучше было бы сделать как в Питоне.

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

Ты по одному этому факту так рассудил? Ты уверен, что твой Яр продуман значительно лучше?

Потом, ты просил язык без точек с запятой. Я тебе показал. Ты почему-то стал говорить, что без точек с запятыми жить плохо.

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

Но из Явы уже ничего не растёт. ;)

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

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

Scala не взлетела

Куча язычков мечтают о таком «не взлетела».

Не сочти за переход на личности, но какой популярности своего языка ожидаешь? И если окажешься единственным его пользователем, то значит ли это, что всё в языке плохо?

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

В лиспе это делается без синтаксического мусора.

Да, без «синтаксического мусора» в виде запятых, но ты их почему-то захотел. И теперь наворачиваешь один мусор поверх другого, чтобы подпереть костылями возникшие проблемы.

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

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

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

в С/С++, в выражениии *x «*» — спецсимвол, явным образом относящийся к «x»

а выражения вида «функ1(X) присваивание функ2(Ч)» не нужны

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

Что мне не нравилось в tcl?

в том что вам ненравится переносы строк \ легко убираются

$btext configure -wrap [dict get $opts -wrap] {*}{
    -xscrollcommand [list $w.sx set] 
    -yscrollcommand [list $w.sy set] 
    -foreground $COLOR(stdin) 
    -background $COLOR(bg) 
    -insertbackground grey 
    -font $::tkcon::OPT(font) -borderwidth 1 -highlightthickness 0 
    -blockcursor 1  
    -undo 1
}

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

По поводу go — это просто продолжение линейки: PL/I — B — C — Alef — Limbo — Go.

Нет. Вернее, таких «линеек» можно много расписать с одним корнем. Go не является продолжением C.

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

C (Thompson, Ritchie)

Ритчи был основным разработчиком Си. В последующих языках он участие не принимал.

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

Вот нашёл страничку:

https://wiki.theory.org/YourLanguageSucks

Хотя довольно дурацкая, но лучше чем ничего.

Она не просто дурацкая, она некорректная. Отстой полный.

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

Это ты — тот анонимус со смайликами в соседних тредах?

это не я. Не являюсь анонимусом довольно много лет

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

Сбацал на коленке маленькую програмку, котора бегает по википедии и смотрит в infobox какой язык на какой повлиял или возник под влиянием другого языка. (Influenced/Influenced by)

Получилось довольно таки интересно: https://www.dim13.org/images/langtree.svg

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

Лучше бы ты напечатал матрицу смежности.

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

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

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

Ты по одному этому факту так рассудил? Ты уверен, что твой Яр продуман значительно лучше?

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

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

В случае lua проблема с локалами не основная. Я уже раньше решил, что либо будут точки с запятой, либо значащие переносы строки. Иначе малореально избежать неоднозначностей.

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

в С/С++, в выражениии *x «*» — спецсимвол, явным образом относящийся к «x»

a * x = b;

Что такое в этом выражении звёздочка? Имя типа, указателем на который мы объявляем x? или левый аргумент оператора *, результат которого имеет переопредёленную операцию = ?

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

Нет,, пример не приведу (это ж думать надо), но в целом некрасиво как-то выглядит, .

Да, без «синтаксического мусора» в виде запятых, но ты их почему-то захотел

Да не то, что я их захотел. Просто это нужно полностью вынести себе мозг, чтобы ещё и запятые выкинуть. Я без запятых в лиспе себя прекрасно чувствую, да и в tcl ничего. Зато в лиспе скобки достали. А если скобки выкинуть, то нужно что-то вместо них. Например, запятые.

tcl был бы идеалом, если сделать:

- жадное выполнение как в лиспе - выкинуть эзотерические строки и сделать вместо них нормальные макросы - сделать синтаксис доступа к полям «объект.поле» - решить вопрос с переносом строк (впрочем, пример уже показали)

Но пугает меня в tcl ещё и expr. В общем-то сама по себе идея очень здравая. Арифметика нужна редко, а её парсер изрядно добавляет сложности и неразберихи. Но это нужно преодолеть определённый барьер вхождения. Некоторые начинают знакомство с язком с hello,world, а некоторые с 2+2. В лиспе это полный пипец, а в tcl тоже не сахар. То, что expr кое-где (в циклах и if-ах) неявно вставляется, только увеличивает недоумение.

Хотя вот тебе пример по мотивам предыдущего:

print_va_args(a,*b);
print_va_args(,a*b); // в языке, где можно пропускать аргументы
Это пример скорее про то, как плохо перекрывать звёздочку с разной арностью и полиморфизмом. Вот тебе ещё пример из SQL:
select f1,f2,f3 f4,f5,f6 from mytable;
С таким запросом можно влететь на конкретные бабки.

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

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

а зачем вообще нужен ручной перенос на новую строку, если есть word-wrap?

Я тоже над этим уже давно думаю. Не могу ответить, честно говоря. Кроме того, что будет выглядеть некрасиво, если перенесётся как попало. И, скажем, вид кода поменяется при изменении размеров окна.

Т.е., нужен со стороны IDE какой-то адаптированный, интеллектуальный word wrap, который будет переносить согласно стилю.

Или давать подсказку ему. Скажем, два пробела - это сразу автоматический перевод на новую строку.

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

den73 ★★★★★
() автор топика

Вот жуткий пример из питона:

value = foo.bar()['first'][0]*baz.ham(1, 2)[5:9] \
  + verify(34, 20)*skip(500, 360)
Если стереть обратный слеш, код останется рабочим. А всё из-за унарного плюса (я унарный минус уже запретил, надо и плюс не забыть запретить). Правда, и я смогу влететь, если будет
value = foo.bar()['first'][0]*baz.ham(1, 2)[5:9] \
  -5+function_for_size_effect()
Потому что для запрета константы -5 мне духа не хватило. Что ж тут сделать? Запретить ставить после переноса строки + и -, наверное. КОму надо - пусть пишут
value = foo.bar()['first'][0]*baz.ham(1, 2)[5:9] - \
  5+function_for_size_effect()
Вписал в доку.

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

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

den73 ★★★★★
() автор топика

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

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