
C for All - etrevino
https://plg.uwaterloo.ca/~cforall/
======
zestyping
There are a lot of features thrown into this language that don't seem worth
the learning costs they incur. What are the problems you're really trying to
fix? Focus on the things that are really important and impactful, and solve
them; don't waste time on quirky features that just make the syntax more alien
to C programmers.

* `if` / `case` / `choose` improvements look fine, though not that important.

* Exception handling semantics aren't defined.

* `with` is pointless and adds gratuitous complexity to the language.

* `fallthrough` / `fallthru` / `break` / `continue` are all just aliases for `goto`. It's not obvious to me that we really need them.

* Returnable tuples look very nice.

* Alternative declaration syntax looks like a nightmare. If we were redesigning C from the ground up, a different declaration syntax might be better, but mixing two syntaxes is a terrible, terrible idea.

* References. Why? They only add confusion.

* Can't make head or tail of what `zero_t` and `one_t` are about, or why they would be useful.

* Units (call with backquote): gratuitous syntax, unnecessary and confusing.

* Exponentiation operator: gratuitous and unnecessary.

~~~
emilfihlman
Exponentiation operator gratuitous and unnecessary?

WHAT?

~~~
kragen
It doesn't improve readability. Compare:

    
    
       discrim = b² - 4ac;                  // Standard notation
       float discrim = pow(b, 2) - 4*a*c;   // C
       float discrim = b \ 2 - 4*a*c;       // C∀
    

I would argue that these are presented here in descending order of
readability.

Also its typing rules are really complicated; apply it to two integers and
magically you are thrown into the floating-point world where you can never be
completely certain of anything, but if you use an unsigned exponent then you
stay safely in integer-land.

~~~
dom96
The choice of operator seems very odd to me. Wouldn't `^` be significantly
more readable?

~~~
userbinator
^ is already used for bitwise xor.

~~~
earenndil
What about __then, like some other languages?

~~~
Amelorate
Python uses * * _, but that is ambigous with

    
    
      int a = 1;
      int *b = &a;
      int c = a ** b;
      // Am I casting b to an int (returning it's address) and exponenting it or am I derefrencing b and multiplying it's result with a?

~~~
userbinator
I suppose ^^ might work, although a little odd because by consistency it would
otherwise be the "logical XOR", a mythical operator that doesn't actually make
much sense.

~~~
poizan42
> a mythical operator that doesn't actually make much sense.

Hmm I'm pretty sure practically every programming languages have it. It
usually looks like "!=" or "<>".

The even more obscure logical XNOR is usually denoted "==" or "="

~~~
kazagistar
Alas, this doesn't deal with the idea of truthyness as a proper logocal XOR
would, so it is incorrect in many of the most popular languages, including C,
where a value that is true is not always equal to another value that is true.
This only works in the much more strongly typed languages, or when you force
cast both sides to a boolean with something like !!

------
vanderZwan
It looks like most people here are so eager to jump on the _" this feature is
good, this sucks, overal I'm not impressed"_-bandwagon (with the typically
unwarranted strong opinions that programmers always have when it comes to
this) that they didn't bother to explore the rest of the website in more
detail. Go to "people" page and you see that it's a language implemented by
professors, PhDs and master students from the Programming Language group at
Waterloo[0][1]. Scroll down and you'll see that a number of these features
came from the master thesis of a student:

    
    
        Alumni
        Ph.D.
        
        Glen Ditchfield, 1992
            Thesis title: Contextual Polymorphism
        
        Masters
        
        Thierry Delisle, 2018.
            Thesis title: Concurrency in C∀.
        Rob Schluntz, 2017.
            Thesis title: Resource Management and Tuples in C∀.
        Rodolfo Gabriel Esteves, 2004.
            Thesis title: Cforall, a Study in Evolutionary Design in Programming Languages.
        Richard Bilson, 2003
            Thesis title: Implementing Overloading and Polymorphism in Cforall
        David W. Till, 1989
            Thesis title: Tuples In Imperative Programming Languages.
        
        USRA
        
        Andrew Beach, Spring 2017.
            Line numbering, Exception handling, Virtuals 
    

So basically, it's a research language, more-or-less developed one student at
a time.

[0]
[https://plg.uwaterloo.ca/~cforall/people](https://plg.uwaterloo.ca/~cforall/people)

[1] [https://plg.uwaterloo.ca/](https://plg.uwaterloo.ca/)

------
enriquto
I'm all for the evolution of C, but this list...

1) has some downright idiotic things (exceptions, operator overloading)

2) has a few reasonable, but mostly inconsequential things (declaration inside
if, case ranges)

3) is missing a few real improvements (closures, although it is not clear
whether the "nested routines" can be returned)

~~~
pmarreck
Can you explain why exceptions and operator overloading are "idiotic" things?
Are you from the Go school of boilerplate-error-checking-code design, or
something?

~~~
UncleMeat
Exceptions work great in garbage collected languages. Reasoning about
exceptional control flow w.r.t. manual memory management is a total nightmare.

~~~
sedachv
> Reasoning about exceptional control flow w.r.t. manual memory management is
> a total nightmare.

Exceptions make manual memory management easier because a proper exception
system has _unwind-protect_ [1]. Exceptions are just movements up the stack -
exceptions combine naturally with dynamic scoping for memory allocation
(memory regions/pools). This kind of memory management was used in some Lisp
systems in the 1980s, and made its way into C++ in the form of RAII. By
extending the compiler you can add further memory management conveniences like
smart pointers to this scheme.

Now if you want to talk about something that actually makes manual memory
management a total nightmare, look at the OP's suggestion for adding closures
to C.

[1]
[http://www.lispworks.com/documentation/HyperSpec/Body/s_unwi...](http://www.lispworks.com/documentation/HyperSpec/Body/s_unwind.htm)

~~~
tomsmeding
C does not have RAII-like memory management in _any_ way. Exceptions work
beautifully with memory management like that, but if it's not there, you can't
just say it should work because memory management should work like that.

So basically you're saying, before adding exceptions, add RAII-like memory
management, and then actually add exceptions. I like both features, but am not
sure how you'd wedge RAII into C. Any ideas on that?

~~~
BruceIV
[On the Cforall team] For what it's worth, one of the features Cforall adds to
C is RAII.

The exception implementation isn't done yet, but it's waiting on (limited)
run-time type information, it already respects RAII.

~~~
RhysU
I have often wanted c99 with destructors for RAII purposes.

~~~
enriquto
you do not need destructors if you put your stuff on the stack

~~~
jcelerier
just putting stuff on the stack in C won't magically call `fclose` or
`pthread_mutex_unlock`, unlike destructors

------
Dinux
This has been tried many times before, and eventually all these attempts die a
lonely death. Why use extensions anyway? If one desired the luxury of modern
scripting languages, switch to C++, Rust, Go or one of the other alternatives
the article mentions.

~~~
pjmlp
Because regardless how some of us might dislike C and its security related
issues, the truth is that no one is ever going to rewrite UNIX systems in
other language, nor the embedded systems where even C++ has issues gaining
market share.

So if one finally manages to get a safer C variant that finally wins the
hearts of UNIX kernels and embedded devs, it is a win for all, even those that
don't care about C on their daily work.

Until it happens, that lower layer all IoT devices and cloud machines will be
kept in C, and not all of them will be getting security updates.

~~~
kerkeslager
What makes you think that a safer C variant would win the hearts of UNIX
kernels and embedded devs any more than C++ (which started as just a C
variant).

~~~
pjmlp
Because most UNIX kernel devs are religiously against the idea of ever
touching C++, even if their beloved C compilers are implemented in C++.

~~~
pcwalton
I highly suspect it's not that Unix C diehards are against the idea of
touching C++—it's that they're against the idea of _using anything but C_. I
don't think anything can win over those kernel developers.

~~~
nwmcsween
Its the complexity of the language vs the benefits it provides. C has many
pitfalls (UB) but its simple. IMO a language that could migrate C programmers
would have dependent types and an effect system with a nice syntax.

~~~
noam87
Idris?

It can compile small enough to run on an Arduino:
[https://github.com/stepcut/idris-blink](https://github.com/stepcut/idris-
blink)

------
naasking
Looks pretty ambitious. My take from skimming:

* switch, if, choose and case extensions look good.

* I can see the justification for labelled break/continue, but looks pretty hairy. Might discourage rethinking and refactoring to something simpler.

* I'm wary of exceptions.

* I don't like the 'with' clauses.

* Weird to add syntax just for mutexes, but they integrate concurrency/coroutines later, so maybe it make sense.

* Tuples are generally useful, but C11's unnamed structs are generally good enough, ie. instead of [int, char] you can return "struct { int x0; char x1 }" or something.

* New declaration syntax is welcome, but the old syntax probably isn't going away, so I'm not sure it's a good idea.

* Constructors/destructors are good. Syntax looks weird though.

* Overloading is very welcome.

* Not sure about operators, but they have their uses.

* Polymorphism is welcome, though it looks a bit cumbersome, and it should come with a monomorphisation guarantee for C.

* Traits seem like too much for a C-like language. I can see the uses, and the compiler can optimize this well, but they're probably too powerful.

* Coroutines are cool.

* Streams look interesting, but the overloading of | will probably be confusing.

~~~
DSMan195276
I'm more or less in agreement, but I just though it was worth adding that the
tuple's could actually have a lot of merit, I think I'd like to see them
(Though I'm not sure the syntax is perfect parsing wise. It might be smart to
prefix them, like `tuple [int, char]` or something.).

It seems like anonymous struct's fill the void, but a big problem with
anonymous struct's is their types are never equal to any other, even if all
the members are the exact same. So that means that if you declare the function
as returning `struct { int x0; char x1; }` directly, it's actually mostly
unusable because it's impossible to actually declare a variable with the same
type as the return type. Obviously, the fix is to forward declare the `struct`
ahead of time in a header file somewhere and then just use that type name, but
that gets annoying really fast when you end-up with a lot of them. The tuples
would allow you to achieve the same thing, but with a less verbose syntax and
would allow them to be considered the same type even without forward declaring
them.

~~~
naasking
> So that means that if you declare the function as returning `struct { int
> x0; char x1; }` directly, it's actually mostly unusable because it's
> impossible to actually declare a variable with the same type as the return
> type.

Are you sure about that? I remember playing with this last year and structural
equality seemed to work when returning structures from functions. I was using
clang, so it could conceivably have been an extension... (edit: some online C
compilers do indeed return an error in this case)

If that's the case, then just make anonymous structs employ structural type
equality and you have better tuples.

~~~
DSMan195276
`gcc` definitely throws an error. It tells you something like "struct
<anonymous> was expected but struct <anonymous> was found". It's a pretty
fantastic error message /s

> If that's the case, then just make anonymous structs employ structural type
> equality and you have better tuples.

Yeah, that would work, I'd be fine with that. I don't think it's _quite_ as
good as a dedicated syntax though, just because the `struct` syntax is a lot
more verbose then a concise tuple syntax could be, and defining `struct`s
inline is pretty clumsy.

~~~
naasking
Yes it's more verbose, but avoids adding new primitive to the language for
something that is probably not too common. I'm also not a fan of tuples
because the fields aren't named. I mean, which field in a return type of [int,
int] do I want exactly?

