Martin Uecker <[email protected]> writes:

> Am Dienstag, dem 21.07.2026 um 20:34 +0200 schrieb Arsen Arsenović:
>> Hi Martin,
>> 
>> Martin Uecker <[email protected]> writes:
>> 
>> > you seem to take it for granted that it templates improve
>> > maintainability, but in my personal experience the opposite
>> > is true.
>> 
>> No, my hunch that the (currently pre-draft) proposal would improve
>> maintainability rests on the experience in the JavaScript and Python
>> cases, in both of which the introduction of gradual typing systems
>> massively increased the ability to detect bugs ahead of runtime,
>> approach new code, and modify old code.  It does not rest on the
>> presence of templates.
>> 
>> Templates are merely a required means by which a similar type system can
>> be implemented for GCCs 'tree', in GCCs implementation language - C++.
>
> So it *does* rest on the use of templates.

No, the idea that introducing gradual typing over trees could improve
maintainability does not presume templates.

An in-C++ implementation of such typing does, of course.

Alternatively, one could conceive of any number of GCC extensions to
implement the same out-of-language, like we did for the diagnostic
functions (__gcc_tdiag__ format style etc, but obviously substantially
more complex).

I'm not sure that'd be a better idea overall, though it would undeniably
be more ergonomic.  Probably also faster to compile.

> I am not sure.  Although C++ tries very hard, writing an abstraction
> using C++ templates is not the  same as improving a language itself,
> so I am not sure one can compare this to TS or Python.

I don't disagree.

> One would have to learn what it does, and this alone is another
> obstacle.  This is why when I encounter some new project, I much prefer 
> ancient C code compared to some modern C++ cod.e  The ancient C code may be
> horrible, but it is relatively easy to understand what it does,
> and then one can start to clean it up.
>
> For a C++ project, one has to first learn and understand all the fancy
> abstractions someone had cleverly introduced, and they are never
> the same, and when they are bad, it is often very painful to correct.
>
> You want to introduce such an abstraction. And I can appreciate how
> it would use of tree code more type safe.  I just do not think it is
> worth it in this form.

Hmm, I had hoped that it parallels tightly enough with existing concepts
(types in variable declarations, tree codes, and tree code classes) not
to require significant extra learning, especially when compared to the
work required to get used to "finding facts" about whatever 'tree' value
you happen to have on hand in a given context, for a new developer.

I think this also largely parallels the aforementioned dynamic
languages.

>> 
>> > Speaking for me, I would not be able to contribute anymore if build
>> > times triple.  It is already a pain today and I have fairly fast 
>> > machines available to me.  
>> 
>> I certainly wouldn't expect build times to triple from such a change ;)
>
> Well, this was a response to your comment.  

Yes, I understand, I wrote this to clarify that I don't actually expect
a 3x slowdown from a change like this.

> But just to give you one example how bad it can get, I recently removed as
> single cuda file with C++ templates from one of my projects, as this
> single file took as long to compile as the the other 450 c-files in
> the project. 

I have had similar experiences.  I once wrote a HTTP client using
Boost.Beast to give it a try and it took ~60 seconds to compile, if
memory serves right.

It may be more or less, but it was significantly more than any other
file in the codebase.

I'm well aware of how bad it can get, I'd hope that it doesn't get quite
that bad here (and would indeed abandon the effort if it does).

> Yes.  Also I think there would be cases where the code is not
> generic.  At least for the C FE a lot of functions work on only
> one kind of tree.

Same for the C++ one.  But of course there are those that don't (like
most of pt.cc for instance).

>> On readability: I'm not sure what you imagine, but there's no reason
>> readability ought to be an issue.
>> 
>> In each location where 'tree' is listed as a parameter or declared as a
>> local, one would also list the expected tree codes or similar, just as
>> they do today (except in the declaration instead of in an assert below a
>> declaration, which seems to me like a strict improvement, as it moves
>> relevant information from function bodies to function signatures,
>> without relying on bit-rotting comments; where there isn't such a check,
>> 'auto' suffices).
>
> An assertion also does not rely on comments.  The thing is that
> a function which works for three random tree codes is weird anyhow.
> Types should carry some useful semantics, and then they help
> readability when expressed explicitely.
>
> foo(tree< one_of<FUNCTION_DECL, PLUS_EXPR> > x)
>
> May be amazing technology, but just tells me the function should
> not exist in this form. So it only helps writing bad code.
>
> foo(expression *e)
>
> on the other hand, is very readable and would tell me something
> useful.

