LINUX.ORG.RU

Что нужно добавить в C?

 


0

5

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

Или покритикуйте мой список.

  • Константы. #define - препроцессор, const не работает полноценно в compile-time, enum только для целых и вообще для другого .
  • Лямбды (анонимные функции) - для удобства коллбеков. Можно без замыканий, т. к. они много скрывают.
  • Модули, если возможно. Для изоляции единиц трансляции.
  • Интроспекция (typeof, хотя бы) - для обобщенного программирования.
  • Более развитая макросистема - для того же. Например, возможность макросы раскрывать в директивы препроцессора.
  • Пространства имен, чистые функции, switch по составным типам, case с диапазоном - для сокращения кода.
  • Аналоги volatile и restrict с более точным контролем - для микрооптимизации.
  • Доступ к стеку вызовов, goto между функциями - для трюков типа трамплинов.
  • В стандартной библиотеке - строки, контейнеры, foreach, большие числа. Возможно, сокеты.
★★★★

Константы. #define - препроцессор, const не работает полноценно в compile-time, enum только для целых и вообще для другого .

Не нужно, define хватает.

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

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

Модули, если возможно. Для изоляции единиц трансляции.

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

Интроспекция (typeof, хотя бы) - для обобщенного программирования.

Не нужно, накладные расходы. Кому нужно - сам делает как ему удобно.

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

Ну абстрактно препроцессор улучшить можно. Конкретно - надо смотреть по конкретным предложениям.

Пространства имен

Не нужно, сломает ABI.

чистые функции

Не нужно, это не стиль С.

switch по составным типам

Как это? Что ещё за составные типы?

case с диапазоном - для сокращения кода.

Разумно.

Аналоги volatile и restrict с более точным контролем - для микрооптимизации.

Не знаю, по-моему и volatile мало кто понимает. Нужно ли это в стандарте? Там вообще в стандарте сейчас понятие потоков есть и чёткая модель памяти?

Доступ к стеку вызовов, goto между функциями - для трюков типа трамплинов.

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

В стандартной библиотеке - строки

Давным давно есть.

контейнеры

Мне кажется, это сложно будет сделать. Может быть и можно.

foreach

Не думаю, что это нужно. Зачем?

большие числа

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

Возможно, сокеты

Не нужно, не кроссплатформенно. Для таких вещей есть POSIX.

Legioner ★★★★★
()
Ответ на: комментарий от no-such-file

нечто, очень похожее на pattern matching

Но не паттерн матчинг

Деталей семантики он не привел. Впрочем, switch по целому числу - это такой очень ограниченный pattern matching.

чем обобщенный switch лучше if else if else?

У switch (как он реализован в Си и Си++) семантика другая

Да именно это я и сказал.

Забавно. Я даже не говорил, чем «switch лучше».

тебе лишь бы вякнуть ещё раз.

Мог бы просто попросить «защитай мне слив».

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

Интроспекция (typeof, хотя бы) - для обобщенного программирования.

Не нужно

Не нужно кому? Те, кто не обязан писать переносимый код, вполне пользуются GNU-расширением __typeof__.

накладные расходы

Какие и на что?

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

Не нужно кому? Те, кто не обязан писать переносимый код, вполне пользуются GNU-расширением __typeof__.

Если compile-time, то можно, проблем не вижу. Я чего то подумал про runtime reflection.

Legioner ★★★★★
()
Ответ на: комментарий от no-such-file

Joy W.N. UNIX Pascal user's manual

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

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

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

qulinxao ★★☆
()
Ответ на: комментарий от no-such-file

ну а про реальную модульность - очень хорошо у Оберона где можно на горячую заменять модули и даже расширят их интерфейсы.

а даже у жабки на эту тему есть интерестности.

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

у Си нет модулей

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

у Си есть линковка как отдельная общая для обьектников вне зависимости от фортран это , асм это или сам его величество С-обьектник.

В том то и дело, что это не относится к си как к таковому, организация линковки - дело операционной системы, ну или среды разработки в недоОС. А вот введение модулей в язык, делает всю эту кухню проблемой языка. Зачем тащить дела ОС в язык? Я понимаю, что в бородатые времена, когда ОС и средства разработки были слабо развиты, такой подход был популярен. На первых персоналках вообще, встроенный язык выполнял роль ОС, но зачем тащить это сейчас в язык. Независимость от ОС я считаю прорывом си. Именно это позволило прозрачно перейти к динамическим библиотекам без какого-то изменения языка.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

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

вот тот же Unix&C по факту ОС это сборщик муссора в том числе ,а С- программа даже не обязана ( и у патриархов сплош и рядом так код и написан) free-шеть mallocнутую память С- программе достаточно свялится , а ОС похоронит трупик и вернёт всё в биогеоценоз.

поэтому как и модулю а сей нет штатного сборщика муссора.

а теперь вопрос:

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

