Settings

Theme

Ask HN: Help me improve my C-like language, C3

12 points by Nuoji 5 years ago · 7 comments · 2 min read


I'm working on a "alternative to C" called C3, but unlike most (e.g. Zig, Odin, Jai, Rust etc) it tries to stay really close to C syntax as far as possible and I'd love to hear what people like and what they dislike, especially if they write a lot of C.

The site here has an overview of the language and code samples: http://www.c3-lang.org

You can try it out in the browser here: https://ide.judge0.com/?1EFo with the list of implemented features/not yet implemented features in the compiler found here: https://github.com/c3lang/c3c

Currently the spec has a bit too many features so I will try to remove the superfluous to make the language more easy to grasp in its entirety.

The syntax tries to stay true to C, with things added on top that C can't easily add due to backwards compatibility:

- Module system

- Generics

- Semantic Macros

- Error handling

- Defer

- Value methods

- Associated enum data

- Subtypes (Go's embedded structs)

- Optional contracts

- Built-in strings, maps, subarrays and vararrays

P.S. I know the change to use `func` with functions is controversial – it's great for a simpler grammar and to make function types stand out, but is quite a departure.

P.P.S. "Why not just use C?" Well, we're seeing C++ inspired languages (like Rust) taking mindshare both from C++ and C communities. I would like to see an alternative that keeps to the simplicity of C code instead of taking C++ syntactic complexity as a base line.

qppo 5 years ago

Here are the things I would need to migrate from C/C++/Rust to a new language:

    Automatic memory management, with optional manual control, 
    no garbage collection. 
    
    A universal or widely accepted build system (Cargo, CMake) 
    
    A public package registry and dependency resolver, designed 
    for deterministic builds, multiple versions of the same 
    package on one machine, etc, and support for private/proprietary
    registries (Cargo, Conan)

    A modern query-oriented/reactive/responsive (non-batch) compiler, 
    that supports static analysis, linting, language server features, 
    AST traversals/queries, etc. 

    Support for debugging with GDB/LLDB. 

    A (substantial) subset of the language with a stable ABI. 
    
    Fast debug builds, fast release binaries. 
Syntax/semantics of the language are significantly less important to me than all of the above.
  • NuojiOP 5 years ago

    - Plan is to be able to at least build a robust ref counting lib in the standard library, supported by subtyping and defer this could be at least as easy as in ObjC before automatic refcounting. Temporary allocators (like Odin) will solve most of the temporary allocs (like when you work with strings etc). I'd need some time to explain how that works in detail, but memory management can be made much easier without even having GC or refcounting.

    - The build system is part of the compiler.

    - Package registry: still on the fence with that one. We'll see.

    - The compiler is not built as a responsive compiler. Working on the compiler I don't feel that the workflow of a compiler is the same as is needed for an IDE. The most important thing is not that the compiler is responsive, but that the language amends itself to be compiled in isolation in a modular way. This is a property of the language, and it's been designed with IDE friendliness in mind.

    - Adding more DWARF support is on the todo and obviously a requirement for a serious language

    - LLVM prevents anything based on LLVM to be really slow to compile. It takes something like 99% of all compile time, even on debug builds with no optimizations. To have really fast debug builds a custom backend is needed for each platform. That will happen eventually.

gus_massa 5 years ago

  /**
   * @ensure const(foo), const(bar.x)
   **/
Does the compiler see inside comments? I think that Python does that for types because they want to preserve backward compatibility, but I never like it. Why not something like:

  #ensure const(foo), const(bar.x)
or

  @ensure const(foo), const(bar.x)
  • NuojiOP 5 years ago

    Three reasons:

    1. Implementing pre/post condition checks are optional for a conforming compiler. Putting the checks in special docs comments underscores that the checks are optional. The more C way would perhaps be to use pragma.

    2. Putting checks either between comments and function signature, function signature and body, or at the start of the signature body visually divides function signature from code that’s actually run.

    3. Since these are hard requirements on calling functions the information needs to be in the documentation anyway. This ensures that docs and contracts are always in sync.

    But yes, I think your opposition to this is a valid one. It is not ideal, rather it is the best trade off I could find. Given the above.

zzo38computer 5 years ago

I might like to have, in a better version of C:

- GNU extensions, such as zero-length arrays, ?: with nothing in between, and statements inside of expressions

- Less confusing syntax for types

- Full LLVM features

- Non-Unicode

- Both normal include files and token macros, as well as namespacing and hygienic macros supported too

- Standard macros for testing alignment, endianness, etc

- Macros that can call compile-time execution of codes which can deal with the AST

- Reduced runtime requirements

- Support for setjmp/longjmp with catch blocks; if you longjmp past such a block, it should execute the catch block to clean up as needed before that block jumps again back to the target of the longjmp operation

- The goto command.

The worst thing about C is I think the confusing syntax for types. Pointer arithmetic and goto are both good, though, so keep those.

I can do without automatic memory management.

  • NuojiOP 5 years ago

    - Some GNU extensions are already there, let me know what else you need.

    - ?: and statement expressions (slightly extended) are available in C3 today.

    - Type syntax is simplified in C3 more in line with other languages, e.g. java style array declarations.

    - What does "full LLVM features" mean?

    - What do you mean by "Non-Unicode"?

    - You'll likely be able to include files (and more), but token macros are out I'm afraid. I've tried to cover all uses, but I know it's not quite complete :(

    - All the stuff with offset, alignment etc will of course be available.

    - Macros can act like compile time functions, but direct manipulation of the AST is not there to make the macros easier and safer to use. There is stil a lot of things one can do with using conditional compilation etc, but no manual construction of AST nodes. It's about trying to keep the language fairly uniform even though you add a very powerful macro system. I'm sorry.

    - What do you mean by "reduced runtime requirements"? The ability to run it freestanding? If so, yes then this is a goal.

    - No setjmp/longjmp, instead it has a system with implicit "Result" style returns. But it has a unique flavour. A brief overview can be found here: http://www.c3-lang.org/errorhandling/

    - Sadly I had to give up on goto. To replace it: labelled blocks and labelled for/do/while/if, switch-jumps with "next", error handling using "failable" Result types and defer. The reason for removing goto was due to the amount of compiler complexity needed to support unstructured jumps. I didn't remove it willingly.

allochi 5 years ago

This is quit interesting project, I'm loving its direction. Something I hoped for long time ago. I like that it's trying to make a better C not eliminating it. Will keep a close eye.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection