Author Topic: C2 Package system  (Read 12514 times)


  • Full Member
  • ***
  • Posts: 220
    • View Profile
C2 Package system
« on: February 05, 2013, 01:58:11 PM »
There was quite some interest in C2 at Fosdem'13 and I had some great
discussions afterwards. So that was very nice. Additionally there were
some great Ada presentations, which got me thinking as well.

This post is a RFC (request for comments) about the C2 package system. I
have some ideas and would like your feedback.

In brief, the current package design is:
- every file is in a package.
- multiple files can belong to the same package.
- when using symbols (functions/types/vars) from other packages, the packages
  has to be 'used' like:
   'use utils;'
- when using symbols from other packages, you only need to specify the package
  prefix if there are conflicts (A::Type and B::Type), otherwise you can just
  use Type.
- the package operator is '::'
- you can only use public types as return/argument type for functions.

The ideas i'm toying with are:
A. replace the '::' with '.', so package::symbol becomes package.symbol.
  The advantage would be better readability, but it would blur the distinction
  between struct.member and package.symbol.
B. The 2nd idea is to always require the full naming (so package::symbol)
  for external symbols. The disadvantage of this is more typing, while the
  advantage would be that adding a symbol to an external package will never
  break the using code. For example: if you have package T that uses packages
  A and B and there is a type A.Type, adding B.Type will break T.
C. Adding an optional 'as Y' option to use statements. So
  use my_long_package as mlp;
  This can partly negate the disadvantages for point B.
D. Each package symbol can be public or not. I'm thinking about adding a third
  option, just for type: 'opaque'. Opaque types may be used as (return/argument)
  types in public functions, but the clients can only use them to pass around
  (not derefence/use them). Clients would be able to allocate them on the stack,
  since sizeof() could be used on opaque types.
  The advantage of this keyword is that it makes the opaque-pointer pattern
  explicit. Also clients would only need a recompile if the sizeof() changes

So I'm interested in your opinions about:
Q: (A) what would be a better package operator? :: or . ?
Q: (B) require full specification of external symbols? (is this worth it/how
    big would the problem really be?/add -lax-naming option?)
Q: (C) What do you think about use <long> as <short>?
Q: (D) Any other options?
Q: any other ideas?

NOTE: I had to disable forum registration for SPAM reasons, but I'd be happy
to create an account for anymore. Just mail me your email/login-name.



  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: C2 Package system
« Reply #1 on: February 06, 2013, 06:32:34 PM »
Hello Bas,

I vote for . instead of ::. Most langages use . and it makes sense, you could imagine your package as an object/structure and you access member of this structure through dot.

you could do import package.func10deprecated as func10 for instance

or from package import funct10 as in python :)

How do you intend to handle concurrency with regards to package handling...


  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: C2 Package system
« Reply #2 on: February 16, 2013, 07:49:17 AM »
Hi Bas,

I just saw the video of your FOSDEM 2013 lighning talk at Very interesting.

(A) I think the . works fine. When using Python, I've never suffered confusion with the . for packages.
(B) I prefer full specification of external symbols. You never have to guess which package something comes from. The breakage scenario you describe convinces me further.
(C) use <long> as <short> makes (B) much more manageable, and I can't think of a downside.
(D) Opaque types sound almost necessary to seriously build software with architecture in mind.


  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: C2 Package system
« Reply #3 on: February 17, 2013, 06:07:04 PM »
Here's a good case for (B) : We're already doing it!

In any sizeable C program, you tend to include the name of the module (package) in the function name. For example, look at mutex.c in the Linux kernel: functions there are named mutex_lock(), mutex_trylock(), etc. With full package naming, the functions would be renamed to lock() and trylock(), and users of these functions would refer to them through the package name as mutex.lock() and mutex.trylock(). Some functions in the kernel are named a little differently, with a verb in front of the package name like flush_workqueue(), which would be renamed to flush() and referred to as workqueue.flush(). See, its often the same amount of typing - so that concern goes away.

When you look at example code in a C language book, thinking about changing all the printf()s and getc()s to the longer stdio.printf() and stdio.getc() seems discomforting. However, in real production code the difference is negligible.


  • Full Member
  • ***
  • Posts: 220
    • View Profile
Re: C2 Package system
« Reply #4 on: February 19, 2013, 12:45:27 PM »
Thanks for your feedback!

I've added the 'use <long> as <short>' construction.
Additionally I've added the 'use <long> local' and 'use <long> as <short> local' construction.
The keyword local can thus optionally be added to a use statement. When added this means
that symbols from the used package can be used without package prefix. Any ambiguity still
causes an error.
So for stdio, the developer could do 'use stdio local' and then use 'printf' without prefix.