I do agree that the latter is preferable in a vacuum, I'm just not sure
it's applicable on the codebase today.  I think the former is preferable
to nothing (assuming it can be done in a way that's not completely
absurd to use of course).

This is where having a worked example would be a tie-breaker, so it is
very unfortunate that I don't have one at the moment.

>> Checks-and-uses of TREE_CODEs would also need to become (explicit)
>> fallible conversion functions, i.e.
>> 
>>   if (TREE_CODE (t) == A) use t;
>> 
>> ... becomes:
>> 
>>   if (auto tA = try_as_tree_or_whatever<A> (t)) use tA;
>> 
>> ... or such.  (I'd have preferred if the 'tA' could shadow 't', but
>> unfortunately if it were to shadow 't' in the then branch, it'd also
>> have to shadow it - a lot less usefully - in the else branch; that's not
>> an issue in this trivial example but is in general)
>
> Thi could look almost identical in C
>
> if (auto e = cast_down(expression, t))  ...
>
> if one wanted to.

I did not actually know that C permitted declarations in if-conditions.

>> A user-defined conversion template, at compile-time, knows the start and
>> end type, and ergo has sufficient information to implement custom typing
>> rules like those.
>
> I do not understand why the conversions need to be implicit.  I have
> C code with cast_down, cast_up macros, where cast_down checks the dynamic
> type.  

Both for sake of the existing code, and for cases where such a
conversion is clearly safe (much like how one can add 'const' to a
pointee type in C).

>> Indeed, considering 'variadic*' analogous to 'tree' in your example
>> would, in terms of type safety, be exactly equivalent to what we have
>> today (well, except that "variadic*" can be anything, and trees can
>> "only" be anything packaged in a tree node).
>
> Yes, the variadic would be correspond to a generic type such as tree. 
> But the point is that you can cast from/to a specific static type. 
> This is what I would call gradual typing.

I understood (and used) it to refer to a type system that permits the
slow introduction of type information and thus static type checking into
existing dynamic or duck-typed code.

This permits the codebase to undergo a slow process of "stricten-ing"
like described in
https://mypy.readthedocs.io/en/stable/existing_code.html

That page, of course, wouldn't apply 1-to-1 to 'tree' and GCC, but I'm
not sure if a more complete and general description exists anywhere.

I seemed to remember such a better description somewhere on the
TypeScript website, but I can't seem to find it now (they have a little
"Adopt TypeScript Gradually" sales pitch on their front page, but I
remember something less sales-y).

>> 
>> What I want is to be able to specify "okay, this 'variadic*' [or tree]
>> can only be X, Y or Z, or ..." in a declaration, and have the compiler
>> verify that as well as it can, while still being somewhat compatible
>> with existing code.  This serves the purpose of self-documentation and
>> type safety.  (note that we're going from "tree" -> "one of ... trees",
>> rather than going from a concrete type to a less specific one).
>
> The core feature you want to have is the  one_of<X, Y, Z> type,
> but I am not entirely sure why.

The reason I keep mentioning it is because it's the most general case
that exists in existing code (and which I can't imagine solving in C at
all).

It could well turn out, if I was to undergo the actual work, that it
becomes clear that it is unnecessary or at least not necessary
frequently enough to warrant its existence, and ergo the whole thing
becomes significantly simpler, but I tend to prefer thinking about the
most general case first.

Again, here some practice needs to take place to be a tie-breaker.

>> It'd be nice if I could, say, convert the C FE to what I'm imagining in
>> time for Cauldron, but I fear that may be optimistic.
>> 
>> Doing so would eliminate all ambiguities and perhaps even alleviate
>> concerns.
>
> Or the opposite. 
>
> I would rather convert the C FE to C, which would be a good idea
> for many reasons, including being more attractive to C programmers,
> but also to exercise language interoperability in GCC itself.

I can see the benefit of that, though I'd personally prefer if the GCC
codebase was to become more uniform, rather than less (even if that
uniformity isn't exactly how I'd like it), as that'd make it generally
easier for new developers.

(and, yes, I understand the irony of saying this in the middle of a
 thread suggesting specifically making the use of 'tree' less uniform
 throughout the codebase..  I'd hope it pays off in this case)

> I am fine with the implicit conversions C has as there
> is a sufficiently simple rule I learned once and that I can remember. 
> I am not too excited about programmer-defined implicit conversions.

That's understandable (though I do think the C ones are a touch too
lax).  Anything programmer-defined can quickly get out of hand.

But, simple, obvious and safe rules can be defined for cases like this.
-- 
Arsen Arsenović

Attachment: signature.asc
Description: PGP signature

Reply via email to