On 21/08/2021 11:32, James Harris wrote:
> On 20/08/2021 19:50, David Brown wrote:
>> On 20/08/2021 17:04, James Harris wrote:
>>>>> int 8 a
>>>>> int 16 b
>>>>> int 32 c
>>>> (I'd prefer some punctuation or other way of
>>>> connecting the number with the type)
>>> I'm surprised to hear that you would want additional punctuation. I tend
>>> to put a lot of effort into trying to make it unnecessary! For example,
>>> instead of C's
>>> if (e)
>>> I have just
>>> if e
>>> Isn't code easier to read without unnecessary punctuation?
>> No. /Excessive/ punctuation, or complicated symbols make code hard to
>> read, especially when rarely used. (So having something like ">>?" for
>> a "maximum" operator is a terrible idea.)
> Hm, I speak about "unnecessary" punctuation. You disagree and say the
> problem is "excessive" punctuation. What's the difference between
> unnecessary and excessive??
None of the punctuation in that paragraph was necessary - the meaning
would have been clear and unambiguous without any periods, apostrophes,
or quotation marks. Yet only the final double question mark was
excessive. It's a matter of degree. Too little punctuation makes the
language harder to read and write, and offers more scope for ambiguity.
Too much makes it hard to read and write, and makes it difficult to
learn. Somewhere in the middle there is a happy medium - going too far
one way (limiting punctuation to the minimum necessary) is as bad as
going too far the other way (excessive punctuation that detracts from
the flow of the code).
>>>> * Could the number be an expression?
>>> Yes, as long as it was resolvable at compile time. If the width were to
>>> be specified by an expression, E, then the syntax would be
>>> int (E) d
>> I'd recommend looking at C++ templates. You might not want to follow
>> all the details of the syntax, and you want to look at the newer and
>> better techniques rather than the old ones. But pick a way to give
>> compile-time parameters to types, and then use that - don't faff around
>> with special cases and limited options. Pick one good method, then you
>> could have something like this :
>> builtin::int<32> x;
>> using int32 = builtin::int<32>;
>> int32 y;
>> That is (IMHO) much better than your version because it will be
>> unambiguous, flexible, and follows a syntax that you can use for all
>> sorts of features.
> My version of that would be
> typedef i32 = int 32
> int 32 x
> i32 y
Punctuation here is not /necessary/, but it would make the code far
easier to read, and far safer (in that mistakes are more likely to be
seen by the compiler rather than being valid code with unintended meaning).
> Your C++ version doesn't seem to be any more precise or flexible.
What happens when you have a type that should have two parameters - size
and alignment, for example? Or additional non-integer parameters such
as signedness or overflow behaviour? Or for container types with other
types as parameters? C++ has that all covered in a clear and accurate
manner - your system does not.
My intention here is to encourage you to think bigger. Stop thinking
"how do I make integer types?" - think wider and with greater generality
and ambition. Make a good general, flexible system of types, and then
let your integer types fall naturally out of that.
> And my
> version is shorter, clearer and (at least once you are used to the
> syntax) easier to read.
"Shorter" is /not/ an advantage, any more than "longer" is an advantage.
> In fact, mine is so much more readable that it
> shows how weird it looks to use both int 32 and i32 - something that IMO
> the C++ version obscures by lots of unnecessary (your term) waffle text!
> So I am not sure what your criticism is.
It doesn't really matter if you decide that "int32", "int32_t", "i32",
or anything else is going to be the normal way to declare a 32-bit
integer. You have to figure out what you think makes sense and reads
well in your language. But the syntax I suggested for defining the type
is not "waffle" - it is intention. You don't want this sort of thing to
be short - you want it to be consistent and logical, unambiguous in
syntax, and not conflict with identifiers the programmer might want.
> I do agree, however, that I need to look at templates. Are C++
> templates, as set out in
> essentially just about parametrising functions and classes where the
> parameters are types and other classes?
> Or are they more flexible?
A limited tutorial on a 20+ year old version of the language is not
going to be the best reference. This is a /much/ better site for C++
(and C) information, and works closely with the language standardisation
It's not a tutorial site, however. It aims to be accurate to the
standards but gives a more reader-friendly format than the standards,
and is excellent at noting the differences between different standards
Originally, templates were just about functions and classes parametrised
by types. They let you make a "max" function that would work for any
type with a " > " operator, or a list container class that could work
for any type. But they moved on from that. They also include template
aliases, variables, and concepts (which are a way of naming
characteristics of types - a sort of "type of type", except they use
duck-typing instead of structural typing). As well as types, template
parameters can be integers, enumerators, and now pretty much any
"literal" class. For a while, C++ templates were used for compile-time
calculations in C++, but that was an awkward process - the syntax was
seriously ugly and they were limited and inefficient. (Now you use
proper compile-time functions.)
Make sure you look at C++20 for inspiration, not ancient C++98. Look at
concepts - they greatly simplify templates and generic programming.
(They are not the only way to do it - remember that a lot of the way
things are done in an old, evolved language like C++ come from adding
features while retaining backwards compatibility - for a new language,
you don't need to do that, and can jump straight to better designs. You
are looking for inspiration and ideas to copy, not copying all the
weaker parts of older languages.)
Perhaps even look at the metaclasses proposal
This will not be in C++ before C++26, maybe even later, but it gives a
whole new way of building code. If metaclasses had been part of C++
from the beginning, there would be no struct, class, enum, or union in
the language - these would have been standard library metaclasses. They
are /that/ flexible.
> I ask that because I wonder if something based on macros (where the
> parameters could be of any form, not just types and classes) could be as
> useful but more adaptable to different situations. After all, the
> creation of real functions from templated functions is rather like the
> instantiation of macros, isn't it?
To some extent, yes - but it is done in a clearer, cleaner and more
Pure textual macros, like C's, have lots of limitations (no recursion is
a critical limitation) - as well as being too chaotic because there are
But there are other languages with other kinds of macros, with different
possibilities. There are some languages were features like loop
structures are not keywords or fundamental language statements, but just
macros from the standard library.
Ultimately, things like macros, templates, generics, metafunctions,
etc., are just names for high-level compile-time coding constructs.
>> If you want more fun, you could make types first-class objects of your
>> language. Then you could have a function "int" that takes a single
>> number as a parameter and returns a type. Then you'd have :
>> int(32) x;
>> type int32 = int(32);
>> int32 y;
> Are you talking there about a dynamic language where int is called at
> run time?
No - "int" would be a compile-time function here.