LINUX.ORG.RU

Убийца ли C язык C3?

 , ,


3

8

В честь сегодняшнего пре-релиза (0.2.4).

C3 (GitHub) - очередной «убийца» C на базе LLVM. Потихоньку разрабатывается шведским программистом (одна штука).

Ключевые особенности:

  • компилятор написан на C
  • поддержка LLVM 12-15 (насколько мне известно, ни один из конкурентов этого не может (привет, Odin, Zig и т.д и т.п.))
  • полная C-ABI совместимость
  • модули - нет хидерам!
  • дженерики
  • макросы, но не как в C
  • слайсы
  • контракты
  • compile time and runtime reflection (плохопереводимая игра слов)
  • SIMD «из коробки»
  • и многое другое!

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

macro int factorial($n)
{
        $if ($n == 0):
                return 1;
        $else:
                return $n * factorial($n - 1);
        $endif;
}

extern fn void printf(char *fmt, ...);

fn void main()
{
        int x = factorial(12);
        printf("12! = %d\n", x);
}
★★★★★

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

Никто не будет читать эту ветку, но всё прецедент интересный. Я сведу его до сути. Это очень смешно.

Покажу вам как писать жсон-парсер(string => ast) в одну строчку.

struct manya_value { string str; }

ast json(string str) {
 return manya_value{str};
}

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

Ну а как мне там узнать что будет объект/массив/строка? В моём маня-языке это семантика. Вот далее и потом я будут обходить аст(ну как если бы я бацал лабу с кодогенерацией в llvm. Ну вы знаете llvm - это не хухры-мухры. Мне можно верить) и там добавлю все эти строки/массивы.

Важно что? Что парсер то в одну строку. Я шиз? Нет - просто показывайте код.

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

Теперь вижу, что понимание у тебя немножко появилось. Это хорошо. Наконец-то и про ast почитал, и про семантику. Там глядишь, и до символов дойдёшь.

Засим дискутировать с тобой прекращаю, клоунада твоя надоела.

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

Молодец. Что-то текущее окружение разбаловало вас. Ты осознал своё положение, но продолжаешь врать и делать вид. В целом типичное пойманного за руку. Уже поймали, всё доказано, но «это не я».

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

Он просто когда пастил не осилил, судя по всему там было что-то типа while(*str[n++]), что тоже какая-то очередная копипаста с while(*p++).

У меня к тебе вопрос как пятизвёздочнику. Почему подобные персонажи до сих не забанены? Он бегает везде/спамит/фармит скор и разводит тупняк.

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

У меня к тебе вопрос как пятизвёздочнику. Почему подобные персонажи до сих не забанены?

Потому что меня не взяли в модераторы...

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

А то, что там обращение к массиву бесполезное Вас не смутило?

Это пример отвечающий одной только цели – показать читаемость кода. Какая-то его корректность как программного кода не нужна.

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

В примере это выглядит так:

  1. Взять элемент массива под номером some.
  2. Уменьшить some на один.

В то время как сложная запись будет чем-то вроде:

  1. Декрементировав some, взять элемент массива под его номером.

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

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

Вот-вот, несколько десятилетий эту мантру слышим.

Видимо опять нужен переводчик с царского на обычный :)

Имеется в виду, что модули в C++ не аналогичны модулям в других языках, и гораздо ближе к предкомпилированным заголовочным файлам и инклюдам по своей сути. В первом приближении их можно описать как дампы AST + непротекающий скоуп.

Классические же модули в С++ не только не нужны, но и невозможны из-за шаблонов.

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

ключевое слово для функции/метода сразу даёт понять, что это функция, не заставляя человекапарсер искать по косвенным признакам

Пофиксил. Человек читает строчку целиком, он и так видит, что это метод.

ya-betmen ★★★★★
()
Ответ на: комментарий от thegoldone

Это пример отвечающий одной только цели – показать читаемость кода

А то, что все всегда в for пишут ++i - это как, норм? Нахер вообще этот фор, надо отдельно херачить, на каждой строчке. while (*p++) вполне читаем и понятен, например.

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

Примеры адекватны цели.

Да, пример убогий и некорректный – и цель такая же.

О чём и речь, лично Ваше удобство здесь не на первой позиции.

Я знаю, мне на ваше тоже как-то наплевать.

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

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

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

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

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

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

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

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

Да всё что угодно. ll1 - это академическая классификация. Как-то обсуждать её нет смысла. Академическая теория не осилил даже родить парсер для паскаля.

Как следствие - зачем реальным языкам этот мусор? Вот его никто и не использует(ну кроме академических языков/лаб. Но все они выглядят как позорище. По той самой причине).

Пример любой язык - любой компилятор. Тот же компилятор С++.

естественные языки и языки формальные служат разным целям.

Это сказки и оправдания. Просто неосиляторы/академическая пропаганда начала впаривать эту дихотомию. Она несостоятельна.

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

Не, просто они сложные. А академическая теория не может даже в паскаль. Как следствие придумываются все опрадвания.

ЯП формальные только по одной причине - это просто. На самом деле они нихрена не формальные. Даже какой-то академический скам не является формальным.

Вот в сишке все бегают с уб - это тоже нечёткие высказывания.

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

Нет. Чёткие определения - просто примитивный мусор. Но в другое практика/теория не может. Поэтому используют их.

Опять же, никакой чёткости там нет. Это так же миф - пример я выше привёл.

что касается контекстной свободы, то чем ее больше, тем проще всем. от компилятора, до читателя.

Нет. Выше было доказано, что человеку не проще. Это миф. Компилятору тоже не проще. Проще академическому скаму продавать свой скам/сидеть на грантах - это да. Других причин нет.

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

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

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

Просто printf работает, когда когда есть контекст. Поэтому какая-то контекста свобода существует только в академической пропаганде.

Любые рассуждения об этой «свободе» всегда значат «я не осилил и пытаюсь впарить это кому-то». Других причин нет. По крайней мере я их не слышал(ну убедительных причин).

Вся логика на языках - контексто-зависимая. Вся семантика такая же. Люди мыслят так. Зачем же языку контексто-свободная грамматика? Чтобы что?

Чтобы вместо компиляторы мы имели мусор? Чтобы вместо развития реально полезного - мы кормили разводил? Не. Это ненужно.

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

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

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

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

Вот мы имеем код. Он контексто-зависимый. Помогут ли нам какие-то контексто-свободные наработки? Нет. Они мусор.

Но если мы будем развивать контексто-зависимый анализ. Интегрировать его в языке/тулинг - мы сможем глубже понимать наш код. Нашу природу. Это цель - развитие.

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

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

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

чему равно в десятичной системе счисления контекстно зависимое 2+2 ?

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

Вот мы имеем код. Он контексто-зависимый. Помогут ли нам какие-то контексто-свободные наработки? Нет. Они мусор.

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

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

пример - ident1 ident2 (ident3, ident4, ident5,…) , в си++ это может быть и незавершенная декларация функции, и декларация переменной, как это интерпретировать понять можно только из семантики этих самых ident.

то есть для парсинга грамматики(синтаксического анализа и выяснения соответствия текста грамматическим правилам) надо вести списки декларированных обьектов, и искать что это за ident. То есть чтобы найти СИНТАКСИЧЕСКУЮ ошибку, надо заниматься уже семантикой. а это неправильно.

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

чему равно в десятичной системе счисления контекстно зависимое 2+2 ?

Зачем ты мне навязываешь этот свои фантазии?. Для начала а) свяжи свои вопросы с темой обсуждения. б) объясни зачем ты задаёшь эти вопросы. в) объяснить почему ты не отвечаешь, а вместо ответа пишешь мне чушь.

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

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

Реальность натянуть на школьные понятия. А после навязывать мне эти понятия. Это не более чем манипуляция.

Начни с определения контекста. Что такое два, что такое система счисления. Что такео «десятичной», что такое 2, что такое +, что такое «равно».

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

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

Начни с определения контекста. Что такое два, что такое система счисления. Что такео «десятичной», что такое 2, что такое +, что такое «равно».

вот так и скажи, коротко и ясно - в замечательной продвинутой контекстной несвободе «2 + 2» это непонятно что. тут непонятно, что такое 2 и что такое оператор +. они могут быть переопределены и иметь сложные смыслы. может это вообще некорректная запись. может это выражение каких то эмоций. короче приехали.

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

констекстная свобода у грамматики это не код.

Действительно - это не код. Это мусор. Правда я нигде не говорил, что это код.

это способ выбора правил разбора этой грамматики. про семантику речи тут нет вообще.