At least anonymous structs would name the fields and so the type serves also
as documentation.

------
castratikron
GNU C is probably my favorite extension of C. There's a lot of good stuff in
there. The vector extensions make it really easy to write platform agnostic
SIMD code.

[https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html](https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html)

~~~
Sir_Cmpwn
Please don't use GNU C, or any other non-standardized version of C. A huge
part of the reason C that is so widespread is because it's a well defined
standard implemented by many compilers for many platforms. GNU C is defined by
its implementation, which is awful.

~~~
pcwalton
Please _do_ use GNU C if you're going to use C. The viral nature of the Linux
kernel has forced GNU C to be an important _de facto_ standard. Take advantage
of that!

~~~
pjmlp
Google has taken the effort to make Linux compile with clang, as part of their
efforts to wipe gcc from Android toolchain.

There is a LLVM talk about it.

However I do agree with you.

clang and gcc cover most of the systems that matter today and their C
extensions definitely make C a safer language.

------
hsivonen
Considering how hard it is to write truly exception-safe C++ and considering
how major C++ code bases don't allow exceptions, adding exceptions to C does
not seem like a good idea.

~~~
jcelerier
> Considering how hard it is to write truly exception-safe C++

Is "writing truly exception-safe" something that necessary ? for me, the
biggest benefit of exceptions is that I can have some code throw from anywhere
and display a nice error pop-up message to my user which informs me of what
went wrong and revert what was currently happening during the processing of
the current event, since the "top-level" event loop is wrapped in a try-catch
block. Often enough, the user can then just resume doing whatever he was
working on.

~~~
humanrebar
> Is "writing truly exception-safe" something that necessary?

If you want your connections cleanly terminated, your temporary files removed,
and your database transactions invalidated, yes.

~~~
jcelerier
> If you want your connections cleanly terminated, your temporary files
> removed, and your database transactions invalidated, yes.

sure, and if you develop in C++ and put these in RAII classes they will be
automatically.

~~~
humanrebar
Because they're exception safe. But it's also possible to use them in an
exception unsafe way.

~~~
jcelerier
well, that's what I don't understand with OP's

> Considering how hard it is to write truly exception-safe C++

that's the _default_ behaviour in C++ code, how hard can it be ?

~~~
yongjik
Exception safety is hardly a "default behavior" of C++, considering such
gems[1] as:

    
    
        // This is unsafe.
        sink( unique_ptr<widget>{new widget{}},
              unique_ptr<gadget>{new gadget{}} );
    
        // This is safe.
        sink( make_unique<widget>(), make_unique<gadget>() );
    

[1] [https://herbsutter.com/2013/05/29/gotw-89-solution-smart-
poi...](https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/)

------
jessaustin
_Without continued development of the language, C will be unable to cope with
the needs of modern programming problems and programmers; as a result, it will
fade into disuse._

C11 is pretty nice! C99 is too. One might think that "almost once a decade" is
kind of slow for updates, but M$ have enough trouble keeping up with the
current schedule. Of course TFA describes a possible direction for C2 _x_ ,
but they could have a more charitable attitude...

~~~
pjmlp
Microsoft does not have any trouble keeping up with C, C++ and .NET Native are
the future of systems programming on Windows.

C compatibility is kept to the extent of ANSI C++ requirements.

ANSI C++14 requires C99 library compatibility and ANSI C++17 was updated for
C11 library compatibility.

[http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0063r2....](http://open-
std.org/JTC1/SC22/WG21/docs/papers/2016/p0063r2.html)

~~~
insulanus
Herb Sutter doesn't like C. That may be the reason that the compiler group at
Microsoft don't put any effort into updating the C compiler to support newer
features.

They do put a great deal of work into the C++ compiler, and seem to be doing a
way, way, better job than they were in the late 90s.

That may be the other reason they don't update the C compiler with new
features.

~~~
pjmlp
The reason is official and has been communicated many times.

C related improvements will only be done to the extent required by ANSI C++,
or requests from key customers that might influence roadmap.

Anyone that really deeply wants to keep using C on Windows, and even enjoys
using COM directly from C (the main ABI since Windows 7 and UWP core stack),
can use any other C compiler.

In fact Microsoft has suggested clang multiple times, and has helped clang
devs to make it work better on Windows.

------
quelsolaar
This is the wrong way to go about it. The syntax is great, what is needed is
updates to reflect modern hardware:

