c3c icon indicating copy to clipboard operation
c3c copied to clipboard

The big list of complaints

Open lerno opened this issue 2 months ago • 15 comments

Inevitably, a language will have certain rough edges. Places where the language could be better but isn't due to some trade off.

But there are also rough edges where it's quite unnecessary to have them. For example, compare D and C++ where their functionality is the same, and note how often D manages the same functionality will simpler syntax and less special cases. This is demonstrating that functionality itself doesn't need to always dictate how ergonomic and nice a feature feels.

The point of this issue is to vent. Complain about features in C3 (not bugs, they are handled elsewhere 😄), where they cause inconvenience or simply feel too rough and unfinished.

A helpful way to think about this might be "If I wrote a clone of C3, what would I fix?". The answer to that question reveals a lot about what feels inconvenient and rough.

Obviously, C3 won't change into a completely different language, but it's still useful to hear grievances. So here are the rules:

  1. Describe what's bad and why.
  2. Describe how would you like it to work (writing an fictional code snippet is great!)
  3. Let me know how long you've been using C3.

The last one is not to weed out suggestions, but rather to determine at what point in development people feel the pain from this. Is it when evaluating it, while trying to learn it, or after coding a lot in the language?

Finally, this is no replacement for a regular issue. If something is serious enough that you think it really should be fixed, file a normal issue.

lerno avatar Oct 14 '25 11:10 lerno

temp_ls or tls should be added to std::io::path tls is confusing so I think temp_ls makes more sense (would also need to use that as a standard for temp functions)

allenyade avatar Oct 15 '25 11:10 allenyade

There is a bit unpleasance to use usual array types like int[10] when transfer it via pointer.

There something like alias MyArray100 = int[100] in my project. I prefer to bypass MyArray100 onto function by a pointer MyArray100* my_array because it is a large data. But then it is impossible to just use my_array[index] because you firstly have to derefference it. Aways doing such a derefferece is a bit annoying.

EroMrinin134 avatar Oct 16 '25 13:10 EroMrinin134

temp_ls or tls should be added to std::io::path tls is confusing so I think temp_ls makes more sense (would also need to use that as a standard for temp functions)

I guess, whole naming shoud be checked for consistency to the 1.0 release.

EroMrinin134 avatar Oct 16 '25 13:10 EroMrinin134

As I see, new contributors are using macros instead of functions more and more often. So a resulting binary file is getting bigger and bigger. I don't know the best way to solve it. It could be a new attribute for macros, or a new compiler switch for converting macros to functions...

data-man avatar Oct 25 '25 14:10 data-man

In general macros should be fewer because they are worse for ABI compatibility.

lerno avatar Oct 25 '25 16:10 lerno

There should be a is_comparable_type($Type) macro just like is_equatable_type($Type), which already exists. I've been using @comparable_value((T){}) as a workaround for the @requires of a generic red-black tree module and using this workaround breaks pointer-type keys, as the compiler will not allow the necessary deref of a known-null (T){} pointer when the macro checks for the less and compare_to functions.

patroclos avatar Nov 08 '25 15:11 patroclos

As I see, new contributors are using macros instead of functions more and more often. So a resulting binary file is getting bigger and bigger. I don't know the best way to solve it. It could be a new attribute for macros, or a new compiler switch for converting macros to functions...

In general, lots of C3 code I have seen uses macros where I would instead have used functions from a C perspective.

any1here avatar Nov 09 '25 13:11 any1here

@patroclos doesn't $defined(a < a) work?

lerno avatar Nov 20 '25 13:11 lerno

File an issue for that, because it seems like an omission.

lerno avatar Nov 20 '25 13:11 lerno

Multi-dimensional arrays are indexed in a different order to their assignment. It wouldn't be a problem if they were different to C but defined and accessed consistently but they are not and that's quite confusing. https://c3-lang.org/language-common/arrays/#fixed-size-multi-dimensional-arrays

joshring avatar Nov 25 '25 09:11 joshring

Multi-dimensional arrays are indexed in a different order to their assignment. It wouldn't be a problem if they were different to C but defined and accessed consistently but they are not and that's quite confusing. https://c3-lang.org/language-common/arrays/#fixed-size-multi-dimensional-arrays

Wouldn't the other order mess up more complex types like int[<2>][4]* ? - it'll become int*[4][<2>]... I'm not sure if it's better...

EroMrinin134 avatar Nov 26 '25 04:11 EroMrinin134

I don't see why you have removed "goto". If you want to be a sucesor of C, you should try to keep it as compatible with C as possible!

pdenapo avatar Dec 01 '25 14:12 pdenapo

I don't see why you have removed "goto". If you want to be a sucesor of C, you should try to keep it as compatible with C as possible!

goto makes some of the new features in C3 more complex. for example optionals allow this:

int? x = possibly_failing_function();
if (catch err = x)
{
  log::error("possibly_failing_function failed with reason %s", err);
  return 1;
}
// x is now no-longer optional because this code cannot be reached when it is an error
int y = x + 1;

while if you have goto it might not work without significantly more static analysis:

int? x = possibly_failing_function();
if (something_else()) goto some_label;
if (catch err = x)
{
  log::error("possibly_failing_function failed with reason %s", err);
  return 1;
}
some_label:
int y = x + 1;  // because you can `goto` here before the optional is checked it may not be safe to access `x`, and the compiler would have to check this for every possible goto and label which is a lot more complex

there are also similar problems with goto and defer

there are multiple alternatives to goto in C3 as well something like this (example from the c3 website):

Foo *foo = malloc(sizeof(Foo));

if (tryFoo(foo)) goto FAIL;
if (modifyFoo(foo)) goto FAIL;

free(foo);
return true;

FAIL:
free(foo);
return false;

can be translated to both this:

do FAIL:
{
    Foo* foo = malloc(Foo.sizeof);

    if (tryFoo(foo)) break FAIL;
    if (modifyFoo(foo)) break FAIL;

    free(foo);
    return true;
};
free(foo);
return false;

and this:

Foo* foo = mem::new(Foo);
defer free(foo);

if (tryFoo(foo)) return false;
if (modifyFoo(foo)) return false;

return true;

you can also use switch as a jump table to emulate things like state machines without goto:

switch (foo) @jump // @jump just forces the compiler to emit this as a jump table, it may not always be faster
{
  case FOO:
    ...
   nextcase BAR;
  case BAR:
    ...
    if (x) { foo = FOO; }
    else { foo = BAZ; }
    nextcase foo;
  case BAZ:
    ...
    nextcase FOO;
}

Book-reader avatar Dec 02 '25 23:12 Book-reader

Even though it is pretty small, I think requirement of fn for functions bothers me a bit. It is nice for lambdas, but named functions can probably be parsed without any ambiguity with the current token rules, and needing fn makes the code less C-like. The struct literals have evolved into being more C-like, so maybe functions can also evolve so. There was a similar discussion in 2021 #144, where the func keyword (the precursor of fn, I suppose) was considered to be removed, but it was decided to be kept for now. The same issue also discusses operator overloading, and now we have operator overloading in C3. At least (re)discussing the fn keyword would be nice.

erenjanje avatar Dec 04 '25 10:12 erenjanje

I find the basic integer type names a bit confusing when comming from C. There is int vs. uint or short vs. ushort but then ichar vs. char having opposite meaning in C and C3.

I prefer using the fixed width integer types such as int16_t, uint32_t, etc. over short, unsigned and so on. I would propose using integer types i8, u8, i16, u16, etc. and even the floating point types f16, f32 and f64.

I've been using C3 for a few weeks now still evaluating and trying to learn it.

alkuna avatar Dec 04 '25 12:12 alkuna

With all my respect,I love c3. Sorry I don't know the underline considerations on the language design or parser/implementation on below changes from C,I just want to say:

  1. scope resovers :: why this is a mandatory requirement other than an option just like c++.So many :: in a page in the source file looks a bit boring.
  2. array row major/column major,why there is a change from C,isn't better to just keep as it in C;
  3. array declare convention: why int[] arr other than int arr[] ,just keep as it in C,so one can @import a image file sample.xpm just as in c/c++ #include "sample.xpm".

LukyGuyLucky avatar Dec 18 '25 02:12 LukyGuyLucky