Hacker Newsnew | past | comments | ask | show | jobs | submit | BruceIV's commentslogin

You can do this sort of search in Firefox as well. Right click on pretty much any search box, then click "Add a Keyword for this Search..." You'll get an add-bookmark dialog that you can put a keyword into (e.g. "w" for Wikipedia) -- I like to save the resulting bookmark in "Unsorted Bookmarks" so that it doesn't clutter up my menus. After that just typing "w Firefox<enter>" in your address bar will bring up the Wikipedia page for Firefox.


[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.


[on the Cforall team] FWIW, the Go docs are somewhat ambivalent on the OO nature of Go[1]. Along similar lines, our main objections to object-orientation are that, in "traditional" implementations like C++ or Java, it tightly couples a number of features that we believe would be better served by a more orthogonal design.

More specifically, C++-style OO couples (1) in-memory layout of types, (2) behaviour of objects, (3) encapsulation boundaries, and (4) the hierarchical "is-a" relationship. In Cforall, (1) and (3) are handled by the usual C mechanisms of struct types and translation-unit boundaries [we go to great effort to maintain C-style separate compilation, though we will likely build a better namespace/module system at some point], (2) by traits, and (4) by a yet-to-be-implemented system of RTTI for specific "inherited" types [likely when the undergrad RA who started our exceptions implementation comes back as a Master's student this fall].

As you mention, many use-cases (including widgets in GUIs, but also abstract syntax trees in compilers) require some sort of heterogeneous collection type to work properly, and for this OO is the right model. We just don't want to force the entirety of that model on every use case, so we can just take traits when we want to write a polymorphic function over related types or an ADT like "Set" which requires its keys be sortable, or just take RTTI for exception handling, when the set of exception types we're handling is known statically, but we need to determine if the thrown exception inherits from one of the caught types.

[1] https://golang.org/doc/faq#Is_Go_an_object-oriented_language


[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.)


[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.


I have often wanted c99 with destructors for RAII purposes.


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


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


I might have missed this.. but how is Cforall implemented?

A new GCC or LLVM frontend, or is it a transpiles-to-C implementation ala. Nim or Vala?


Transpiles-to-(GNU-)C -- it was first written before LLVM, if we were starting the project today it would likely be a Clang fork.


Clang harks back to 2007 and LLVM 2003.. is this a research project that was recently taken back up?

I was curious about the implementation because I've had rough experiences with Vala and Nim's approach. Unlike with "transpiles-to-js" languages, transpiling to C has some tooling gaps (debugging being the big one). I admittedly don't have a ton of experience with either language but I couldn't find a plugin that gave me a step-through debugger for something like CLion or VS Code. You can debug the C output directly but this will turn off newcomers and assumes the C output is clean.


The initial implementation was finished in '03, and we revived the project somewhere around '15, so your guess about a research project that was recently taken back up is correct.

We intend to write a "proper compiler" at some point (probably either a Clang fork or a Cforall front-end on LLVM), but it hasn't been a priority for our limited engineering staff yet. I think we are getting a summer student to work on our debugging story (at least in GDB -- setting it up so it knows how to talk to our threading runtime and demangle our names), and improving our debugging capabilities has been a major focus of our pre-beta-release push.


What I will like is more strict compile time checks. Most C pros have to rely on external tooling for that.


It's maybe not quite what you're looking for, but Cforall's polymorphic functions can eliminate nearly-all the unsafety of void-pointer-based polymorphism at little-to-no extra runtime cost (in fact, microbenchmarks in our as-yet-unpublished paper show speedup over void-pointer-based C in most cases due to more efficient generic type layout). As an example:

    forall(dtype T | sized(T))
    T* malloc() {  // in our stdlib
        return (T*)malloc(sizeof(T)); // calls libc malloc
    }

    int* i = malloc(); // infers T from return type


Excuse me for my lamerism, but can you tell me what is a polymorphic function?

My idea was that if it is better to do as much compile time checks as possible before you introduce run-time checks. Does that void pointer protection run faster that code that was checked at compile time? How?


A polymorphic function is one that can operate on different types[1]. You would maybe be familiar with them as template functions in C++, though where C++ compiles different versions of the template functions based on the parameters, we pass extra implicit parameters. The example above translates to something like the following in pure C:

    void* malloc_T(size_t sizeof_T, size_t alignof_T) {
        return malloc(sizeof_T);
    }

    int* i = (int*)malloc_T(sizeof(int), alignof(int));
In this case, since the compiler verifies that int is actually a type with known size (fulfilling `sized(T)`), it can generate all the casts and size parameters above, knowing they're correct.

[1] To anyone inclined to bash my definition of polymorphism, I'm mostly talking about parametric polymorphism here, though Cforall also supports ad-hoc polymorphism (name-overloading). The phrasing I used accounts for both, and I simplified it for pedagogical reasons.


[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.


[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.


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.


[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.


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). 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)


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.


[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.


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


[actually on the Cforall team] This is basically our pitch -- the last 30 years of language design features applied to a language that is not only source-compatible with C (like C++), but actually maintains the procedural paradigm of C (unlike C++) -- idiomatic C code should require minimal to no change to make it idiomatic Cforall code, and skilled C programmers should be able to learn the extension features orthogonally, rather than needing to figure out complex interactions between, say, templates and class inheritance. We are working in the same space as C++, and do draw inspiration from C++ where useful, but with the benefit of decades of watching C++ try things to see where the important features are.

There's also some really neat language-level concurrency support; work is ongoing on new features and a shorter summary, but you can see one of our Master's student theses for details: https://uwspace.uwaterloo.ca/handle/10012/12888


the existence of exceptions seems to bely the idea of minimal changes to make idiomatic C code idiomatic Cforall code.

While C does have longjmp and friends, usage of them is hardly idiomatic, so most C code assumes no non-local tranfer of control happens when calling functions. Coding with non-local transfer of control and without require very different idioms.


[actually on the Cforall team] Huawei has funded the project for the past couple years, the web server is just our university research group's web host, which we didn't expect to get this much traffic on (it wasn't one of us who put this page on HN). We've been running fairly low-profile for the moment, but should make a beta release later this summer.


How did you get funding? I'd like to get some funding for my project (ziglang.org)


IIRC [not the team lead] they approached us when they were looking for modernization options for their existing C codebases. From there it went through the usual university-corporate research partnership process.

Zig looks neat, BTW.


Zig is great. It is my C replacement right now, and I guess it would be 'revolutionary' by the definition on the C for All site.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: