Live data from Hacker News

How to design a replacement for C++

apenwarr.ca

61–70 of 75 posts

Re: How to design a replacement for C++

#61
post #58

Earlier quoted context omitted.

I just meant that the role of the stack is hardcoded. In most assemblys you can write to the stack pointer and presto, you're working with a new stack. This is a capability of assembly that C doesn't expose.

longjmp()?

No, that only lets you jump out - not e.g. jump between several suspended computations.

Re: How to design a replacement for C++

#62

2. Do not remove the cpp preprocessor. 7. One-time declaration/definition of functions. Aren't these in conflict? A C-style preprocessor is crippled without the header-file model. You'd do better to replace it with some other kind of metaprogramming.

If that's bad, try doing closures without garbage collection.

Re: How to design a replacement for C++

#63

Some comments on your proposed additions (my other comments were about the proposed reductions): - I don't think .NET-style generics can be implemented in a statically typed language that doesn't have a common base class (e.g. everything derives from class Object). This is an oversimplification to say this but at some level generics are implemented as syntatic sugar for typecasts between Object and the type parameter…

> This is an oversimplification to say this but at some level generics are implemented as syntatic sugar for typecasts between Object and the type parameter type.

This is not true. Java generics work this way (google "type erasure"), but C# generics are implemented with specialized code, so that e.g. List.Add has its own IL implementation distinct from the one for List.Add. This lets the JIT do type-specific optimizations, like not having to box the ints in a List.

The specialization code also tries to share code in cases where the type parameters don't matter (e.g. so that you don't have a million identical implementations of List.Count hanging around).

Re: How to design a replacement for C++

#64

Some comments on your proposed additions (my other comments were about the proposed reductions): - I don't think .NET-style generics can be implemented in a statically typed language that doesn't have a common base class (e.g. everything derives from class Object). This is an oversimplification to say this but at some level generics are implemented as syntatic sugar for typecasts between Object and the type parameter…

Generics requiring type casts and a common base class is Java type-erasure braindeadness.

CLR (.NET) generics compile separate code for each value type parameter, so you can have eg. vectors of structs, with the same performance as in C++. (for reference types, it uses the same code with an additional hidden "generic context" parameter, but that's an implementation detail). CLR has pass-by-value too, and although older versions of the MS.NET JIT did not inline such functions, the current version should have performance similar to C++.

Unfortunately, few programmers know how to get the maximum performance out of the CLR.

About not being to able to reassign references in C++ - the main reason is probably because that would require a separate operator, since assigning to a reference calls operator= on the class.

C++ has subtle interactions in many areas of the language, especially operator overloading, allowing you to override even assignment. If C++ can not do something apparently simple, there is probably a good reason for that, only obvious to those who know the spec inside out.

Re: How to design a replacement for C++

#65

If I recall correctly, D allows you to disable garbage collection and do your own memory management, and it does give the programmer a lot of power over how memory is managed, up to and including literally using C's malloc and free. I think it's more accurate to say that D has optional, on-by-default garbage collection. I still wouldn't write a kernel in it, and I can't agree more about D 2.0, but it's a bit misleadi…

Can anyone explain or provide a reference for the problems with D 2.0?

Re: How to design a replacement for C++

#66
post #61

Earlier quoted context omitted.

longjmp()?

No, that only lets you jump out - not e.g. jump between several suspended computations.

It raises a valid issue though: The article's author is operating under the assumption that any replacement language must be totally interoperable with C -- both calling and being called. If you have some crazy stack-reassignment logic in a new language, it will break a native C function's ability to longjmp out of a calling function written in the new language.

Re: How to design a replacement for C++

#67
post #45

Earlier quoted context omitted.

> but you can access the function version if you want, e.g. in glibc, getc() will call the macro, while (getc)() will call the function. Are you sure about this?

Yes (the macro must be define as #define getc(stream) ... of course, but that's the only legal definition anyway). ("Free-standing implementations" like kernels have a lot of freedom to muck with the standard library. But that's not really relevant.)

Ah okay, I understand what you meant now. One thing however - if it is a macro, couldn't it just be:

  #define getc fgetc_or_similar
At least C89/90 only mentions that if it is a macro, it may evaluate arguments more than once (but then it may not, as in the above case).

Re: How to design a replacement for C++

#68

1. Instead of the ability to directly call and be called by C/C++, include a really kick-ass Foreign Function Interface that can JIT the hookups and wrappers. And more important than call compatibility IMO is C++ object ABI compatibility. (I realize there is no universal C++ ABI; just pick one and be compatible with it.) If you can declare a struct or class in the language and make its layout match a C or C++ class/s…

> 3. No, mark-sweep garbage collection can be made to coexist with C++-style memory management.

GC depends on being able to find all valid pointers. C++ allows pointer games, like the xor trick for doubly-linked lists, which hide pointers. (It uses a single pointer field in each element to represent both the forward and backward pointer.)

GC can't collect things that are algorithmically inaccessible. There are algorithms that are efficient because they don't kill pointers to objects that are no longer in use.

I like GC, but there are costs.

Re: How to design a replacement for C++

#69
post #64

Some comments on your proposed additions (my other comments were about the proposed reductions): - I don't think .NET-style generics can be implemented in a statically typed language that doesn't have a common base class (e.g. everything derives from class Object). This is an oversimplification to say this but at some level generics are implemented as syntatic sugar for typecasts between Object and the type parameter…

Generics requiring type casts and a common base class is Java type-erasure braindeadness. CLR (.NET) generics compile separate code for each value type parameter, so you can have eg. vectors of structs, with the same performance as in C++. (for reference types, it uses the same code with an additional hidden "generic context" parameter, but that's an implementation detail). CLR has pass-by-value too, and although old…

I think this is probably true too, that they didn't want to have a separate operator just to reassign a reference. I think it could have been made to work, but just wasn't worth it.

Fortran for example has this - pointers in fortran behave like value types (like C++ references) when performing operations on them, however there is a special => operator to change the actual pointer. I never used operator overloading in fortran but I don't think it would be much of an issue, you would be able to overload the operator for anything except a pointer type.

Re: How to design a replacement for C++

#70
post #51

1. Instead of the ability to directly call and be called by C/C++, include a really kick-ass Foreign Function Interface that can JIT the hookups and wrappers. And more important than call compatibility IMO is C++ object ABI compatibility. (I realize there is no universal C++ ABI; just pick one and be compatible with it.) If you can declare a struct or class in the language and make its layout match a C or C++ class/s…

I think exceptions are an important language advance, but I can't dispute that they can cause a mess of problems when it comes to cross-language (or cross-thread) boundaries. Exceptions are not completely problem-free, but there is no alternative. If you don't have exceptions, every single line of code: doSomething(); Becomes: int result = doSomething(); if (result != OK) return result; ... and that is the simple cas…

Exceptions aren't the only solution though. Conditions/restarts in common lisp seem to be a more powerful but similar alternative.

One problem with exceptions is that they can only be one deep. Ie. if you are executing the code invoked by handling an exception, what should happen if another exception gets thrown. Java says forget about the old exception (ie. lose information), C++ says crash. Maybe there is something in between?

With or without exceptions, being error-safe is still really hard. I find you have to think "transactionally". For every operation you perform you have to think about what you need to clean up if it fails, so you focus on specifying what you want to do, not how you want to do it.

Post reply on HN