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)
Ответ на: комментарий от untitl3d

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

грамматика должна быть класса LL1. все остальное ложно. сишная таковой не является. следуя этому нехитрому знанию про LL1 и пишут всякие fun, var, type, class и тепе.

alysnix ★★★
()

Моё мнение что этот яп проектировал человек с поверхностным пониманием проблемы. Видно что багофич чистого си он наелся и смежные яп изучал. Но некоторые его решения прямо жёсткий фейспалм.

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

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

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

Сложно. В С можно передавать тела в макросы, и есть __cleanup__.

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

И что все к этому UB прицепились...

Если пытаешься впихнуть >4 байт в 32 битный тип это UB, если делишь на ноль это тоже UB. Может стоит хоть чуть-чуть следить за ходом мысли и своей программой когда пишешь код? Особенно в местах, где нужен си или его убийцы.

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

Может потому, что люди не особо внимательны, ошибаются и желают от компилятора защиты от ошибок?

urxvt ★★★★★
()

очередной «убийца» C

Нет тела — нет дела.

PhysShell ★★
()

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

cyzemogy
()

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

компилятор написан на C

Дальше можно не читать…

mord0d ★★★★★
()

Главный вопрос - а чем оно лучше C?

Meyer ★★★★★
()

еще одна процедурная зал упа без классов, Г-споди, уbay их всех !

Syncro ★★★★★
()
8 октября 2022 г.

Кого-нибудь интересуют вести с полей или всех «фи» уже было достаточно?

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

модули - нет хидерам!

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

Я вижу здесь некое противоречие.

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

Объясните что ещё за модули когда в примере используется «extern fn void printf(char *fmt, …);». Молули подразумевают что будет использоваться что-то вида «import stdio;».

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

На момент публикации ещё не было своей реализации printf. Теперь есть:

import std::io;

fn void main()
{
    io::printfln("int.min = %s", int.min);
    io::printfln("int.max = %s", int.max);

    io::printfln("uint.min = %s", uint.min);
    io::printfln("uint.max = %s", uint.max);

    io::printfln("123 = %c", 0xffff);

    int[*] a = { 1, 2, 3 };
    io::printfln("array = %s", a);
}
dataman ★★★★★
() автор топика

fn... смешная экономия буков, либо... зачем вообще fn?

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

Тогда должно быть написано «import libc». Объявление внешних символов прямо в коде – это нарушение принципов модульности и те самые инклюды.

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

import libc

Так тоже можно. Такой модуль есть.

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

грамматика должна быть класса LL1. все остальное ложно.

инструмент должен быть удобен - понятная и правильная цель.

инструмент должен целиком разбираться ключиком на десять - цель ложная.

olelookoe ★★★
()

Двойное двоеточие – отстой бессмысленный.

То, что есть defer – хорошо. Но это д.б. стандартом в наше время.

То что не нужно делать break в seitch – разумно.

Нет goto – ну не знаю. Сомнительно.

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

Двойное двоеточие – отстой бессмысленный.

Да, мне тоже не нравится. Но какая альтернатива, точка? Давайте хорошие доводы, я постараюсь убедить автора. :)

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

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

macro uint[<*>].popcount(uint[<*>] i) = $$popcount(i);
macro uint[<*>].ctz(uint[<*>] i) = $$ctz(i);
macro uint[<*>].clz(uint[<*>] i) = $$clz(i);
macro uint[<*>] uint[<*>].fshl(uint[<*>] hi, uint[<*>] lo, uint[<*>] shift) => $$fshl(hi, lo, shift);
macro uint[<*>] uint[<*>].fshr(uint[<*>] hi, uint[<*>] lo, uint[<*>] shift) => $$fshr(hi, lo, shift);
macro uint[<*>] uint[<*>].rotl(uint[<*>] i, uint[<*>] shift) => $$fshl(i, i, shift);
macro uint[<*>] uint[<*>].rotr(uint[<*>] i, uint[<*>] shift) => $$fshr(i, i, shift);
dataman ★★★★★
() автор топика

Лажа. Автор такой заявляет:

Rejected ideas: Constructors and destructors.

И ты видишь, что это не шутка. Хочешь писать на c3 - будешь пердолиться с кодом в стиле 70-х:

fn String new(char[] c)
fn void String.destroy(String* str)

fn void! File.open(File* file, char[] filename, char[] mode)
fn void! File.close(File *file) @inline
fluorite ★★★★★
()
Ответ на: комментарий от dataman

Да. В сишке хоть goto есть. if (err) goto cleanup; А тут что предлагается?

Ещё не совсем понял, вот этот tildebe - это авторский код?

fluorite ★★★★★
()

Вангую, что будет, как с D. Реально интересные фичи заберут в C++, после чего нужность самого языка окажется под вопросом (модули вот уже забрали).

Вот синтаксические фишки типа fn не заберут, конечно. Но эту нишу уже Раст занял. Большая часть пишущих на си-подобных языках конструкцию int this_is_a_function_SURPRISE (...) считают достоинством, а не недостатком. Я вот не считаю, но и крестовый поход против си из-за этого устраивать не буду. «Не жили богато, нечего и начинать».

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

А тут что предлагается?

https://www.c3-lang.org/errorhandling/

tildebe - это авторский код?

Это API к tilde-backend, как возможной альтернативе LLVM. Пока не рекомендуется к использованию. :)

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

Ну вместо этого отстоя, используется нормальный defer.

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

Конструкторы и деструкторы – это же одни проблемы. Они только в отстойных языках, где try и catch.

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

io::printfln(«uint.min = %s», uint.min);

Что будет если плейсхолдер %s не будет соответствовать типу переданного значения?

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

Но какая альтернатива, точка?

Да, в Обероне используется точка для обращения к модулям так же как и записям.

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

И ты видишь, что это не шутка. Хочешь писать на c3 - будешь пердолиться с кодом в стиле 70-х:

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

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

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

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

fluorite ★★★★★
()

И ещё вопрос. Оно на ШлангВМ. А значит к нему есть LSP-плагин для разработки, который прям очень помогает и всё такое?

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

Ничего плохого не случится. И можно переопределить to_string и/или to_format:

struct Foo { int x; void* bar; }

define IntFooMap = std::map::HashMap<int, Foo>;
define IntDoubleMap = std::map::HashMap<int, double>;

fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
{
    String s = string::new_with_capacity(128, allocator);
    s.printf("{%s, %p}", foo.x, foo.bar);
    return s.str();
}

static initialize
{
    io::formatter_register_type(Foo);
}

static initialize и static finalize это аналог паскалевским initialization/finalization, с возможными приоритетами:

import std::io;

fn void main()
{
    io::println("Hello, world!");
}

static initialize @priority(300)
{
    io::println("Hello startup2");
}

static initialize
{
    io::println("Let's start main...");
}

static initialize @priority(200)
{
    io::println("Hello startup");
}

static finalize
{
    puts("Bye bye");
}
dataman ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.