Я знаю что это. Детище неосиляторов не имеющие смысла к существованию. Мне ненужно рассказывать это. Это самая примитивная примивщина.

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

Хотя на самом деле и грамматика код, но это уже совсем сложно. Поэтому ненужно.

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

Символы мусор - это часть методички. Сразу выкидывается.

Не, знать любой контекст. Если мы говорим про ll1-мусор - там контекст чётко определён. А манёвры на тему «ну мы можем расширить его» - непроканают.

пример - ident1 ident2 (ident3, ident4, ident5,…) , в си++ это может быть и незавершенная декларация функции

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

Вспоминает что я говорил ранее. Для мусора - это какие-то символы неведанные. Вернее их тупой класс(который идентифкатор). А вот для нормального подхода это не мусорный класс ident, а уже подкласс.

И с учётом этого всё уже спокойно разрешимо.

и декларация переменной, как это интерпретировать понять можно только из семантики этих самых ident.

Правильно. Только у тебя уже есть семантика - это твои символы. Конечно - это мусорная академическая абстракция. Такая же бесполезная.

Поэтому не смогши ничего с реальными символами - они так же решили добавить в них семантику, а именно их классификацию. Тот самый ident оттуда.

Вот в нормальном подходе этих ограничений/фантазий нет. Они мусор.

то есть для парсинга грамматики(синтаксического анализа и выяснения соответствия текста грамматическим правилам) надо вести списки декларированных обьектов, и искать что это за ident. То есть чтобы найти СИНТАКСИЧЕСКУЮ ошибку, надо заниматься уже семантикой. а это неправильно.

Удивительно то как академическая пропаганда всем навязывает свои фантазии. С чего вдруг эта ошибка должна быть синтаксической? Это твои фантазии. Как и рассуждения о правильности.

Поэтому люди ищут и дают нормальные ошибки. Академический даёт мусор и не может написать паскаль.

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

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

Не, в том и смысл. Что в контекстой несвободе есть 2, а у тебя нет ничего. В этом фишка.

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

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

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

Так же и здесь.

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

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

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

Вот попытайся ответить на вопрос - зачем. Что мне даёт фантазирование о контекстно-свободной грамматике? Что индустрии даёт.

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

За рамками этого - зачем? Вот ты выше показывал последовательность идентификаторов со скобочками. Зачем мне не учитывать их классы? Чтобы что? Что мне это даст? Кроме убогих сообщений об ошибках, ограниченности и прочего?

Ведь я итак знаю эту информацию. Я её могу получить. Зачем мне искусственно себя ограничивать? Что-бы что? Подумай об этом.

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

Поэтому не смогши ничего с реальными символами - они так же решили добавить в них семантику, а именно их классификацию. Тот самый ident оттуда.

блин. просто тут у высказывания Вася Петя(Гоша, Саша, Степа, Коля, Ваня) нет однозначной интерпретации в рамках C++. и потому интерпретация выбирается из значений этих вась и петь, а также места, где это встретилось. это не дает ничего кроме сложностей при разработке как самих языковых тулзов, так и чтений глазками.

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

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

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

блин. просто тут у высказывания Вася Петя(Гоша, Саша, Степа, Коля, Ваня) нет однозначной интерпретации в рамках C++.

Есть, но не в этом дело. Она и не должна быть. В С++, конечно же, много легаси и академического мусора. Это такой компромисс, но это уже хорошо.

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

Не, это самая мусорный пропагандистский лозунг из всех. Это упрощает создание тулзов, вернее как минимум не мешает ему. Единственное кому оно мешает - скамерам. Там да. Об этом подробнее писал я выше.

так и чтений глазками.

Никаких проблем нет. Я уже выше говорил. Утверждать, что у человека есть проблема с пониманием контексто-зависимой информации - это совсем шиза.

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

В целом это типичная методичка неосиляторов про вывод типов. Уже давно протухшая.

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

Да, только вот контексто-свободность это как раз такие для автоматов. Вернее тех кто может только в примитивные их вариации.

У человека никогда не было контексто-свободы. Это придумали неосиляторы. Как раз таки для тех самых автоматов.

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

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

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

Напоминаю, что у вас срач о

