Author Topic: Design a better "C"  (Read 32070 times)

0 Members and 1 Guest are viewing this topic.

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #150 on: August 01, 2021, 10:50:41 am »
Of course C can be replaced.

C can be replaced and it will be. It has already reached its limits and we go on with a lot of troubles, but as until we work with 4-8 cores, we  go on with gritted teeth, with more than 32 cores it becomes rather a bloody hell.

The Linux kernel is another example. Yes, we have it, yes it has worked for 20 years, but ... if you look at how the code is maintained, and if you consider the complexity of the new kernel line v6 ... C doesn't help at all, C++ doesn't help at all, we need something better.

And Rust is probably the choice.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23017
  • Country: gb
Re: Design a better "C"
« Reply #151 on: August 01, 2021, 11:17:20 am »
I think we need to rethink the problems rather than come up with new solutions for the same problems. You mention parallelism as a deal breaker for C which arguably can be a problem. But a new language doesn’t necessarily solve those problems merely reshape them.

Hence my earlier point about clean room thinking. tggzzz will nod to this one but it belongs in the computer science domain. Think Hoare’s CSP paper. My first implementation of that for me was using pipes and stdio with a C program that had no concept of threads at all.

The language is rarely the problem. The environment and the thinking is.
« Last Edit: August 01, 2021, 11:22:54 am by bd139 »
 
The following users thanked this post: evb149

Offline PlainName

  • Super Contributor
  • ***
  • Posts: 6796
  • Country: va
Re: Design a better "C"
« Reply #152 on: August 01, 2021, 11:43:45 am »
Quote
the original C language only had a couple dozen keywords and a couple dozen fundamental types and a couple dozen basic operators

Perhaps that's its attraction: it is small enough to be entirely grasped by most programmers, yet remains a very sharp tool. It is the PH2 screwdriver of languages. Hex heads and star drives are great if someone else has done the work, but try putting an appropriate indent in a custom screw you just made.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19279
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Design a better "C"
« Reply #153 on: August 01, 2021, 12:14:04 pm »
I think we need to rethink the problems rather than come up with new solutions for the same problems. You mention parallelism as a deal breaker for C which arguably can be a problem. But a new language doesn’t necessarily solve those problems merely reshape them.

Hence my earlier point about clean room thinking. tggzzz will nod to this one but it belongs in the computer science domain. Think Hoare’s CSP paper. My first implementation of that for me was using pipes and stdio with a C program that had no concept of threads at all.

The language is rarely the problem. The environment and the thinking is.

Yes indeed, wit the proviso that a language can make it more or less practical to think and express high level design cleanly and unambiguously.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: evb149, bd139

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #154 on: August 01, 2021, 12:39:56 pm »
The language is rarely the problem. The environment and the thinking is.

C allows too many hipster bad habits.
New language, new bad habits, but also new fresh air, and new good habits.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23017
  • Country: gb
Re: Design a better "C"
« Reply #155 on: August 01, 2021, 01:08:56 pm »
Play chess one piece at a time, not smash the board and buy a new one…
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14297
  • Country: fr
Re: Design a better "C"
« Reply #156 on: August 01, 2021, 04:56:04 pm »
If you *need* integers of a known size then you can specify those with uint8_t, int_least32_t and friends. If you want an integer that a pointer can be converted to and from without loss you have uintptr_t. And so on. I don't know of any other language that allows you to express your actual needs so precisely. Maybe Ada?

Ada definitely, in a much, much better way.
But C is certainly a much simpler language requiring much simpler compilers. Which is a big plus in itself.

 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 151
  • Country: us
Re: Design a better "C"
« Reply #157 on: August 01, 2021, 04:57:29 pm »
C has often been described as a "high level assembly language".

C has often been incorrectly described as a "high level assembly language" by people who know little about C. FTFY.

