Closed lerno closed 2 years ago
The thing is that sizeof isn't really a function, but rather an operator, that may (depending on your formatting) look like a function. I am more inclined to promoting the usage of sizeof
like this, even for types:
size_t foo = sizeof a;
size_t bar = sizeof my_type;
Since we know that in C, when using sizeof
, types need to have parentheses and symbols can have parentheses, we can just translate those two to this in C:
size_t foo = sizeof (a);
size_t bar = sizeof (my_type);
As a rule of thumb, the parenthesis belong to the argument and not sizeof
, so there should be a space inbetween for better clarity
The downside of spaces in general is that it adds ambiguity to precedence rules. If it looks like a function call then we can rely on it having the precedence of a function call. My problem with C’s cast operator is exactly that it is hard to figure out this precedence.
The second point is polluting the global keyword space. There are more compile time functions needed for macros. It would be good if they are distinct.
I see, what about sticking in a bang and doing it Rust-like like this:
size_t foo = sizeof!(a);
size_t bar = sizeof!(my_type);
That way, we don't have to introduce extra special characters and we can call all these intrinsic macros. It will make it visible, that these compile time functions are macro related and they won't lose visible precendence.
To clarify, I am talking in reference to the macro concept I and @bvdberg made two years ago in bb_macro_tests, which has macros use bangs to differentiate from function calls, if you haven't seen it already @lerno
I read the bang as "here comes an exception". I'm not a fan of it when reading Rust code either. In Ruby it's used for methods that alter the underlying object, so "foo.sort()" returns a sorted foo, while "foo.sort!()" sorts the foo in place.
I would prefer a prefix exactly because it's possible to visually parse them as something macro expandable up front. "@" is the one I think is the least used for other purposes in other languages, but anything unused, such like # or $ would work equally well. Obviously any prefix need to avoid any operator. The suffix opens up for more alternatives, but I'd still argue that prefix is easier to read.
foo = @bar(12);
foo = #bar(12);
foo = 'bar(12);
foo = bar@(12);
foo = bar#(12);
foo = bar!(12);
foo = bar:(12);
foo = bar?(12);
foo = bar'(12);
Scanning quickly bar!
can look like barl
or similar.
I see, I don't know Ruby, so I don't have the association, sorry. I only have associations with ?
as nullable type and single '
gives me anxiety and reminds me of lifetimes in Rust and generics in OCaml. :smile:
I don't think that prefix vs suffix means that much of a significant difference in code, especially with shorter identifiers like these ones. I'd argue that all that matters is if the editor can just colorcode macros differently based on that extra characters.
So yeah, It doesn't matter that much which character, so long as there is one. Remember, in C, editors can only guess if its a macro based on ALLCAPS casing, but one can't be sure, whereas a character is definitive.
Nevertheless, I stand by my point and I would like to throw in another one. The bang is easier to type. I can tell you that on many slavic keywords, we have special characters on the numeric row and @
, #
and $
are a pain in the ass to type. Meanwhile, I have never heard of latin script language that would have !
unavaiĺable firsthand.
I realize the issue with keyboards, but that's not really a valid thing since most languages have "bad" characters like that. Characters more or less painful to type for swedish: \ [] | $. One would expect people to be used to typing @ since it's very frequently used.
$ is a variable prefix in several languages (Perl, PHP). Shows up as parameter names too, so the association is poor. For Objective-C we have @ that prefix its keywords that differentiate it from C.
Extensions to C generally uses __ to introduce new syntax-like things. C++ adds the [[ ]] for annotations.
I would expect it would be easy to write as well, sadly keyboard makers didn't think slavs needed to write @ :smile: . Yea, sadly in C2, we already have @
used for attributes, which would make it more confusing for beginners and harder to process for syntax highlighters (since you can't differentiate macro from an attribute that easily anymore, when they share the same special charwecter)
I would think the other way.. since @ is already used for attributes, it's smart to reuse it since it already means "compile time something". The attributes are @( ... ) and the macros are @...( )
That said, I would prefer something better than @, it's just that I think the postfix "!" is so much worse... (or any postfix for that matter)
For me "@" reminds me a bit of something unfolding, consequently I think it looks reasonable. Jai uses # directives instead. This is (to me) a possible replacement for @(...) attributes, which I do think look excellent as they are. If swapped then directives should be #... and not @(...)
func i32 foo @(inline) {
}
func i32 foo #inline {
}
Both are fine to me visually. With values, then #something(30)
or #something=30
both works, although I prefer the former.
Unpacking macros with #foo();
is not great but can be lived with. In the macros proposal I sent to @bvdberg I then use $ as prefix for compile time variables.
Going more into other languages' territories we get
[[foo()]]
${foo}()
${foo()}
<foo()>
%%foo()
%%foo()%%
#foo()#
{$foo()}
macro::foo()
$::foo()
%:foo()
#[foo()]
Etc.
Not that I recommend those.
@bvdberg Any thoughts on this yet?
I've raised this in the forum and it needs some resolution I think as it affects syntax and parsing quite a bit:
Currently compile time functions, such as sizeof has no prefix. I've always found sizeof a bit confusing since it clearly looks like a normal function but isn't. Now, if we add semantic macros and more compile time functionality, it seems like we should not pollute the global namespace with a huge amount of keywords. Consequently I'd like a separate namespace for macros, and I suggest those start with "@".
Consequently it's @sizeof, @typeof etc. Semantic macros would then share the same namespace so @my_macro(....) when expanding a macro. Where the "@" should be thought of as "macro expansion starts here"
Alternatively we use "#" or even "$", but for # it's more associated with line based macro handling, so it might feel weird and confusing:
There also needs to be a guideline when to use the prefix. For example, consider a defer that is possible to write inline:
Here defer both would act as a keyword and as an attribute macro.
Using @ttributes and keywords, the examples would look like this I suppose:
I'd like to be able to separate attributes that work like compiler directives from constructs that work like actual macros, transforming the actual meaning of the code. That's why I prefer the former version.
Note that the above does not need to be decided right away. For the current state of C2, the only thing that needs a decision is really whether sizeof should have a @ prefix or not, and if this keyword should be common to all compile time functions.