fn int foo() { ... }
//vs
int foo() { ... }
Ну так.
Какому-то человеку может быть не понятно, что foo - функция? Ну он видит код, понимает, что это функция. Нахера ему fn? Чтобы что? Оправдать это можно только тем, что «я не хочу сношаться с парсером кода». Больше это оправдывать решительно нечем.
Вот если бы ты начал что-нибудь про то, каким был перл...

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

Какому-то человеку может быть не понятно, что foo - функция?

непонятно,просто не надо приводить наивные примеры. вот пример правильный

sdasdsfgsklak::fdsfsfasdgfdas::dafsdfsdf::dsfsdfsd<ffsdafgasdf<fsdf>, fdssadfasdf, tytyrwer24324hhfjsdjhfs<fhfshdjhfd, int>> hhjfshfjsdf::hhfjshdfsdf::hjhfsjdhfsdf::hgbfdsfsdfgdfhgh::ffsdfsdf(dhdhfajshfasdf::dsfglotr, kklfsdfs::mmfsdmfsd::dgdfgh);

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

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

непонятно,просто не надо приводить наивные примеры. вот пример правильный

И чем тебе поможет fn в начале? Это говно сразу станет понятное?

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

Оправдать это можно только тем, что «я не хочу сношаться с парсером кода». Больше это оправдывать решительно нечем.

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

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

Какому-то человеку может быть не понятно, что foo - функция?

Обычно в языках есть замыкания и анонимные функции. Тогда fn() – объявление, fn()() – вызов, any_name() – всегда вызов.

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

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

Ну то есть нечем.

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

И что это меняет? Если у тебя не fn, а тип, после которого аргументы и блок кода - всё равно не понятно, что это - анонимная функция?

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

Внимание обнаружено маняврирование. Дальнейшее обсуждение невозможно.

Маняврация 0

вот пример правильный

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

Основание тому, что первый пример правильный - а) он работает, б) это явно живой код, а не набор символов.

Маняврация 1

);

Выдача декларации символа из си за fn.

  • fn в паскалятине означает функцию, у функции есть тело. Сравнение не может быть произведено. Манявристу требуется, либо привести в паскалятине аналог декларации символа, либо на сишке показывать аналог функции.

  • Декларация символа не является функций. Обнаружено терминальное невежество. Оно является декларацией «переменной». Такой же как int x.

    Доказывается это очень просто:

template<typename T> using fn = T;

fn<void(int)> foo;

Маняврация 2

декларацией функции и декларацией переменной

Отметается как пример полней несостоятельности(пруфы выше).

просто ошибкой

В контексте

fn человек

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

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

Требуется пояснение по фундаментальной маняврации.

В этой маняврации производится типичная подмена контекста.

Предположим, что это действительно переменная/функция. Которая объявляется через одну конструкцию. Но вот в чём проблема. Это всё работает в сишке, а не в паскалятине. Т.е. в паскалятине не может быть такой ситуации, когда одно похоже на другое. Это слишком сложно.

Поэтому в паскалятие будет условное var для переменных. Таким образом нельзя будет спутать функцию с переменной. Таким образом fn является бесполезным мусором с т.з. идентификации функции/переменной.

Данная маняврация берёт контекст из сишки и натягивает его на паскаялтину, чтобы создать видимость наличия «проблемы»(забудем, что проблема есть только в фантазиях манявратора). Без этой подмены рассуждения в принципе не сходятся.

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

И что это меняет? Если у тебя не fn, а тип, после которого аргументы и блок кода - всё равно не понятно, что это - анонимная функция?

В случае с C3 оно вообще ничего не меняет в этом плане.

У него (автора С3) там есть пример с defer как альтернативе goto. Проблема в том, что у goto есть доступ к контексту функции и возвращаемым значениям. А если вызывать функции определённые вне текущей, то доступа к контексту не будет.

void do_something(void) {
    //
    defer finialize(ptr);
    //
}

Вот тут совсем нет доступа к контексту do_something изнутри finialize. Можно только передать параметры. И они сохранятся такими, какие они на момент передачи. Конечно можно использовать указатели прочее, но это всё равно не альтернатива goto и не полноценный defer.

В стандарт C предложено внести лямбды и defer из golang

Здесь описано предложение внести лямбды и defer в Си. Как видите, там используется совершенно другой синтаксис, вовсе не int name(int) и не fn int name(int). Потому что оба они для этого не подходят.

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

