C³designer's blog

Yes, I'm C³wife's husband ;)

« Back to blog

Aims and Rules of Thumb for the Design of C³: a Request for Comments

I wrote a working document called "Aims and Rules of Thumb for the Design of C³", based on the chapter 4 of The Design and Evolution of C++ by Bjarne Stroustrup. The conclusion of the document is the following list of rules and I would like to know what you think of them.

Aims
 
C³ makes programming more enjoyable for serious programmers.
 
C³ is a general-purpose programming language that supports
– low-level programming
– data abstraction
– object-oriented programming
– generic programming
– functional programming
– metaprogramming
 
General rules
 
C³’s evolution must be driven by real experience.
Do the simplest thing that makes C³ better at fulfilling its aims.
C³ must be useful now.
Provide the best available implementation as a default for every feature.
Always provide a transition path.
C³ is a language, not a runtime system.
Provide comprehensive and customizable support for each supported style.
Don’t try to force people to use a specific programming style.
 
Design support rules
 
Support sound design notions.
Provide facilities for program organization.
Say what you mean.
Don't set policy.
Provide a mean to set policy.
Unleash large-scale collaboration.
 
Language-Technical Rules
 
No implicit violations of the static type system
Provide as good support for user-defined types as for built-in types.
Locality is good.
Avoid order dependencies.
Each individual feature must be easy to teach.
Syntax matters.
External tools usage should be eliminated.
All facilities have an interface in C³.
All facilities not directly supported by the environment are implemented in C³.
 
Low-level programming support rules
 
Leave no room for a lower-level language below C³ (including assembler).
What you don’t use, you don’t pay for (zero-overhead rule).
All implementation choices can be made by the user.
C³ allows mapping to any native environment.

 

Feb 14, 2011
Michel Fortin said...
It's hard to not to agree with a list of principles. Two things I noted:

- C³ is a language, not a runtime system.

Not imposing a runtime is a good idea. That said, it should come with a good runtime to use as the default, otherwise it'd would make the language impossible to learn. Even C has its own runtime!

- Leave no room for a lower-level language below C³ (including assembler).

Really? And how are you going to write a function that does a system call?

Feb 14, 2011
Thanks for the feedback Michel!

What I call a "runtime system" would be something like the JVM. Don't worry, there will be plenty of available functions. As we speak, I'm designing the minimal system necessary to run my "hello, world" program.

About assembly-level coding, it's just a matter of syntax: instead of linking to object files generated from separate .s files, I would like to have an API that is a direct mapping of the instruction set of the machine with C³ syntax.

Feb 16, 2011
Q said...
Minus the functional programming and metaprogramming, it sounds a lot like Ada to me.
Sep 16, 2011
Tandava said...
I would take care it doesn't grow into an "all things for all men" monstrosity like Ada or PL/1
Sep 16, 2011
This is a valid concern that I'm already facing: Among the ideas for C3 that I have, there is both the idea of making it open-source friendly and open-source itself, but I also want to support very specialized niches like high-performance computing and games where paying customers would enable such solutions to exist. How do I serve both without losing my focus? (Yes, I know, I must first have something that does "hello, world"...)

At least, in my quest for making C3 "all-purpose", I'm not adding a lot individual features. I'm focused on making general mechanisms to allow different needs to be fulfilled. I'm also planning on using these features myself to offer complete solutions for some niche, like education or games (because it's what I know best)

Nov 07, 2011
stellacore said...
I found this page because, having worked with c++ for 17 years now. In the 90's I learned the deep hierarchy Java style. Today I use a very modern functional style. My experience has involved scientific and engineering type use, extreme high performance, multithreaded scaling. Sort of like game programming, but more concentrating on maintaining precision, formula correctness, and in some cases, dealing with memory compaction. We always have used algorithmic changes for performance, never bit diddling, although we have tried to code things to make it easy for automatic vectorization, etc.

Reading your goals, etc, it seems we agree much on the philosophical side of things. The parsing choices you've made are right on, Keeping the language simple (no automated GC, awesome!).

Of course there's the detail level: some questions about syntax, examples, etc.

Some of my concerns, especially coming from c++ include:

- level of type checking and safety, especially regarding type promotion ('explicit' really has saved our bacon).
- allowing for heavy use of immutable paradigm (we rely heavily on "in place construction" support in the compiler and constify most everything).
- allowing editable arguments to be passed by reference only is bad for readability. Allow pass by const ref, value and addressof (or equivalent) ONLY.

some suggestions:
- const keywords for variables should always be to the right of what is being made const. I know lots of c and c++ programmers don't follow this but using this rule should make parsing much easier and i found that it was much easier to constify even more portions of types removing lots of stupid coding errors.

Nov 07, 2011
Thanks for the feedback stellacore! Here's my thoughts on each of your concerns:

- There will be no implicit conversions at all.

- What do you mean by "in place construction"?

- Pass by const reference is the default. There is no pass by value (if the callee needs a copy, it must be done explicitly). Pass by reference will be explicit at the call site with the & operator, except for operators that are already explicit like +=, -=. etc.

The declarator syntax is much simpler in C³ than in C++ which means that there is no problem with const to the left of the type. In fact, the grammar does not allow const to the right...

Nov 07, 2011
In fact, there is no "magic" at call sites. No conversion nor any copy constructor call.
Nov 07, 2011
stellacore said...
You may want to read this about comst placement. It also describes const class methods.

http://carlo17.home.xs4all.nl/cpp/const.qualifier.html

All I ask is for consistency here. I've just been using the conventions in the above for 6.5 years now.

Nov 07, 2011
stellacore said...
By "in place construction"

an example (chose vector but could be map, object, etc)

a function that creates a vector, populates it then returns it. *if* the vector is declared first in the function and the function only has a single exit point at the bottom returning that function some compilers are able to forego the vector copy and actually fill the vector from the code which called the function. C++0x I believe formalizes this with rvalue references (which look kind of messy to me).

somevec = genvec();

vector genvec()
{
vector res;
// fill vector res
return res;
}

Nov 08, 2011
No worries, I know how const works in C++ :) The good news is that in C³ you won't need to follow a convention for const since there will be only one legal way of writing it and it is very easy to understand.

I think you will like the way most temporaries are eliminated in C³! The rules are much saner than C++98's RVO (return value optimization) or C++11's rvalue references. In fact, in your example, if there is no side effect in the function, C³ would be able to do all the work at compile-time!

Jan 13, 2012
Brian said...
Hmm...seems like "clay" is very interesting. They even avoided OO by using haskell type "variants". Looks good but I'm missing method dispatch (object.method() syntax).