-Vector types. (With arbitrary sizes not just up to vec4 for like on GPUs)

-New operators like clamp, and other intrinsic. (See GLSL and modern instruction sets)

-Min/max: |< >|

-Dot: __

-Cross product: ><

-Swizzle: a.3.2.1.0

-Qualifiers for warping behavior.

-Standard library with cash management hints.

-Define qualifiers for padding of structs to be defined.

I would also argue you could change some things in the spec to make it easier
for compilers to optimize, like making the calling a switch without a catching
case undefined behavior.

As for the syntax itself, I could find being able to type multiple break
commands in a row to get out of more then one loop useful, but its not a big
thing.

I would probably drastically restrict the power of the pre-processor too.

(If you have too much time on your hands:
[https://www.youtube.com/watch?v=443UNeGrFoM](https://www.youtube.com/watch?v=443UNeGrFoM))

------
karlding
Peter Buhr also teaches CS 343: Concurrent and Parallel Programming [0] at the
University of Waterloo in a dialect of C++ that he has been working on [1],
called uC++ [2].

[0]
[https://www.student.cs.uwaterloo.ca/~cs343/](https://www.student.cs.uwaterloo.ca/~cs343/)

[1] [https://github.com/pabuhr/uCPP](https://github.com/pabuhr/uCPP)

[2]
[https://en.wikipedia.org/wiki/%CE%9CC%2B%2B](https://en.wikipedia.org/wiki/%CE%9CC%2B%2B)

~~~
BruceIV
[on the Cforall team] One of our Master's students has incorporated the
majority of the uC++ features into Cforall as well, with some neat extensions
for multi-monitor locking in a way that doesn't introduce synchronization
deadlocks not present in user code.

~~~
filereaper
As an alumni, I firmly believe there's room for a 4th year course in-addition
to CS343. There's quite a lot in advanced control flow which can be covered.

I've always found it unfortunate that the university has courses from first
year all the way to fourth year in Data Structures and Algorithms (all the way
up to CS466/CS666) but Control Flow is treated like a secondary citizen.

~~~
BruceIV
[also a CS 343 TA] I personally agree with you -- if it were up to me I'd
refactor CS 343 into a pair of courses, maybe focusing on high-level
concurrency constructs with a follow-up course on building that sort of
runtime system.

~~~
zodiac
I personally really hated the use of uC++ and would have loved to do the whole
course in some MIPS dialect. I really liked how through most of second year
the only language reference I really needed to look at fit on one piece of
paper
([https://www.student.cs.uwaterloo.ca/~cs241/mips/mipsref.pdf](https://www.student.cs.uwaterloo.ca/~cs241/mips/mipsref.pdf)).
The uC++ language, on the other hand, is not specified anywhere except in the
enormous 600 page textbook, and even then very far from fully specified (e.g.
there was a builtin function called rendezvous-something, where that string
literally only appeared in the book once, and it was not defined at that
place)

~~~
filereaper
I'd argue that's the point of moving from a 2nd year course to a 3rd year one.
You incrementally add more complexity. The ISO C++ spec is a similar heavy
tome.

------
flohofwoe
IMHO there are better proposals for a "better C" language which fix some of
the shortcomings of original C:

\- [http://c2lang.org/site/](http://c2lang.org/site/)

\- [https://ziglang.org/](https://ziglang.org/)

\- [https://nim-lang.org/](https://nim-lang.org/)

As long as the language is small and has good tooling, and (most importantly)
can easily interoperate with C libraries (have a look at Nim for an really
awesome C integration), it doesn't matter whether it is backward compatible
with C.

C itself should stay what it is. A low level and simple language without
surprises which is only very slowly and carefully extended. Languages that are
developed "by committee" and add lots of new features quickly are usually also
quickly ruined.

~~~
earenndil
I've written in the past about C2[1]. Nim is aimed at bit of a higher level
than a "c replacement" should. I don't really know much about zig, but from
what I do know, I like it.

1:
[https://www.reddit.com/r/programming/comments/7ugm8e/c2_c_wi...](https://www.reddit.com/r/programming/comments/7ugm8e/c2_c_with_cleaner_syntax_a_module_system_no/dtlz4k9/)

------
snarfy
C is an evolving ISO standard.[1] We are currently at C11.

> The purpose of the project is to engineer modern language features into C in
> an evolutionary rather than revolutionary way.

It's also the purpose of the standards body. Why not propose these changes to
the standard?

[1] -
[https://www.iso.org/standard/57853.html](https://www.iso.org/standard/57853.html)

~~~
pjmlp
Maybe because one needs to buy a seat at the table, by making a formal
proposal, pay the travel expenses on their own and get to win the hearts of
others members when voting comes to be.

------
emilfihlman
If there's one thing I would do to C it is to replace the normal datatypes
with u8, u16, u32, u64 (ad infinitum) and their signed brethren s8, s16, s32,
s64, ...

And don't start with the stupid (u)intXX_t.

~~~
Nursie
They aren't stupid, and they are both standard and available on nearly every
system going. People absolutely should use stdint. h

I wish more would.

~~~
Ace17
> People absolutely should use stdint.h

Definitely. However, you have to admit the names (uint32_t) could be made less
verbose, like "u32".

~~~
emilfihlman
Exactly.

We are talking about the smallest possible datatypes that build up everything
here. They don't have to be named variable_typeFactory_type_signed_t.

------
Someone
From
[https://plg.uwaterloo.ca/~cforall/features](https://plg.uwaterloo.ca/~cforall/features):

    
    
        Exponentiation Operator
    
        New binary exponentiation operator '\' (backslash)
        for integral and floating-point types.
    
        2 \ 8u; // integral result (shifting), 256
       -4 \ 3u; // integral result (multiplication), -64
    

I hope that’s a documentation error. Otherwise, it seems designed for the
“Obfuscated C for all” contest:

    
    
       int i = f();
       int j = i \ 3u;
    

Does what ‘\’ does really depend on the sign of _i_?

~~~
Sean1708
The "shifting" vs "multiplication" is just an optimisation since

    
    
      x * 2 == x << 1
    

for any positive x. As far as I'm aware shifting a negative number is
undefined, which will be why they use multiplication for negatives.

------
antirez
So the mailing list and the other stuff are "internal only"? How is possible
for external individuals to take part?

~~~
BruceIV
I'm actually on the Cforall team -- we've been running fairly low-profile for
the moment (it wasn't one of us that posted the homepage to HN), but plan on
making a beta release of the compiler and stdlib sometime this summer.

If you're interested in working on the project though, more hands are always
welcome; I'd suggest contacting our team lead, Peter Buhr, his email is pabuhr
AT the university domain Cforall is hosted on.

~~~
kodablah
Out of curiosity, why not do the development in public? Or is there a repo I
missed?

~~~
BruceIV
Most programming languages do an initial period of internal development before
a public release.

When I started on the project ~3 years ago, it took me about 2 weeks to work
around the (then current) set of compiler bugs to make a 100-line benchmark
program -- naturally a public release at that point would not have been
fruitful. Today our compiler generally works, and we're looking forward to
making a public release once we get a couple more features stabilized.

~~~
kodablah
I think there is a difference between working on something in public and a
public release. I'm always skeptical of the claims that things can't be done
transparently because it's not open to input yet. Those things are orthogonal.
You don't have to work in secret just to avoid some of the issues with
publicity. Granted I know it happens often, I just don't think it needs to be
that way.

~~~
Retra
If you want to work on something in public, you potentially have to write
public-facing prose. You have to explain what the project is, where to find
stuff, who to contact, documentation... set up a website, wrangle newcomers,
commenters, press, etc. For a research project, that's a lot of work to do by
people with limited time/budget for something that hasn't even been
demonstrated to work.

Basically, day 1 transparency either requires a budget or misplaced
priorities.

~~~
kodablah
I specifically addressed this:

> I'm always skeptical of the claims that things can't be done transparently
> because it's not open to input yet. Those things are orthogonal.

You don't have to explain anything. You don't have to set up a website (case
here already had a website, code was just hidden). I'm not sure where these
requirements come from, but it's not true, and I'd argue you do more harm
giving the impression of secret development than you do not accepting input at
an early stage. We all understand the latter, but many of us are wary of the
former when someone says their committed to openness and does the opposite.

------
rwmj
Did they bother to ask any C developers what the pain points are? The kernel,
qemu, libvirt, coreutils and gnulib developers really use C and POSIX to
breaking point, and have some real problems that might be addressed in the
language, but I don't see much evidence of those problems being addressed
here.

Did they study existing code bases and bugs to find out how applicable these
changes are to fixing real problems?

~~~
vanderZwan
It's a research language:

[https://plg.uwaterloo.ca/~cforall/people](https://plg.uwaterloo.ca/~cforall/people)

You can check the various Master Theses at the bottom of the page.

------
msaltz
In my opinion, what C is lacking isn’t primarily language features - it’s: 1)
a common, readable style standard that people can agree on 2) _modern_ agreed-
upon idiomatic ways to write readable and safe code. There are certainly
common C idioms but many exist for historical reasons and not because they’re
necessarily the best things to do, and 3) a standard library that exemplifies
the above two things, provides common functionality needed between projects,
and fosters a sense of community

Efforts like those of the poster don’t really address these things.

When I tell people I like C, the response differs depending on experience
level. Less experienced people who haven’t spent time in C++ either will say
“Gross, pointers”. People used to C++ will say “what about templates and
constructors/destructors”, and “are you going to write your own library for
vectors and maps every time?” And people who are experienced (more experienced
than me) and like C have generally said that the main things they miss from
C++ are constructors and destructors (and mostly destructors), and templates
(but only for container types), but that they can live without them.

C is a small language that _can_ be relatively easy to write (once you
pick/write a suitable stl-equivalent), and extremely easy to read (and to the
extent that you can look at a line and know exactly what’s going on under the
hood). IMO it should stay that way.

Take a look at zproject [0] for what I think is a good effort to standardize C
style and project structure. Even if you disagree with the particular design
choices, the spirit of it is what I think is needed to keep people from just
assuming C is for dinosaurs.

[0] [https://github.com/zeromq/zproject/](https://github.com/zeromq/zproject/)

~~~
sanbor
I have little experience with C but my feeling is that it's a waste of time to
have to deal with memory in my program.

I don't just have to worry about the problem that I'm trying to solve but also
about handling the memory properly.

Of course there are scenarios where writing a fast and lightweight app is part
of the problem but for many projects that's not the case.

I'm fine with pointer arithmetic and all that but I'm not fine with the
constant fear that I did some oversight and my app is going to crash and I'll
have to spend time debugging what's going on.

~~~
Retra
Most programming problems are pretty trivial to solve if you're willing to
ignore performance. It behooves us to realize that the main difference between
mathematics and computer science is that computer scientists have to account
for the several orders of magnitude difference between the runtime costs of
different operations. If that weren't an obstacle, we'd basically only need
one programming language, and it would like pretty much like standard
mathematics.

So I interpret your comment as something like "I don't want to program, I just
want to assemble mathematical statements", which is a fine and perfectly
legitimate thing to do, but it also seems a bit lazy, impractical, and
probably irrelevant, given the subject.

~~~
sanbor
My point was about why invest time in C dealing with memory with the risk of
segfaults when there many other languages like JS, Java, Go that would take
care of that task for you.

Also I'm talking about projects (e.g. building a word processor), not
programming problemns (e.g. invert this binary tree). In my experience
projects are complex systems with many moving parts interacting and most bugs
comes from the complexity of the system/problem. With C, I don't just have to
think about the problem that I'm solving but if I did something wrong when
dealing with memory allocation/releasing.

I don't have much experience in C except from the basics so I hope to hear
from people that loves C why they choose it or if its just a constraint
inherent to the problem they're dealing with.

------
chubasco
I think I would prefer the Indiana Jones approach. "Leave it alone! It belongs
in a museum!"

~~~
jokoon
You would be right if OS kernels were not written in C.

Linux is pretty much deployed on a lot of hardware, it is still maintained,
and it uses C.

Granted it is not the best language, but it's simple enough to do kernel
development.

The same goes for cobol, it's the best paying language out there.

------
throwaway45074
The (draft) ISO C11 spec is already nearly 700 pages[1]. How can anyone
justify adding something like "choose" (a switch() without fall-throughs) to
such a language?

Who are these people[2], and what is their mandate? Did they actually consult
with the likes of Linus Torvalds, Greg KH, Mike Pall--those who actually use C
every single day on mission-critical projects like OS kernels and virtual
machines--and ask them what improvements to C _they_ need?

1) [http://www.open-
std.org/jtc1/sc22/wg14/www/docs/n1548.pdf](http://www.open-
std.org/jtc1/sc22/wg14/www/docs/n1548.pdf)

2)
[https://plg.uwaterloo.ca/~cforall/people](https://plg.uwaterloo.ca/~cforall/people)

------
ndh2
From [https://plg.uwaterloo.ca/~pabuhr/](https://plg.uwaterloo.ca/~pabuhr/):

> _The ability to write generic reusable programs, called polymorphism, is
> fundamental to advanced software engineering. I am interested in static
> type-systems providing polymorphism without the use of subtyping. The
> problem with subtyping is that it imposes significant restrictions on reuse
> when static type-checking is required. This work has resulted in a new
> dialect of C language, called Cforall, which adds parametric polymorphism
> and extensive overloading to provide a more general type-system._

------
irundebian
Please smart people, spent your intelligence on clean approaches such as
memory-safe system programming languages such as Rust or so instead of wasting
time with old broken legacy languages. I want to see secure systems before I
die.

------
antirez
I studied the documentation, basically 80 percent of what is added is not what
is needed for C to become better, in my opinion.

~~~
kosma
Thousand times this. C for All is "what the language researchers want", not
"what the C users need".

------
dimman
"Without continued development of the language, C will be unable to cope with
the needs of modern programming problems and programmers; as a result, it will
fade into disuse. Considering the large body of existing C code and
programmers, there is significant impetus to ensure C is transformed into a
modern programming language."

Really? Lots of C code written today is written using C89/C90 or C99 std. I
think if it's something that history tought us it is that C does _not_ need to
be transformed into something else or we would already be happily using this
"something else" today.

------
adrianmonk
Wow, they really hate object-oriented programming.

It's the one thing they immediately emphasize that their language isn't, and
it's the one example they give for "disadvantages of multiple legacy design-
choices".

------
TwoBit
We already have this. Just use C++ and stay away from the features you don't
want. If you want to enforce specific restrictions then start an effort to
provide a formal C++ feature restriction specification.

------
enriquto
A beautiful, and simple, addition to the C language would be a mechanism to
assess the remaining stack size. This is trivial to check in assembler, but
practically impossible in portable C.

Indeed, thanks to VLA, the stack can be used as a clean notation for raii. You
just replace this ugly, but very common, construction

    
    
        void f(int n)
        {
                float *x = malloc(n * sizeof*x);
                // ...
                free(x);
        }
    

with this

    
    
        void f(int n)
        {
                float x[n];
                // ...
        }

~~~
BruceIV
[on the Cforall team] we actually take advantage of this same VLA idiom for
temporary storage for polymorphic variables.

Fun fact from when we switched our implementation to use VLAs: if you call
alloca() for stack memory instead, it doesn't work properly inside a loop,
because it never releases the memory until the stack frame is exited.

------
filereaper
uWaterloo uses an in-house language to teach advanced control flow, in my days
it was uC++ built by Peter Buhr in CS343. They might have opted to use C for
All now.

I've found it quite easy to spin up parallel tasks in uC++ if I needed both
C++ and easy-to-use parallelism, the language isn't formally supported but for
small student projects its pretty kick ass, also the prof who built it is just
quick email away.

So all I'm all in favour of C for All as an alumni, hopefully it enriches the
existing curriculum.

~~~
BruceIV
[on the Cforall team -- also a CS 343 TA] We've incorporated the main uC++
feature set into Cforall, but are still using uC++ for 343; maybe in another
couple years when Cforall is stabilized a bit we'll give it to the students.

------
luckydude
Hmm, we took a different approach, here's my C-like dialect (built on Tcl's
byte codes so it co-exists with Tcl code. And yes, I know, but we needed Tk so
were stuck with Tcl).

[http://little-lang.org](http://little-lang.org)

Stuff that I'd like to C in an evolved C:

regexp engine as part of the language so you can do

    
    
        while (buf = <>) if (buf =~ /some regexp/) puts(buf);
    

<> and <FD> from perl, just handy.

Lists as a built in, with any element type and builtins like push, pop, shift,
unshift, etc. Again, more perl goodness without all the @'s and $'s.

${expr} interpolation inside strings. Like shell, and it's handy.

At this point I'm just typing in the L language docs, so most of the stuff
here:

[http://www.little-lang.org/little.html](http://www.little-
lang.org/little.html)

BTW - the logo for the language is a tip of the hat to the things that
inspired it: the Tcl feather logo, the Perl camel logo, and "C" all bunched
together. I'm very fond of that logo but not sure that anyone but me gets it.

------
sagichmal

        Exception Handling
    

Oh no :(

------
joshuak
I've had renewed interest in C recently, having been away from it for nearly
10 years. This renewed interest comes from working with golang for the last
few years, and has caused me to find this book[0] which discusses ways to
implement OOP ideas in pure C. Not to promote Go, or OOP, but rather I wonder
if selecting useful idioms form modern languages wouldn't be a better
intermediate step to updating C, then language level changes.

[0]
[https://www.cs.rit.edu/~ats/books/ooc.pdf](https://www.cs.rit.edu/~ats/books/ooc.pdf)

------
js8
Not bad, but not much to call home about either.

Personally, I would like to see better support for immutability/purity and
more first-class functions (does C still insists on functions to be global in
scope?).

Also, I think user-defined constructors/destructors are a bad idea. I
generally found that any side effects that are done in constructors and
destructors are a nasty source of bugs. It's almost always better to use a
factory method (function), which makes user-defined constructor/destructor
useless as a concept.

~~~
jcelerier
> It's almost always better to use a factory method (function), which makes
> user-defined constructor/destructor useless as a concept.

well, no. In languages with constructors, you can enforce invariants in your
class and ensure that no object that does not respect the invariants exists in
your system. If you only have factory methods, you can still construct objects
"normally" then nothing prevents anyone from creating another object which
does not respect them. Or you can hide your struct definition in an
implementation file, but then you loose the ability to construct on the stack
and have to dynamically allocate, which kills performance.

~~~
js8
> In languages with constructors, you can enforce invariants in your class and
> ensure that no object that does not respect the invariants exists in your
> system

Actually, it's not enough. If you can mutate the class variables (attributes),
then you can always create a class that doesn't have these invariants
enforced. The only way that could completely prevent invariants in the class
being disrespected would be to have a strong, possibly dependent, type system.

For example, consider a function (method) that takes two objects of the same
class and creates another object of the same class based on the two. During
the construction of the returned object, invariants can be broken, and if this
function contains an error, it will return an invalid object.

This is especially problematic with the RAII pattern. Because resource
acquisition can fail, you have to allow for "broken" objects to be returned,
which represent the resource not being acquired. In functional programming,
this is done with sum types (and in general way with Maybe, for instance).

I would say I am against RAII pattern, because it gives people a false sense
of security, as you have to deal with the resource not being acquired anyway
(either by returning object in incorrect state or by exception). But if you
forfeit RAII, you might as well get rid of user constructors and use factory
methods (and simple data constructors and sum types) everywhere for simplicity
and consistency.

~~~
dragonwriter
> Actually, it's not enough. If you can mutate the class variables
> (attributes), then you can always create a class that doesn't have these
> invariants enforced. The only way that could completely prevent invariants
> in the class being disrespected would be to have a strong, possibly
> dependent, type system.

You can completely avoid it if the invariants are expressed as validation
methods, and mutation of state isn't direct but through a mechanism initially
updates shadow state and guarantees that validators are run and failed
validations result in both the original state being preserved and an error
being signalled, and only successful validation results in state updates.

A sufficiently robust type system is superior than this kind of runtime check
in all kinds of ways, but is not the only way to avoid invalid state with
mutable objects.

~~~
js8
Right. What you are talking about is essentially a dynamic dependent type
system.

------
Ericson2314
This is stupid. C accepts too many programs already. Rust mainly improves by
accepting fewer. The few compatability-breaking changes this includes don't go
far enough to matter.

------
crimsonalucard
>While C++ had similar goals, it has the disadvantages of multiple legacy
design-choices (e.g., object-oriented)

How many people agree with this statement? OO is a legacy design choice or in
other words: a bad design choice.

I agree with the statement, so do most modern languages like rust and golang
but I wonder what do non language designers think? This statement was given as
if it was obvious but many programmers who I work with still think OO is the
greatest invention ever.

~~~
pjmlp
Go and Rust are also OO.

There isn't such thing as the only true and single way of doing OOP.

Also without OOP, good luck doing GUI programming in C++. Even Motif and GTK+
are OOP based, in C, because immediate UIs suck for anything beyond simple
game UIs.

~~~
crimsonalucard
Modern GUIs happen mostly in JavaScript with the react + redux ecosystem which
is more of a functional model then OO.

~~~
pjmlp
JavaScript uses the same OOP model as SELF, prototype based.

It doesn't matter what libraries one uses, they don't remove the OOP model out
of JavaScript.

Additionally all those react ideas already existed in Smalltalk as well.

~~~
crimsonalucard
I'm talking about javascript + react + redux. Generally when you use these 3
technologies you avoid javascript oop features.

~~~
pjmlp
No you don't, because JavaScript is OOP all the way down.

~~~
crimsonalucard
Yes you do, because immutability is recommended by redux. OOP features can be
ignored.

~~~
pjmlp
Unless you manage to write JavaScript code without functions and data types,
you are using JS OOP features, implemented via prototype based OOP.

~~~
crimsonalucard
No. I'm talking about programming style. I am not talking about how certain
JavaScript properties are implemented.

------
edflsafoiewq
Everyone wants to cripple switch by turning it into the structure variously
known as cond, when, match, etc. If you can only have one, by all means, take
the cond, it will be useful more often, but switch's computed goto is a very
useful thing to have in reserve.

------
mar77i
What's with the weird cryptic, trigraphish syntax for something common as
constructors and destructors?

How are _init(struct obj _o) _cleanup(sturct_ o) not enough? Okay, except
those rare cases when you need a _new(struct obj __o).

~~~
BruceIV
[on the Cforall team] It broadly matches our other operator-overloading
syntax, where the ?'s show where the arguments go, e.g. ?+? for binary
addition, ?++ for postincrement and ++? for preincrement. For something as
common as constructors and destructors, a concise syntax is a desirable
feature.

~~~
andrewmcwatters
What I get out of this is that you like to play with languages rather than
make actual things with them.

------
coldtea
The biggest evolution for C, to cut down bugs to 1/10 would be to have a
proper built-in string type -- one that easily transforms into the relevant C
type, and that keeps the size.

(And maybe a vector and hashmap).

~~~
earenndil
sds? [https://github.com/antirez/sds](https://github.com/antirez/sds)

------
halfer53
I'm personally in favour of this proposal, I'm sick of having to write
function pointer when implementing objects in C. Looking forward to seeing
this in the next C standard

------
rotrux
looks like the University of Waterloo isn't on the cloud!

Anyone else having trouble accessing the site?

------
LaneRendell
Hallelujah.

------
andrewmcwatters
I think C developers are harder to convince than developers who more regularly
consume modern languages. I see no reason to use this over ANSI C.

~~~
kurtisc
C especially is used by EEs who are less likely to care for newer features.

~~~
platinumrad
EEs are why C89/C90 will be with us forever.

~~~
Gibbon1
Personally I don't think actual EE's doing firmware care very much for
C89/C90. But I've seen CS people totally spaz when confronted by code with
variable length arrays. And try to 'fix' code by removing <stdint.h>

~~~
platinumrad
It's not meant as a slight against EEs. It's just my experience that people
with EE backgrounds tend to be more invested in becoming very skilled with
"ANSI" C (plus whatever extensions help them get things done) while people
with CS backgrounds are more likely to be interested in chasing new and
"better" ways of doing things like C99 VLAs or C11 generic selection or a new
language. It seems like your experience has been the opposite of mine so maybe
it's wrong for me to generalize.

------
gcbw2
Should have fixed the easier problem first. The 'searchability' of the
language name.

~~~
BruceIV
[on the team] It helps if you use the official ASCII spelling, Cforall -- a
DuckDuckGo search for "Cforall" in private browsing mode pulled up our
homepage first result. (I have no idea who the OP for this thread is, they're
no one associated with the team.)

------
SidiousL
I see they are adding an analog of the C++ iostreams, but I don't see a
discussion of how to disambiguate between `sin' as in stream-in and `sin' as
in the mathematical function.

Really, they should introduce some kind of modules or namespaces. Of course,
C++ already has namespaces and will have modules sooner or later...

------
thanatos_dem
Site is down... that doesn’t exactly bode well for an article seemingly about
programming.

~~~
mbel
For convenience of other readers, here is a version cached by Google:
[https://webcache.googleusercontent.com/search?q=cache:wEWECJ...](https://webcache.googleusercontent.com/search?q=cache:wEWECJ0f2q8J:https://plg.uwaterloo.ca/~cforall/+&cd=1&hl=pl&ct=clnk&gl=pl)

~~~
wolfgke
Or here by archive.org:
[https://web.archive.org/web/20180323124625/https://plg.uwate...](https://web.archive.org/web/20180323124625/https://plg.uwaterloo.ca/~cforall/)