Если сравнивать int name(int) и fn int name(int), то это два неподходящих варианта. Неподходящих потому, что они тащат с собой не нужное барахло, когда нужно сделать шаг в сторону (на самом деле defer – повседневка).

Убогости выражения

int name(int) {
    // allocate ptr
    defer void (*)(void) { free(ptr); } ();

    // stuff
}

fn спереди никак не изменит. Как и остальные варианты сишных функций с defer, с каким-то специальным синтаксисом для лямбд, специальным синтаксисом для defer и так далее.

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

Проще говоря, это всё попахивает охранительством сишного синтаксиса, при явной его убогости в общем плане. И fn int name(int) занимается тем же самым охранительством. Вместо того, чтобы отринуть его.

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

И fn int name(int) занимается тем же самым охранительством. Вместо того, чтобы отринуть его.

В C3 есть макросы, и кл-ое слово fn нужно хотя бы для этого. Другой пример:

define Callback = fn char(char c);
fn char do_not_change(char c) => c;

fn void main()
{
    Callback tl = &do_not_change;
}
dataman ★★★★★
() автор топика
Ответ на: комментарий от thegoldone

Как видите, там используется совершенно другой синтаксис, вовсе не int name(int) и не fn int name(int). Потому что оба они для этого не подходят.

Что ты несёшь? Какое отношение синтаксис int name(int) имеет к теме? Это вообще не имеет отношения к функциям. В целом фиксирую очередное невежество.

Неподходящих потому, что они тащат с собой не нужное барахло, когда нужно сделать шаг в сторону (на самом деле defer – повседневка).

Какое барахло?

Убогости выражения

defer void (*)(void) { free(ptr); } (); - не позорься, ты не знаешь что такое void (*)(void) ни что такое выражение не имеет смысла.

Уж тем более какие-то ещё мусорные скобки наклал. Зачем ты так позоришься?

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

rust/ruby - || free(ptr) js/c#/тысячи их - () => free(ptr) С/С++ - []{free(ptr); } java/kotlin - () -> {free(ptr); }

Можно вопрос - где и в какой вселенной анонимные функции определяются через ключевые слова?

Уж про разницу между анонимной/не анонимной функции разницу, думаю, показывать не стоит. Уровень пациента уже ясен.

Даже привету пару примеров: fn foo() -> type - rust, function foo(): type {} - js/ts.

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

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

rust/ruby - || free(ptr) js/c#/тысячи их - () => free(ptr) С/С++ - []{free(ptr); } java/kotlin - () -> {free(ptr); }

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

js

В JS () => expr всего лишь эквивалент function() { expr };, просто «стильный модный и молодёжный». Вот кл. слово function. Остальные варианты полагаю имеют тот же смысл.

С/С++ - []{free(ptr)}

Говно по всем параметрам.

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

С/С++ - []{free(ptr)}

Говно по всем параметрам.

Я даже готов объяснить почему. Вот есть функция гипотетического языка Икс

fn name(a arg) reply { block }

А вот её вызов в defer

fn some() (r reply) {
   let a = 10;
   defer name(a);

   // stuff

   ret;
}

А вот она же, только определённая внутри функции some

fn some() (r reply) {
    let a = 10;
    defer fn(a args) reply { block } (a);

    // stuff

    ret
}

И здесь есть всё что нужно, при этом используется уже существующий синтаксис без доп. спец. конструкций:

  1. Аргументы.
  2. Возвращаемое значение.
  3. Наследование родительского пространства имён до defer.
  4. Замороженные переданные значения (} (args);), дальнейшие изменения которых в родительской функции ничего не изменят для отложенной функции.
  5. Доступ к возвращаемому значению родительской функции.
  6. Если это заложено в языке Икс, а так как он выдуман, то заложено, ещё и отложенные вызовы игнорируют исключения в родительской функции и всё равно отрабатывают.

Без всего этого нормального defer не реализовать.

Ну и вопросы:

  1. Зачем отдельный синтаксис-то тогда?
  2. Зачем явно или неявно что-то передавать во внутреннее пространство имён, если для этого есть обычные подходы.
  3. Зачем явно добавлять работу по заморозке передаваемых значений.

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

А объяснение тут одно. Потому что в C/C++ синтаксис функций достаточно устаревший и убогий, и он не позволит этого сделать. Получится говно.

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

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

Какие-то фантазии на тему.


reply name(a arg) { block }

reply some() {
   let a = 10;
   defer name(a);

   // stuff

   ret;
}

reply some() {
    let a = 10;
    defer reply(a args) { block };

    // stuff

    ret
}

Зачем он пишет какой-то мусор вида:

defer fn(a args) reply { block } (a); - это логически неверная запись. Это вызов функции по-месту. Это не является корректным.

В любом случае ничего не мешает на сишке писать подобное шуе reply(args a) {}(a);

Судя по всему эта какая-то максимально дырявая/бездарная вариация захватов. Это в принципе ненужно. Как и ненужно указывать типы, если они могут быть выведены.

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

И здесь есть всё что нужно, при этом используется уже существующий синтаксис без доп. спец. конструкций:

Как то мимо. Никакой существующий синтаксис для лямбд ненужен. Это чушь.

Лямбды - это выражения. А функции - это стейтменты. Функции существуют отдельно. Лямбды существуют в контексте.

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

Удивительно как ты ничего не зная позволяешь себе рассуждать о сишке. В сишке нет никакого «синтаксиса» - это твои фантазии.

В сишке есть только скобочки и имя. Скобочки - функция, имя - имя переменной/символа.

foo() {}

Это синтаксис функции в сишке. foo - имя сивола, () - признак функции. Точно так же как arr[] - здесь [] - признак массива.

{} - это тело функции.

Соответственно, если мы говорим об анонимной функции - у неё не должно быть имени. Как нет имени у выражений.

Поэтому результирующий синтаксиc - это () {}. А не какие-то твои фантазии.

В С++ используется именно такой синтаксис, только вот в лямбдах нужны ещё и захваты. Поэтому для захватов выделены отдельные скобочки. И т.е. в лямбде описание захватов приоритетней нежели описание параметров - в цпп сделали [] - основными.

У обычных функций, собственно, никаких захватов нет. Поэтому скобочки им ненужны.

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

Поэтому именно в цпп никакой синтаксис не меняется - он дополняется. Просто в силу необходимости.

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

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

В любом случае ничего не мешает на сишке писать подобное шуе reply(args a) {}(a);

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

Ну тогда это будет

defer (args a) {  /* stuff */ }(a);

Возвращаемого значения нету, типа тоже. Есть аргумент, есть блок. Всё прекрасно.

  1. Чем это не устраивает?
  2. Тут всё ещё нет возможности подменить возвращаемое значение родительской функции в отложенном вызове.
thegoldone ★★
()
Ответ на: комментарий от right_security

А теперь идёт по ссылке:

p = malloc(N);
defer { free(p); }

Что мы здесь видим? Мы здесь не видим функции. Мы видим вызываемый блок. На самом деле это базовая концепция того, почему скобочки можно убрать.

Т.е. функция у нас () {}, но скобочки это признак функции. Он нужен для правильной декларации символа, его типа. Но сама функция - это блок.

Поэтому если мы уже находится в том контексте, где есть признак функции. Нам нет смысла писать ещё один признак функции.

Такая же история со списком инициализации в си. [] = {} - Это контекстная сущность, она берёт признак из контекста.

Когда же в си выделили {} в отдельную сущность. Ей уже потребовалось задавать контекст, поэтому она стала ([]){}/(struct){} - признак добавляется рядом.

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

Вот по аналогии defer = это такой же признак, признак функции.

typedef void defer();

defer {};

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

А то, что показываешь ты/врёшь про сишку - это никакого отношения к «нормально» и сишки не имеет.

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

В С++ используется именно такой синтаксис, только вот в лямбдах нужны ещё и захваты. Поэтому для захватов выделены отдельные скобочки. И т.е. в лямбде описание захватов приоритетней нежели описание параметров - в цпп сделали [] - основными.

  1. Обычное дело, это когда {} (любой) наследует родительское пространство имён, но не может в нём создавать новые переменные.
  2. И есть вызов функции, когда аргументы копируются фактом передачи.

Извините, но на фоне этого выражение []{} мне кажется излишним. Не кажется ли Вам, что это просто ненужная перегрузка языка доп. конструкциями?

  1. Функции можно дать имя, присвоить её переменной и использовать во множестве мест, где угодно. А []{} так умеет без макро-костылей?
thegoldone ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.