Around the same time I was skeptical about the approach of the HP PA-RISC successor,ItanicItanium. At that time any tiny change to the implementation required someone to re-hand-optimise inner loops; the compiler was supposed to solve that issue, but never quite managed it. In addition, just as CPU power consumption was becoming the limiting factor, the Itanic strategy was to waste power doing lots of speculative execution.It was obvious from the very start of Itanium development that its strategy would make for extremely high power consumption. So, it seemed to be a strategy to split the market into mobile and non-mobile threads. That was always a very weird strategy for a company like Intel, when notebooks were a booming business.
I've been pondering the idea of attempting to create a new (compiled) programming language specifically designed for hardware programming... tldr...
This is not as crazy as it might at first appear, I'm a very experienced software developer
So of course we can discuss what the language can do, go ahead I've been asking for some nine pages now! For example I recently said that I think the language should support runtime access to metadata like string capacity/lengths, arrays dimensions and bounds and so on. The C language is - IMHO - rather poor in that area, so lets address that.
Accessing implementation internals like string capacity/length, but isn't that exactly where C is the best tool you have? Higher level languages hide all such implementation details in their string classes (that's the whole point). In C, such string type does not exist, you have to create your own, which also means you have access to everything you want, and exactly as you want. More work, but this is why embedded developers with limited resources prefer C.
Arrays are indeed a weak point in C, being too primitive and requiring you to babysit implementation details, but if you did actually read any of this thread, it has been discussed in numerous replies above, mostly by Mr. N. Animal. No need to complain about this not being discussed.
On the other hand, people often write crappy code like this, as taught in classes:Code: [Select]#define ARRAY_LEN
unsigned char array[ARRAY_LEN] = {1, 2, 3, 4};
for(int i=0; i<ARRAY_LEN; i++)
...
When C is much more capable:Code: [Select]uint8_t array[] = {1, 2, 3, 4}; // automagic array length!
for(int i=0; i<NUM_ELEM(array); i++) // despite being automagic, length is still known, at compile time! Googling the NUM_ELEM helper macro is left as an excercise for reader. Add to utils.h or something
...
Of course still quite primitive, but... We manage! And those who complain, often do not even know what we have available. As I said earlier, use C to its fullest, and it's not as crappy as some lazy examples from 1980's seem like.
Around the same time I was skeptical about the approach of the HP PA-RISC successor,ItanicItanium. At that time any tiny change to the implementation required someone to re-hand-optimise inner loops; the compiler was supposed to solve that issue, but never quite managed it. In addition, just as CPU power consumption was becoming the limiting factor, the Itanic strategy was to waste power doing lots of speculative execution.It was obvious from the very start of Itanium development that its strategy would make for extremely high power consumption. So, it seemed to be a strategy to split the market into mobile and non-mobile threads. That was always a very weird strategy for a company like Intel, when notebooks were a booming business.
Intel did not design the Itanic architecture. HP designed the Itanic.
The objective was simple. In 1989 it was known that HP PA-RISC would run out of steam in a decade's time. When that became significant to customers, they would look for alternatives. What became the Itanic was simply a means of keeping customers buying HP PA-RISC machines. By the mid to late 90s that was the server market.
I've been pondering the idea of attempting to create a new (compiled) programming language specifically designed for hardware programming... tldr...
This is not as crazy as it might at first appear, I'm a very experienced software developerleave the job to computer scientists and linguists, or at least, go discuss with them. what you are trying to do is like a very experienced engineer who want to lay a new theoritical physics in quantum mechanics. you may ended up reinventing the wheel or may not know what you are dealing with.. if you have to ask here, you are not the man trust me, i'm sorry to break the mood.. i'm not the man, nor most of us here. so rather than keep heated arguing endlessly, like a bunch of experienced engineers discussing about quantum mechanics that they have no clue about... find some reading materials about what a "computer programming language" is all about.. its a classical knowledge nothing new, C/C++ language was designed to be as low level as it can get while maintaining human readable syntax and avoid coupling to certain machine architecture, but generic and compatible enough for all. if you think you can do better, show your working proof. just a blueprint or "list of ideas" will not be enough. try do it actually and you may find the actual barrier in the middle of your journey. just "list of ideas" is easy to brag about. if you have to ask me what features i want in a programming language? i would say none! C/C++ provides me all i need to convert the semantic of procedural processes into machine readable (actual working) processes, through subroutines, definitions etc. if you think you have struggled in embedded system, i doubt your proficiency as a software developer, esp if you cannot differentiate between what a "language" and "compiler" and "machine dependent codes" is? you can make a parser or a compiler not necessarily you can make a new "language". cheers, ymmv.
Many high level languages actually let you find the current and maximum lengths of strings or the rank and bound of arrays at runtime. C does not, sure you can write code to somehow create abstractions that do that if you really want, but that's really what languages are for, to reduce the need for such drudgery.
Many high level languages actually let you find the current and maximum lengths of strings or the rank and bound of arrays at runtime. C does not, sure you can write code to somehow create abstractions that do that if you really want, but that's really what languages are for, to reduce the need for such drudgery.at what cost? as a language designer, you should already have the answer in your belt.
btw, you can start designing one "highly managed" language if you want to, you can start a list of mostly used features and we would love to try... if what you have in mind is that (highly managed language), looking at C is a bad start. start looking at other highly managed language such as maybe Python? or Rust? or whatever, i dont know, i'm not a proficient "all languages" programmer... C is not a managed language. but most people use it. its like automatic car vs manual car. both will have market. i choose manual car... lets see if one day manual car extinct.
func get_fastest_motors_speed (X) float(binary(128)) optimize(speed) determinate
{
arg X binary(16);
return (something);
}
Well you need to define "cost" first and you haven't.
Well you need to define "cost" first and you haven't."resources" cost, mcu storage space and RAM to store all those drudgery avoidance codes. your language may not run very well in atTiny mcu, or asks for larger ARM processor etc. its inevitable... this will open to endless debate. so just make one and put it into the ring, lets see who takes the bait.
dcl usernames(1024) string(64); // array of 1024 strings - total metadata is 2 bytes in this specific example.
func parse_text (text) bool
{
arg text string(*);
L = length(text); // Get the capacity of this fixed length string
}
dcl usernames(1024) string(64) opaque; // array of 1024 strings - no string metadata
dcl gradenames(1024) opaque string(64) opaque; // array of 1024 strings - no string metadata no array metadata
/* or */
dcl usernames(1024) string(64,opaque); // array of 1024 strings - no string metadata
dcl gradenames(1024,opaque) string(64,opaque); // array of 1024 strings - no string metadata no array metadata
Around the same time I was skeptical about the approach of the HP PA-RISC successor,ItanicItanium. At that time any tiny change to the implementation required someone to re-hand-optimise inner loops; the compiler was supposed to solve that issue, but never quite managed it. In addition, just as CPU power consumption was becoming the limiting factor, the Itanic strategy was to waste power doing lots of speculative execution.It was obvious from the very start of Itanium development that its strategy would make for extremely high power consumption. So, it seemed to be a strategy to split the market into mobile and non-mobile threads. That was always a very weird strategy for a company like Intel, when notebooks were a booming business.
Intel did not design the Itanic architecture. HP designed the Itanic.
The objective was simple. In 1989 it was known that HP PA-RISC would run out of steam in a decade's time. When that became significant to customers, they would look for alternatives. What became the Itanic was simply a means of keeping customers buying HP PA-RISC machines. By the mid to late 90s that was the server market.
Explicit support for fixed-point numbers is provided by a few computer languages, notably PL/I, COBOL, Ada, JOVIAL, and Coral 66. They provide fixed-point data types, with a binary or decimal scaling factor. The compiler automatically generates code to do the appropriate scaling conversions when doing operations on these data-types, when reading or writing variables, or when converting the values to other data types such as floating-point.
Moreover, in 2008 the International Standards Organization (ISO) issued a proposal to extend the C programming language with fixed-point data types, for the benefit of programs running on embedded processors.[3] Also, the GNU Compiler Collection (GCC) has back-end support for fixed-point.[4][5]
Digital Signal Processors have traditionally supported fixed-point arithmetic in hardware. But more recently, many DSP-enhanced RISC processors are starting to support fixed-point data types as part of their native instruction set. When the precision requirements of the application can be met with fixed-point arithmetic, then this is preferred since it can be smaller and more efficient than floating-point hardware. DSP algorithms often represent the data samples and the coefficients used in the computation as fractional numbers (between -1 and +1) to avoid magnitude growth of a multiplication product. Fractional data type, where there are zero integer bits, is a subset of the more general fixed-point data type.
The fixed-point types are
short _Fract,
_Fract,
long _Fract,
long long _Fract,
unsigned short _Fract,
unsigned _Fract,
unsigned long _Fract,
unsigned long long _Fract,
_Sat short _Fract,
_Sat _Fract,
_Sat long _Fract,
_Sat long long _Fract,
_Sat unsigned short _Fract,
_Sat unsigned _Fract,
_Sat unsigned long _Fract,
_Sat unsigned long long _Fract,
short _Accum,
_Accum,
long _Accum,
long long _Accum,
unsigned short _Accum,
unsigned _Accum,
unsigned long _Accum,
unsigned long long _Accum,
_Sat short _Accum,
_Sat _Accum,
_Sat long _Accum,
_Sat long long _Accum,
_Sat unsigned short _Accum,
_Sat unsigned _Accum,
_Sat unsigned long _Accum,
_Sat unsigned long long _Accum.
QuoteThe fixed-point types are
short _Fract,
_Fract,
long _Fract,
long long _Fract,
unsigned short _Fract,
unsigned _Fract,
unsigned long _Fract,
unsigned long long _Fract,
_Sat short _Fract,
_Sat _Fract,
_Sat long _Fract,
_Sat long long _Fract,
_Sat unsigned short _Fract,
_Sat unsigned _Fract,
_Sat unsigned long _Fract,
_Sat unsigned long long _Fract,
short _Accum,
_Accum,
long _Accum,
long long _Accum,
unsigned short _Accum,
unsigned _Accum,
unsigned long _Accum,
unsigned long long _Accum,
_Sat short _Accum,
_Sat _Accum,
_Sat long _Accum,
_Sat long long _Accum,
_Sat unsigned short _Accum,
_Sat unsigned _Accum,
_Sat unsigned long _Accum,
_Sat unsigned long long _Accum.
I make no apologies for saying this notation is quite ridiculous, it is retrograde, looking more like some 1940s primitive machine code than a 21st century programming language. Of course if the grammar restricts the flexibility for supporting new data types then perhaps the proponents of this can be forgiven.
This is precisely the kind of stuff I was really hoping to hear more about from engineers here, these are precisely the kinds of expansions of language capabilities that I've been talking about, this is why grammar is so so important, the C grammar is a great example of technical debt that has grown and grown and grown.
QuoteThe fixed-point types are
short _Fract,
_Fract,
long _Fract,
long long _Fract,
unsigned short _Fract,
unsigned _Fract,
unsigned long _Fract,
unsigned long long _Fract,
_Sat short _Fract,
_Sat _Fract,
_Sat long _Fract,
_Sat long long _Fract,
_Sat unsigned short _Fract,
_Sat unsigned _Fract,
_Sat unsigned long _Fract,
_Sat unsigned long long _Fract,
short _Accum,
_Accum,
long _Accum,
long long _Accum,
unsigned short _Accum,
unsigned _Accum,
unsigned long _Accum,
unsigned long long _Accum,
_Sat short _Accum,
_Sat _Accum,
_Sat long _Accum,
_Sat long long _Accum,
_Sat unsigned short _Accum,
_Sat unsigned _Accum,
_Sat unsigned long _Accum,
_Sat unsigned long long _Accum.
I make no apologies for saying this notation is quite ridiculous, it is retrograde, looking more like some 1940s primitive machine code than a 21st century programming language. Of course if the grammar restricts the flexibility for supporting new data types then perhaps the proponents of this can be forgiven.
This is precisely the kind of stuff I was really hoping to hear more about from engineers here, these are precisely the kinds of expansions of language capabilities that I've been talking about, this is why grammar is so so important, the C grammar is a great example of technical debt that has grown and grown and grown.I think its time the C standard flipped things around, and started with length specific types, and derived bland vague names, like int and short int, from the specific ones - mostly for backwards compatibility and places where the size of the variable is essentially irrelevant, like a small loop counter.
...float(dec(32)), float(dec(64)), float(dec(128))
...float(bin(16)), float(bin(32)), float(bin(64)), float(bin(128)), float(bin(256))
float(bin(16)) or half
float(bin(32)) or single
float(bin(64)) or double
float(bin(128)) or quad
float(bin(256)) or oct
‘hr’ or ‘HR’ for short _Fract and _Sat short _Fract
‘r’ or ‘R’ for _Fract and _Sat _Fract
‘lr’ or ‘LR’ for long _Fract and _Sat long _Fract
‘llr’ or ‘LLR’ for long long _Fract and _Sat long long _Fract
‘uhr’ or ‘UHR’ for unsigned short _Fract and _Sat unsigned short _Fract
‘ur’ or ‘UR’ for unsigned _Fract and _Sat unsigned _Fract
‘ulr’ or ‘ULR’ for unsigned long _Fract and _Sat unsigned long _Fract
‘ullr’ or ‘ULLR’ for unsigned long long _Fract and _Sat unsigned long long _Fract
‘hk’ or ‘HK’ for short _Accum and _Sat short _Accum
‘k’ or ‘K’ for _Accum and _Sat _Accum
‘lk’ or ‘LK’ for long _Accum and _Sat long _Accum
‘llk’ or ‘LLK’ for long long _Accum and _Sat long long _Accum
‘uhk’ or ‘UHK’ for unsigned short _Accum and _Sat unsigned short _Accum
‘uk’ or ‘UK’ for unsigned _Accum and _Sat unsigned _Accum
‘ulk’ or ‘ULK’ for unsigned long _Accum and _Sat unsigned long _Accum
‘ullk’ or ‘ULLK’ for unsigned long long _Accum and _Sat unsigned long long _Accum
dcl counter fixed bin (P,S);
dcl counter1 fixed bin (18,7); // precision=18, scale=7
dcl counter2 fixed bin (29,3);
dcl counter2 fixed bin (30,-6);
Interesting presentation on the difference between a coroutine and a thread:
https://www.educba.com/coroutines-vs-threads/
If the language is going to be used for IoT or Edge computing, it might be helpful to have parallel computing as part of the language. Fortran already has this feature as part of the language specification.
By parallelism are you thinking of multiple cores? or preemptive multitasking on a single core?