qulinxao ★★☆
()
Ответ на: комментарий от no-such-file

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

ща как раз есть проблема когда на уровень языка тащат всё

однако посмотри на эволюцию С-->golang - так как оба языка предназначенны в том числе для исполнения на голом железе замечательно почему в golang добавили то чего не было 40 лет назад в С ( хотя и тогда всё что добавли в golang уже было известно среди многих включая и BellLabs)

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

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

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

no-such-file ★★★★★
()
Ответ на: комментарий от qulinxao

которым был обычно бэйскик и был её осью

Так в том то и дело. И не на персоналках тоже. Был такой подход ввиду тормознутости железа. Собственно бейсик для того и был изобретен, чтобы предоставить интерактивную среду программирования в которой есть всё в себе. Прото-IDE из 60-х. Отсюда и растут ноги у всех этих модулей в языке, файлов в языке, сетевых интерфейсов в языке и прочего хлама, который в языке как таковом не нужен, а должен быть отдан на откуп ОС и/или среды разработки.

так как оба языка предназначенны в том числе для исполнения на голом железе

Go на голом железе? Со сборщиком мусора и многопоточностью в языке? Да ты наверное бредишь. Нет, я понимаю, что можно реализовать концепт в виде среды исполнения для Go на голом железе без ОС (такое микроядро для Go-сервисов), но это тот-же бейсик-ОС родом из 70-х.

no-such-file ★★★★★
()
Ответ на: комментарий от Legioner

case с диапазоном - для сокращения кода.

Разумно.

Некоторые компиляторы вроде умеют.

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

Go на голом железе? Со сборщиком мусора и многопоточностью в языке? Да ты наверное бредишь. Нет, я понимаю, что можно реализовать концепт в виде среды исполнения для Go на голом железе без ОС (такое микроядро для Go-сервисов), но это тот-же бейсик-ОС родом из 70-х.

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

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

Программа компилировалась со спец флагом (минимальынй рантайм прикручивался) и запускалась на голом железе.

Дай, что ли, почитать.

no-such-file ★★★★★
()

Немного проприетарщины.

system
()
Ответ на: комментарий от no-such-file

ну зачем же так грубо то?

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

qulinxao ★★☆
()
Ответ на: комментарий от no-such-file

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

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

голэнг спроектирован ровно так же как С(для того времени) - использая некоторый идеализированный СОВРЕМЕННОЙ(созданию) многопотоковый проц(с комуникацией через сеть с другими узлами) как идеализированную машину исполнения

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

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

Это, конечно, сарказм.

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

не уже ли?

фортран с коммон блоками и вызовом процедуры(без ПАРАМЕТРОВ!!!) с сохранением адресса возврата в специальной (затираемой ежель ...) переменной - вот оно самое.

зы. за линк на блог благодарю , очень полезный.

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

а если серьёзно , то как давно заметил тот же Оруэл ( а он видимо просто был в курсе мыслей приведшей к гипотезе Уорфа-Спарфа?) язык определяет сознание.

вот такаая рефлексия : давно когда учился и нас ознакамливали с рекурсией , я был несколько удивлён от чего соученики(сокурсники) буксуют - и тут достаточно не давно повторно наткнулся на двухтомник

Ф. Л. Бауэр, Г. Гооз - Информатика. Вводный курс. Часть 1 и 2

а так получилось , что не очень понимая но я его пролистал/прочитал в возрасте 12-14 лет.

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

а вот затем наткнулся на вот такое археологическое : http://funcall.blogspot.ru/2011/02/no-stack-no-problem.html

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

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

поддержка языком рекурсивных вызовов функций

Не обязательно через стек.

что согласись излишество и баловство

Дело вкуса.

no-such-file ★★★★★
()
Ответ на: комментарий от qulinxao

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

Ой ой, где-то я уже это слышал, ах да, ява и ява-процессоры.

что бы рантайм на современных машинах у голэнга был так же минимален(почти остутсвует) как и С-изначального

У си изначального, да и у неизначального райнтайм вообще может отсутствовать. Плюшки типа автолинковки пролога/эпилога, libc и прочая можно отключить, кому они не нужны. Си компилятор может выдавать код для запуска as is, голанг может? - хренушки. Это всё тот же бейсик-все-включено, на современный лад да, с потоками, сборщиком мусора и другими модными батарейками.

PS: я понимаю, это такой фирменный стиль, но все же твои посты выглядят как перевод гуглом с китайского.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

да , ибо Pcode который стал общеизвестен в java-ипостаси реализован был уже в середине 70ых и цель была как раз получить окружение малозависимое от конкретной железки , а задача распределённых вычислений и вариант акторов и варинат cspХоара и работы с препрепредшествениками plan9(inferno(в котором опять Limbo и Dis)) т.е задача получение многомашиной системы где отдельномашиность универсализированно через обёртку либо в виртуальную машину либо унивефецирующий рантайм идеи уже более 40 лет.

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

модули в С всегда были - это .c файл

... и h-файл. Это не модули. Компилятор и линкер не знают друг о друге, LTO превращается в rocket science.

Изоляция делается через static

Изоляция - это когда делаешь import и получаешь только имена из импортированного модуля. А не так, как получается с include, когда в довесок получаешь массу ненужного из других «модулей».

Пространства имен

Не нужно, сломает ABI.

Можно попробовать сделать без слома. А хоть и с ним, невелика беда. Его делали даже без изменения языка.

чистые функции

Не нужно, это не стиль С.

В GNU C уже есть.

Что ещё за составные типы?

struct, union. Проверка нескольких полей в одном case.

Не знаю, по-моему и volatile мало кто понимает. Нужно ли это в стандарте?

Имхо, без этого чистый стандарт малоюзабелен. В ряде задач - либо ассемблер, либо implementation-defined behaviour.

Там вообще в стандарте сейчас понятие потоков есть и чёткая модель памяти?

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

строки

Давным давно есть.

char* - это не строка. Строка - это ADT, причем желательно эффективный (а не тот где strlen - O(n)).

контейнеры

Мне кажется, это сложно будет сделать.

В куче библиотек же сделали. Осталось выбрать, можно с вариантами (например, linux/list.h и GList). А хорошо в си не сделаешь, да.

foreach

Не думаю, что это нужно. Зачем?

Нынешний for - это тупой while. Уровень ниже, чем у настоящего for/foreach, перебор выглядит сложнее, чем он есть.

большие числа

Не нужно

Тогда уж и math.h не нужен.

сокеты

Не нужно, не кроссплатформенно. Для таких вещей есть POSIX

... а так же win32 и пр. Если уж воистину платфомозависимые треды стандартизовали, то с сокетами, которые везде BSD, проблем не будет.

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

Default linkage и так опциями компилятора выставить можно.

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

Нормальное именование библиотечных функций. Например compareStrings вместо strcmp.

Тебе в сторону Qt надо ползти, считай что это Си со всем о чем ты мечтал.

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

Тебе в сторону Qt надо ползти, считай что это Си со всем о чем ты мечтал.

Qt это же приплюснутые.

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

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

Пара .c и .h файл + static не заменяет даже самую простую систему модулей.

Пример:

Модуль A использует модуль B, в котором есть функция f. В си ты от линкера уже не спрячешь функцию f.

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

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

Это нужно. Проблем было бы меньше, если бы можно было писать функции посреди кода.

int main(){
     int f(int x){
         return x+1;
     }
     printf("%d", f(0));
}
Waterlaz ★★★★★
()
Ответ на: комментарий от tailgunner

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

Полезно. Блок должен быть функций. Собственно это есть в гнуси, но там оно обрезанное.

Хорошо бы стандартизировать расширения GNU C - там есть и typeof, и блоки кода как выражения, и форма RAII.

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

И еще хочу возврат нескольких значений из функции :)

Пацаны досихпор не осилили структуры? Ну что с вас взять.

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

Те, кто не обязан писать переносимый код,

Ахаха насмешил - gnuc-код самый переносимый в мире. А тут вдруг пацан решил, что он не переносимый - куллстори.

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

У тебя уже есть gcc для PIC? Нет? Вали отсюда, ламер.

anonymous
()

switch по составным типам, case с диапазоном - для сокращения кода.

Это называется pattern matching + guards.

loz ★★★★★
()

Динамические переменные и питон-форматирование.

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

Пацаны досихпор не осилили структуры? Ну что с вас взять.

Структуры будут для такого подходить, если будут параметрические типы.

Типа такого:

struct pair<t1, t2>{
    t1 a;
    t2 b;
};
struct pair<double, int> some_func();
Waterlaz ★★★★★
()
Ответ на: комментарий от loz

Это называется pattern matching

Можно ли говорить про pattern-matching при отсутствии алгебраических типов?

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

Зачем создавать, а потом разбирать структуру когда нужно просто вернуть несколько значений?

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

Си с параметрическими типами и тайпклассами

Это уже не си. Rust?

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

Что значит несколько значений, что значит разбирать? Нука накатай мне пример как ты вернёшь эти несколько значений - пример синтаксиса:

int a, b;//запиши в них значений 1 и значение 2 из функции f().

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

Зачем? Ну вернул ты эту структуру - что дальше? Куда ты её запишешь, а если никуда записывать не надо - как ты из неё получишь значений по отдельности?

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

Если у тебя функция возвращает больше одного значения - значит это уже какая-то сущность - объект из ооп-мира. Она именуется и используется как тип тайпдефом, если тебе нужны какие-то другие «типы» - ты не осилил этот ЯП.

Если тебе нужны какие-то более фичастые вещи - стейтмашина, контексты тебе в помащь. work(); - апдейтит твой окнтекст, далее выщёлкиеваешь get_int(), get_double().

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