The only version of C that could be called "high level assembly language" without stretching it too much was the nascent version described in various versions of "C Reference Manual" in the 1970s (https://www.bell-labs.com/usr/dmr/www/cman.pdf).

The very moment the K&R version came into existence, the idea of "high level assembly language" has been abandoned for good and forgotten.
« Last Edit: August 01, 2021, 04:59:15 pm by TheCalligrapher »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #158 on: August 01, 2021, 05:25:02 pm »
The only version of C that could be called "high level assembly language" without stretching it too much was

the compilers(1) I have on very old CP/M SBC boards ;D
 

(1) 1975-1989: Arnor C v1, Aztec C v1, BDS-C v1.6, Ecosoft C Compiler v3, HiTech C v3, HiSoft C v1, ManxC v1, Mi-C v3, Mix C Compiler v2, Q/C Compiler V3,  SIL-Digilog v1, Small C v2, Supersoft C v1, Whitesmith C v2, Amsterdam Compiler Kit v1
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #159 on: August 01, 2021, 05:33:31 pm »
C has often been described as a "high level assembly language".  Though awkwardly it specifies so little about the actual machine that you couldn't well USE it as anything like a portable assembly language!
How many bits per char?  Well..
How many bits per short..? int?  ...long?  long long?
How many bits per float? ... double?
Is the FP on this target SW or HW, IEEE-754 compatible or something totally other?
How are signed integers represented?  Two's complement?  One's complement? Sign magnitude?
How do you do things like arithmetic shifts / rotates involving signed quantities?
How about standard efficient portable bit-reverse, count leading / trailing zeroes?, count number of 1s in a word?  Calculate parity?  Set / Clear a bit at index? 
Can you load a multi-byte type from an unaligned address?  If so under which cases?  Is it efficient?
What about structure padding / packing?
Are pointers to different types convertible to each other? 
Pointer comparison and arithmetic valid / invalid cases?
What's this NULL pointer thing anyway -- 0 is a valid address sometimes!
Macros / preprocessor stuff that doesn't kind of suck?
Taking advantage of linker / assembler capabilities by a standard higher level "C" interface?
How do you even do something SUPER SIMPLE like detect flags relating to arithmetic / logical operations -- was there a carry?  Is the result 0? positive? negative? NaN? Inf? Denormalized? 
What about swizzling?  Byte swapping?  Endian conversion?
What about atomic operations on bits, bytes, fundamental data types?
Locks?  Semaphores? Mutexes?

Basically one can go on all day about things that C DOES NOT DO WELL in relationship to using it for bare metal down to the bit / byte / register / processor architecture specific level.  There SHOULD have been some attempt to standardize the C APIs for a lot of things that are
"commonly ubiquitous standard "intrinsic" or "builtin" operations.  Just an API / library interface to at least make it possible to express your INTENT to the compiler / assembler and whether a given machine implements that thing e.g. bit reverse efficiently in ASM or not the target specific code can at least portably generate something functional and relatively optimal if possible.  Compile time flags might have been defined like __HAS_FAST_BITREV_U32 or whatnot to allow compile time selection of faster alternatives for CODECs / FFTs / what not.

The other things that C is pretty useless for is high level programming.
For instance C++ container classes, or similar in python, java, etc.
In this day and age reinventing linked lists, hash tables, vectors, heaps, sorting, iterating, basically any container or <algorithm> etc. is a waste of time in C compared to what one can do in 6 lines of C++ code using containers / algorithm / STL.

What the relevant "higher level languages" should implement is some kind of "C like" "unsafe" or "low level" mode / library / API / domain specific language to let one express medium-low-ish level algorithms that are machine specific and should have native-ish performance in the high level language but allow it to generate / use efficient code -- that can't be hard the original C language only had a couple dozen keywords and a couple dozen fundamental types and a couple dozen basic operators.   Also considerable effort should have been made to allow call / runtime interoperability between "C" linking / libraries and high level languages and where sensible the reverse. 

Then for productivity and high level programming use the high level languages and for lower level data structure or machine interfacing use the "C like / better than C" low level system library from the HLL...and if you want / need to go all the way to ASM level at least create some portable APIs / intrinsics / language expressions that map to the many of the algorithmic / data type / ALU "hidden corners" you can't portably express even in C.


Precisely the points  :clap:

And what about monads? The lack of monads is the reason why C needs gotos, and it's the reason why the critical sections of every OS looks a mess ... hard to understand, debug, and maintain.

I want monads, please give me monads, I can have monads in a functional language like eRlang, but monads can be also implemented in every imperative language, so add monads to C!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: evb149

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14297
  • Country: fr
Re: Design a better "C"
« Reply #160 on: August 01, 2021, 05:34:16 pm »
Just a wake-up call. Every x years there's a new language that will replace C.

Yes yes, I started right away saying this. Nobody needs to be waken up in this thread, I'm pretty sure.

The main reason why C still sticks, apart from its own merits (and it has a lot of them obviously despite some of its shortcomings), is just that it's become industry-standard and is standardized. With actually a decent standard. Yeah, I know some may whine about it, but just take a look at the C++ standard, and come back. I think you'll see how good the C standard is after that quick adventure.

The whole point of this thread was collectively figuring out what features could make C better without compromising any of its fundamental benefits. For this, I think we have gotten a few points that I'll summarize here (likely not exhaustive at all):
- Better, more consistent arithmetics;
- Partly related: no risky implicit conversions;
- Much fewer, or ideally no undefined behaviors;
- Modules;
- Constrained types (such as ranges) - could also be used for bound checking when indexing arrays/buffers;
- Tagged blocks, for easier and more consistent flow control;
- Getting rid of the C switch with fall-through;

Points about parallelism have been made, but as some have said, I'm not too sure having built-in support in the language would dramatically change things, part from sugar coating. It may make the developers' life a bit easier, but for a dramatic change, different computer architectures more adapted to parallelism should probably be devised first. Another thing to consider with this is that built-in support for parallelism almost inevitably implies offloading the nasty work to some runtime. It's kinda displacing the problem without fundamentally solving it.

Of course another point was, as a corollary, to figure out what exactly would prevent any new language from taking off. The mere fact that those "are not C" partly explains this - see above - but there are oither reasons. As discussed earlier, one big problem is that most of those attempts have been lacking pragmatism, have essentially been one-person projects (so, way too opiniated approaches, lacking proper reviews of real-world practices), and have been much, much too complex. Yeah. If you wanna avoid the pitfalls of C++, do not fall into the same trap! Too complex languages with a bunch of programming paradigms stacked together are confusing, almost impossible to master, promote language fragmentation (which hinders maintenance), tend to make developers misuse them, make developing compilers a hell, the list is long...

Yeah, Rust is nice, but IMHO it has fallen into this exact trap heads down.

As to C++, I've found this "FQA" rather to the point: http://yosefk.com/c++fqa/index.html , and this can also trigger some thinking if you're ever considering designing a new language.

« Last Edit: August 01, 2021, 05:36:04 pm by SiliconWizard »
 
The following users thanked this post: evb149, Just_another_Dave

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23017
  • Country: gb
Re: Design a better "C"
« Reply #161 on: August 01, 2021, 05:38:56 pm »
You can write monads in C fine. Just you have to do some of the legwork that the higher languages compile away  :-//
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #162 on: August 01, 2021, 06:11:06 pm »
You can write monads in C fine.

You can also write polymorphism in C, and I usually do, but you have NO help from the C compiler, and this is the point! I want the compiler to help me!

To have monads in C, you have to write polymorphic code, plus other stuff, and the result is ... ugly to read, also when I write  polymorphic code, there is no "(inner) this" mechanism like in C++, therefore I need to pass p_this_t (void*) pointers among methods (which are not truly "methods" but rather pointers to special functions), also because the C language has no support for opaque pointers, no support for methods, and also no concept of module, and again ... it's possible to "implement them", I can even mimics modules and opaque pointers, I can do everything, but the compiler is not helping me at all, and the code written this way is prone to contain bugs.

The Linux kernel needs this stuff, and for a lot of reason Linus hates doing this stuff in C++, so ... it's like trying to drive a nail into the wall with a screwdriver rather than a hammer.

We don't need all the bloated features offered by C++, just a couple of features, and for example Visual Pascal offers try {} catch {} error {} statements, which are close to monads and it's better than nothing.

With full monads you can embedded the behavior within a datatype, and it's really great to have! Elegant, powerful, and it automatically makes the code more robust since a lot of programmers are so lazy they don't write all the code to cover the abnormal functioning in case of errors, because without native-monads you have to write many more lines of code. I can understand them.

Seriously, I'd like to avoid to continuously hack the C compiler, I'd prefer to have native support.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: evb149

Offline Karel

  • Super Contributor
  • ***
  • Posts: 2214
  • Country: 00
Re: Design a better "C"
« Reply #163 on: August 01, 2021, 06:31:58 pm »
The whole point of this thread was collectively figuring out what features could make C better without compromising any of its fundamental benefits.

I understand it's interesting to talk about it, but we all do know that nobody is going to use this this information
and after another 20 years or so, C will still "rule"...

 :popcorn:
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19279
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Design a better "C"
« Reply #164 on: August 01, 2021, 09:16:02 pm »
The whole point of this thread was collectively figuring out what features could make C better without compromising any of its fundamental benefits.

I understand it's interesting to talk about it, but we all do know that nobody is going to use this this information
and after another 20 years or so, C will still "rule"...

 :popcorn:

... In the same way that COBOL still rules, I hope
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14297
  • Country: fr
Re: Design a better "C"
« Reply #165 on: August 02, 2021, 05:08:37 pm »
You can also write polymorphism in C, and I usually do, but you have NO help from the C compiler, and this is the point! I want the compiler to help me!

Yeah. Well, generally implementing "OO" stuff in C is doable (and I do this). It does require manual handling of many things, and sure you don't get any help from the compiler. OTOH, it doesn't necessarily require a lot more LOCs than a C++ equivalent. It just looks different, and you have approximately zero safety net.

To have monads in C, you have to write polymorphic code, plus other stuff, and the result is ... ugly to read,

Yeah. Monads? That can get pretty hairy. That's not something I would have considered adding to C. Drifting too far off there.

The Linux kernel needs this stuff, and for a lot of reason Linus hates doing this stuff in C++, so ... it's like trying to drive a nail into the wall with a screwdriver rather than a hammer.

I'd be interested in knowing exactly why the Linux kernel would need "monads". Can you elaborate on this and maybe give a couple examples?

As to C++, I really suggest reading the "FQA" I linked to above. It's a relatively comprehensive analysis of the official C++ FAQ, taking answers and elaborating on them, often "debunking" them as well. After reading this, unless you're a die-hard C++ developer, you're likely to have a more definitive understanding of why many people "hate" C++, and why you probably shouldn't use it. You'll also get to see that many answers given in the official C++ FAQ are either ill-devised, or just dishonest. That also doesn't bode well IMHO.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #166 on: August 02, 2021, 07:30:26 pm »
The Linux kernel is programmed like if it was object-programming but without object programming support, and all the exception points are manually encoded and usually expressed with "goto".

Gotos are good and extremely efficient for critical sections, and they are not the problem, rather the reason why you need to write gotos is the problem: you write goto because the language has no support for the error propagation.

With monads, you can define the abnormal behavior of something and embed it into a datatype, and the code will react like defined, you don't need to write any goto, you can plan and study the error propagation, and to do that you don't need to manually instruments the code to make sure you haven't forgotten something, it's rather the compiler that truly helps you.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14297
  • Country: fr
Re: Design a better "C"
« Reply #167 on: August 02, 2021, 10:47:26 pm »
OK, thanks for the point.

So, basically, what you would like is something to help with error handling. Indeed C is very "rough" with that, and error handling is almost always tedious and clunky.
And, OTOH, exceptions have been proven not to be a very good answer to that in general.

Problem with monads, as I see it, is that they really make sense only for a functional programming language. In particular, they reveal their potential when you heavily use function composition. C is not a functional language, and I don't think anyone would want it to become one. I've seen attempts at implementing monads in non-functional programming languages, and all were trying to indeed implement some kind of functional approach in a language not made for this. Often clunky, inefficient and inconsistent.

Or maybe you have in mind something like monads in spirit, but adapted to a non-functional language. If so, I'd be curious to read you elaborate on it a little.

Now the point of adding features to improve error handling, and do it better than exceptions, is duly taken anyway.

 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 3996
  • Country: nz
Re: Design a better "C"
« Reply #168 on: August 02, 2021, 10:58:21 pm »
OK, thanks for the point.

So, basically, what you would like is something to help with error handling. Indeed C is very "rough" with that, and error handling is almost always tedious and clunky.
And, OTOH, exceptions have been proven not to be a very good answer to that in general.

Not sure I agree with that.

I do agree that the way C++ and Java do exceptions sucks.

I like much more the model where the handler is called *before* unwinding the stack, and has the option of resolving the problem and returning to the place the error occurred.
 
The following users thanked this post: DiTBho

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14297
  • Country: fr
Re: Design a better "C"
« Reply #169 on: August 02, 2021, 11:32:17 pm »
OK, thanks for the point.

So, basically, what you would like is something to help with error handling. Indeed C is very "rough" with that, and error handling is almost always tedious and clunky.
And, OTOH, exceptions have been proven not to be a very good answer to that in general.

Not sure I agree with that.

I do agree that the way C++ and Java do exceptions sucks.

I like much more the model where the handler is called *before* unwinding the stack, and has the option of resolving the problem and returning to the place the error occurred.

Well, can you point me to a language that would, in your opinion, implement exceptions "right"?
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 3996
  • Country: nz
Re: Design a better "C"
« Reply #170 on: August 03, 2021, 01:40:24 am »
OK, thanks for the point.

So, basically, what you would like is something to help with error handling. Indeed C is very "rough" with that, and error handling is almost always tedious and clunky.
And, OTOH, exceptions have been proven not to be a very good answer to that in general.

Not sure I agree with that.

I do agree that the way C++ and Java do exceptions sucks.

I like much more the model where the handler is called *before* unwinding the stack, and has the option of resolving the problem and returning to the place the error occurred.

Well, can you point me to a language that would, in your opinion, implement exceptions "right"?

Dylan and its predecessor, Common Lisp.

https://opendylan.org/books/drm/Conditions

https://en.wikibooks.org/wiki/Common_Lisp/Advanced_topics/Condition_System

https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
« Last Edit: August 03, 2021, 01:42:42 am by brucehoult »
 
The following users thanked this post: DiTBho

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3452
  • Country: it
Re: Design a better "C"
« Reply #171 on: August 03, 2021, 05:58:24 pm »
Rush is not too bad  :-//

Rush is awesome
 
The following users thanked this post: SiliconWizard

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: Design a better "C"
« Reply #172 on: August 04, 2021, 09:19:26 am »
Without monads that can trap errors before unrolling the stack, at least I would like C to force the user to always initialize a variable.

Code: [Select]
private p_char_t boolean_test_ans[2] = { "failure", "success" };

In this example one of my customers made a mess with my code by badly copying and past a procedure.
As result, he forgot to initialize a variable to value False before the test

Code: [Select]
boolean_t test_result;

if (...)
{
     test_result=....
}
printf("test %s: %s\n", test_name, boolean_test_ans[test_result]);

since test_result is only set inside the if () {}  block, if the block is not executed test_result is not initialized, and as result it can assume randoms values.

The result is catastrophic, because  boolean_test_ans points to a random address in memory.


The initialization of variables is a better practice, it should be mandatory !
Code: [Select]
boolean_t test_result=False;

if (...)
{
     test_result=....
}
printf("test %s: %s\n", test_name, boolean_test_ans[test_result]);

Please add it to the list  :D
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Just_another_Dave

  • Regular Contributor
  • *
  • Posts: 192
  • Country: es
Re: Design a better "C"
« Reply #173 on: August 04, 2021, 11:48:40 am »
Without monads that can trap errors before unrolling the stack, at least I would like C to force the user to always initialize a variable.

Code: [Select]
private p_char_t boolean_test_ans[2] = { "failure", "success" };

In this example one of my customers made a mess with my code by badly copying and past a procedure.
As result, he forgot to initialize a variable to value False before the test

Code: [Select]
boolean_t test_result;

if (...)
{
     test_result=....
}
printf("test %s: %s\n", test_name, boolean_test_ans[test_result]);

since test_result is only set inside the if () {}  block, if the block is not executed test_result is not initialized, and as result it can assume randoms values.

The result is catastrophic, because  boolean_test_ans points to a random address in memory.


The initialization of variables is a better practice, it should be mandatory !
Code: [Select]
boolean_t test_result=False;

if (...)
{
     test_result=....
}
printf("test %s: %s\n", test_name, boolean_test_ans[test_result]);

Please add it to the list  :D

Being able to define a default value for specific types could also be a solution for that problem, as it avoids having to set an initial value for each variable, which would require to modify existing programs to be able to be able to compile them, while eliminating random behaviors
 

Offline PlainName

  • Super Contributor
  • ***
  • Posts: 6796
  • Country: va
Re: Design a better "C"
« Reply #174 on: August 04, 2021, 12:37:41 pm »
gcc, and I presume other compilers, will warn when this occurs. If this - setting a value on declaration - was mandated I would prefer to have it default to nul if nothing is specified. And for the compiler to continue to warn (that is, ignoring that it's defaulted to nul and treat it as uninitialised).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf