On 21/08/2021 11:32, James Harris wrote:
On 20/08/2021 19:50, David Brown wrote:
I'd recommend looking at C++ templates. You might not want to follow
all the details of the syntax, and you want to look at the newer and
better techniques rather than the old ones. But pick a way to give
compile-time parameters to types, and then use that - don't faff around
with special cases and limited options. Pick one good method, then you >>> could have something like this :
builtin::int<32> x;
using int32 = builtin::int<32>;
int32 y;
That is (IMHO) much better than your version because it will be
unambiguous, flexible, and follows a syntax that you can use for all
sorts of features.
My version of that would be
typedef i32 = int 32
int 32 x
i32 y
Punctuation here is not /necessary/, but it would make the code far
easier to read, and far safer (in that mistakes are more likely to be
seen by the compiler rather than being valid code with unintended meaning).
Your C++ version doesn't seem to be any more precise or flexible.
What happens when you have a type that should have two parameters - size
and alignment, for example? Or additional non-integer parameters such
as signedness or overflow behaviour? Or for container types with other
types as parameters? C++ has that all covered in a clear and accurate
manner - your system does not.
My intention here is to encourage you to think bigger. Stop thinking
"how do I make integer types?" - think wider and with greater generality
and ambition. Make a good general, flexible system of types, and then
let your integer types fall naturally out of that.
Perhaps even look at the metaclasses proposal <https://www.fluentcpp.com/2018/03/09/c-metaclasses-proposal-less-5-minutes/>.
This will not be in C++ before C++26, maybe even later, but it gives a whole new way of building code. If metaclasses had been part of C++
from the beginning, there would be no struct, class, enum, or union in
the language - these would have been standard library metaclasses. They
are /that/ flexible.
Ultimately, things like macros, templates, generics, metafunctions,
etc., are just names for high-level compile-time coding constructs.
On 21/08/2021 19:11, David Brown wrote:
On 21/08/2021 11:32, James Harris wrote:
On 20/08/2021 19:50, David Brown wrote:
...
I'd recommend looking at C++ templates. You might not want to follow >>>> all the details of the syntax, and you want to look at the newer and
better techniques rather than the old ones. But pick a way to give
compile-time parameters to types, and then use that - don't faff around >>>> with special cases and limited options. Pick one good method, then you >>>> could have something like this :
builtin::int<32> x;
using int32 = builtin::int<32>;
int32 y;
That is (IMHO) much better than your version because it will be
unambiguous, flexible, and follows a syntax that you can use for all
sorts of features.
My version of that would be
typedef i32 = int 32
int 32 x
i32 y
Punctuation here is not /necessary/, but it would make the code far
easier to read, and far safer (in that mistakes are more likely to be
seen by the compiler rather than being valid code with unintended
meaning).
Noted.
Your C++ version doesn't seem to be any more precise or flexible.
What happens when you have a type that should have two parameters - size
and alignment, for example? Or additional non-integer parameters such
as signedness or overflow behaviour? Or for container types with other
types as parameters? C++ has that all covered in a clear and accurate
manner - your system does not.
That's not wholly true. Specific terms and syntax are not yet decided
but I do have the concept of qualifiers. For example,
int 32 x
int 32 alignbits 3 y
In that, y would be required to be aligned such that the bottom 3 bits
of its address were zero.
However, the syntax is not yet chosen and if as you suggest the use of punctuation would not be onerous I would prefer the addition of the
colon as in
int 32: x
int 32 alignbits 3: y
The additional colon would make parsing by compiler and by human easier.
I have omitted it up until now as I could imagine that programmers would
not want to have to type it in simple declarations such as
int: i
but maybe that doesn't look too bad.
My intention here is to encourage you to think bigger. Stop thinking
"how do I make integer types?" - think wider and with greater generality
and ambition. Make a good general, flexible system of types, and then
let your integer types fall naturally out of that.
The goal is that range specifications would apply anywhere relevant, not
just for integers. For example,
array (5..15) floati32: v
would declare an array of between 5 and 15 elements of type floati32.
One might use that as a parameter declaration to require that what gets passed in has to be an array which matches within certain size limits.
I take your point on board but I don't know that my syntax can be made
more general without getting in to either variants or generics.
...
Perhaps even look at the metaclasses proposal
<https://www.fluentcpp.com/2018/03/09/c-metaclasses-proposal-less-5-minutes/>.
This will not be in C++ before C++26, maybe even later, but it gives a
whole new way of building code. If metaclasses had been part of C++
from the beginning, there would be no struct, class, enum, or union in
the language - these would have been standard library metaclasses. They
are /that/ flexible.
I've been looking at some material by one of the proposers, Herb Sutter.
A proper discussion about such things needs a topic of its own but I
should say here that my fundamental reaction is not favourable. He effectively acknowledges that the more such proposals complicate a
language the more a programmer has to depend on tools to help understand program code and that's a step too far for me at present.
One of Sutter's justifications for metaclasses is that they help remove
a lot of boilerplate from C++ code and, on that, ISTM that the problem
may be the presence of the boilerplate in the first place. I don't know enough C++ but ATM I am not sure I'd have the boilerplate to remove.
As a wider point, I've previously seen Python become more 'clever'. And
it has become less comprehensible as a result. C++ is already alarmingly complex. Sutter's proposals would make it more so. In both cases ISTM
that people who are unhealthily immersed in the language (Python, C++)
see ways to be even cleverer and that makes a language worse. I believe similar has happened with Ada and JavaScript. C, by contrast, despite
some enhancements has remained pleasantly small and focussed.
I'll keep metaclasses in mind but ATM they are in the bucket with other
ideas for code customisation such as those you list here:
Ultimately, things like macros, templates, generics, metafunctions,
etc., are just names for high-level compile-time coding constructs.
On 26/11/2021 19:41, James Harris wrote:
That's not wholly true. Specific terms and syntax are not yet decided
but I do have the concept of qualifiers. For example,
int 32 x
int 32 alignbits 3 y
In that, y would be required to be aligned such that the bottom 3 bits
of its address were zero.
Before you try to think out a syntax here, ask yourself /why/ someone
would want this feature. What use is it? What are the circumstances
when you might need non-standard alignment? What are the consequences
of it? If this is something that is only very rarely useful (and I
believe that is the case here - but /you/ have to figure that out for
your language), there is no point going out of your way to make it easy
to write. Common things should be easy to write - rare things can be
hard to write.
So for me, your "alignbits 3" is just wrong - it makes no sense. You
are trying to say it should be aligned with 8-byte alignment, also known
as 64-bit alignment. Obviously I can figure out what you meant - there really isn't any other possibility for "alignbits 3". But if you had
written "alignbits 8", I would take that to mean a packed or unaligned declaration, not one with 256-byte alignment.
The additional colon would make parsing by compiler and by human easier.
I have omitted it up until now as I could imagine that programmers would
not want to have to type it in simple declarations such as
int: i
but maybe that doesn't look too bad.
I only know one person who regularly complains about having to use punctuation and finds it inconvenient to type symbols. But even he uses punctuation at times in his languages.
(On the other hand, too much punctuation makes code harder to read and
write. As with most things, you want a happy medium.)
My intention here is to encourage you to think bigger. Stop thinking
"how do I make integer types?" - think wider and with greater generality >>> and ambition. Make a good general, flexible system of types, and then
let your integer types fall naturally out of that.
The goal is that range specifications would apply anywhere relevant, not
just for integers. For example,
array (5..15) floati32: v
would declare an array of between 5 and 15 elements of type floati32.
Unless a language was just a simple, limited scripting tool, I would not bother making (or learning) a new language that did not have features
such as variants or generics (noting that these terms are vague and mean different things to different people). There are perfectly good
languages without such features. Given the vast benefits of C in terms
of existing implementation, code, experience and information, why would anyone bother with a different compiled language unless it let them do
things that you cannot easily do in C? Being able to make your own
types, with their rules, invariants, methods, operators, etc., is pretty
much a basic level feature for modern languages. Generic programming is standard. I would no longer consider these as advanced or complex
features of a modern language, I'd consider them foundational.
On 27/11/2021 15:17, David Brown wrote:
On 26/11/2021 19:41, James Harris wrote:
My intention here is to encourage you to think bigger. Stop thinking >>>> "how do I make integer types?" - think wider and with greater
generality
and ambition. Make a good general, flexible system of types, and then >>>> let your integer types fall naturally out of that.
The goal is that range specifications would apply anywhere relevant, not >>> just for integers. For example,
array (5..15) floati32: v
would declare an array of between 5 and 15 elements of type floati32.
(No. That's just not what anyone would guess that to mean. It looks like
an array of length 11 indexed from 5 to 15 inclusive.
It's not clear what the purpose of this is, or what a compiler is
supposed to do with that info.)
On 26/11/2021 19:41, James Harris wrote:
On 21/08/2021 19:11, David Brown wrote:
What happens when you have a type that should have two parameters - size >>> and alignment, for example? Or additional non-integer parameters such
as signedness or overflow behaviour? Or for container types with other >>> types as parameters? C++ has that all covered in a clear and accurate
manner - your system does not.
That's not wholly true. Specific terms and syntax are not yet decided
but I do have the concept of qualifiers. For example,
int 32 x
int 32 alignbits 3 y
In that, y would be required to be aligned such that the bottom 3 bits
of its address were zero.
Before you try to think out a syntax here, ask yourself /why/ someone
would want this feature. What use is it? What are the circumstances
when you might need non-standard alignment? What are the consequences
of it? If this is something that is only very rarely useful (and I
believe that is the case here - but /you/ have to figure that out for
your language), there is no point going out of your way to make it easy
to write. Common things should be easy to write - rare things can be
hard to write. What you certainly don't want is a short but cryptic way
to write it.
So for me, your "alignbits 3" is just wrong - it makes no sense. You
are trying to say it should be aligned with 8-byte alignment, also known
as 64-bit alignment. Obviously I can figure out what you meant - there really isn't any other possibility for "alignbits 3". But if you had
written "alignbits 8", I would take that to mean a packed or unaligned declaration, not one with 256-byte alignment.
int 32 alignbits 3: y
(On the other hand, too much punctuation makes code harder to read and
write. As with most things, you want a happy medium.)
Remember that metaclasses are not for the "average" programmer. They
are for the library builders and the language builders. A good
proportion of modern C++ features are never seen or used by the majority
of programmers, but they are used underneath to implement the features
that /are/ used. Few C++ programmers really understand rvalue
references and move semantics, but they are happy to see that the
standard library container classes are now more efficient - without
caring about the underlying language changes that allow those efficiency gains. Probably something like 99% of Python programmers have never
even heard of metaclasses, yet they use libraries that make use of them.
it will die out because no one uses it. (There are only two kinds of programming languages - the ones that people complain about, and the
ones no one uses.)
On 27/11/2021 15:17, David Brown wrote:
On 26/11/2021 19:41, James Harris wrote:
On 21/08/2021 19:11, David Brown wrote:
...
So for me, your "alignbits 3" is just wrong - it makes no sense. You
are trying to say it should be aligned with 8-byte alignment, also known
as 64-bit alignment. Obviously I can figure out what you meant - there
really isn't any other possibility for "alignbits 3". But if you had
written "alignbits 8", I would take that to mean a packed or unaligned
declaration, not one with 256-byte alignment.
On that, I wonder if I could persuade you to think in terms of the
number of bits. AISI there are two ways one can specify alignment: a
power of two number of bytes that the alignment has to be a multiple of
and the number of zero bits on the RHS.
When specifying constants it's easier to begin with and convert from the number of bits. Consider the opposite. Given
constant ALIGN_BYTES = 8
there are these two ways one might convert that to alignment bits.
constant ALIGN_BITS = Log2RoundedUp(ALIGN_BYTES)
constant ALIGN_BITS = Log2ButErrorIfNotPowerOfTwo(ALIGN_BYTES)
IOW (1) there are two possible interpretations of the conversion and,
perhaps worse, (2) either would need a special function to implement it.
By contrast, if we begin with alignment bits then there's a standard conversion which needs no special function.
constant ALIGN_BYTES = 1 << ALIGN_BITS
Hence I prefer to use bit alignment (number of zero bits on RHS) as the
base constant. Other constants and values can easily be derived from there.
...
int 32 alignbits 3: y
...
(On the other hand, too much punctuation makes code harder to read and
write. As with most things, you want a happy medium.)
Yes. I could require
int(32)<alignbits 3> y
which would perhaps be more convenient for the compiler (and more
familiar for a new reader) but in the long term I suspect it would be
more work for a human to write and read.
...
Remember that metaclasses are not for the "average" programmer. They
are for the library builders and the language builders. A good
proportion of modern C++ features are never seen or used by the majority
of programmers, but they are used underneath to implement the features
that /are/ used. Few C++ programmers really understand rvalue
references and move semantics, but they are happy to see that the
standard library container classes are now more efficient - without
caring about the underlying language changes that allow those efficiency
gains. Probably something like 99% of Python programmers have never
even heard of metaclasses, yet they use libraries that make use of them.
When it comes to language design I have a problem with the conceptual division of programmers into average and expert. The issue is that it
assumes that each can write their own programs and the two don't mix.
In
reality, code is about communication. I see a programming language as a lingua franca. Part of its value is that everyone can understand it. If
the 'experts' start writing code which the rest of the world cannot
decipher then a significant part of that value is lost.
Hence, AISI, it's better for a language to avoid special features for experts, if possible.
...
it will die out because no one uses it. (There are only two kinds of
programming languages - the ones that people complain about, and the
ones no one uses.)
:-)
On 27/11/2021 15:17, David Brown wrote:
On 26/11/2021 19:41, James Harris wrote:
That's not wholly true. Specific terms and syntax are not yet decided
but I do have the concept of qualifiers. For example,
int 32 x
int 32 alignbits 3 y
In that, y would be required to be aligned such that the bottom 3 bits
of its address were zero.
Before you try to think out a syntax here, ask yourself /why/ someone
would want this feature. What use is it? What are the circumstances
when you might need non-standard alignment? What are the consequences
of it? If this is something that is only very rarely useful (and I
believe that is the case here - but /you/ have to figure that out for
your language), there is no point going out of your way to make it easy
to write. Common things should be easy to write - rare things can be
hard to write.
Yet C breaks that rule all the time. Just today I needed to type:
unsigned char to mean byte or u8
unsigned long lont int to mean u64 [typo left in]
printf("....\n", ...) to mean println ...
Yes you could use and uint8_t uint64_t, but that still needs:
#include <stdint.h>
to be remembered to add at the top of every module
So for me, your "alignbits 3" is just wrong - it makes no sense. You
are trying to say it should be aligned with 8-byte alignment, also known
as 64-bit alignment. Obviously I can figure out what you meant - there
really isn't any other possibility for "alignbits 3". But if you had
written "alignbits 8", I would take that to mean a packed or unaligned
declaration, not one with 256-byte alignment.
I don't get it either, but I guess you're not complaining of a way to
control alignment of type, just that this not intuitive?
In my assembler I use:
align N
to force alignment of next data/code byte at a multiple of N bytes,
usually a power-of-two.
My HLL doesn't have that, except that I once used @@ N to control the alignment of record fields (now I use a $caligned attribute for the
whole record as that was only use for @@, to emulate C struct layout).
The additional colon would make parsing by compiler and by human easier. >>> I have omitted it up until now as I could imagine that programmers would >>> not want to have to type it in simple declarations such as
int: i
but maybe that doesn't look too bad.
I only know one person who regularly complains about having to use
punctuation and finds it inconvenient to type symbols. But even he uses
punctuation at times in his languages.
Shifted punctuation is worse.
(On the other hand, too much punctuation makes code harder to read and
write. As with most things, you want a happy medium.)
My intention here is to encourage you to think bigger. Stop thinking >>>> "how do I make integer types?" - think wider and with greater
generality
and ambition. Make a good general, flexible system of types, and then >>>> let your integer types fall naturally out of that.
The goal is that range specifications would apply anywhere relevant, not >>> just for integers. For example,
array (5..15) floati32: v
would declare an array of between 5 and 15 elements of type floati32.
(No. That's just not what anyone would guess that to mean. It looks like
an array of length 11 indexed from 5 to 15 inclusive.
It's not clear what the purpose of this is, or what a compiler is
supposed to do with that info.)
Unless a language was just a simple, limited scripting tool, I would not
bother making (or learning) a new language that did not have features
such as variants or generics (noting that these terms are vague and mean
different things to different people). There are perfectly good
languages without such features. Given the vast benefits of C in terms
of existing implementation, code, experience and information, why would
anyone bother with a different compiled language unless it let them do
things that you cannot easily do in C? Being able to make your own
types, with their rules, invariants, methods, operators, etc., is pretty
much a basic level feature for modern languages. Generic programming is
standard. I would no longer consider these as advanced or complex
features of a modern language, I'd consider them foundational.
That still leaves a big gap between C, and a language with all those
advanced features, which probably cannot offer the benefits of small footprint, transparency, and the potential for a fast build process.
Plus there are plenty of things at the level of C that some people (me,
for a start) want but it cannot offer:
* An alternative to that god-forsaken, error prone syntax
* Freedom from case-sensitivity
* 1-based arrays!
* An ACTUAL byte/u8 type without all the behind-the-scenes
nonsense, and the need for stdint/inttypes etc
* 64-bit integer types as standard
* A grown-up Print feature
* etc etc
What /are/ the actual alternatives available as the next C replacement;
Rust and Zig? You're welcome to them!
On 28/11/2021 10:33, James Harris wrote:
On 27/11/2021 15:17, David Brown wrote:
So for me, your "alignbits 3" is just wrong - it makes no sense. You
are trying to say it should be aligned with 8-byte alignment, also known >>> as 64-bit alignment. Obviously I can figure out what you meant - there >>> really isn't any other possibility for "alignbits 3". But if you had
written "alignbits 8", I would take that to mean a packed or unaligned
declaration, not one with 256-byte alignment.
On that, I wonder if I could persuade you to think in terms of the
number of bits. AISI there are two ways one can specify alignment: a
power of two number of bytes that the alignment has to be a multiple of
and the number of zero bits on the RHS.
Those are equivalent in terms of the actual implementation, but not in
the way a programmer is likely to think (or want to think). The whole
point of a programming language above the level of assembly is that the programmer doesn't think in terms of underlying representations in bits
and bytes, but at a higher level, in terms of values and the meanings of
the values.
If I write "int * p = &x;", I think of "p" as a pointer to
the variable "x". I don't think about whether it is 64-bit or 32-bit,
or whether it is an absolute address or relative to a base pointer, or
how it is translated via page tables. Considering the number of zero
bits in the representation of the address is at a completely different
level of abstraction from what I would see as relevant in a programming language.
When specifying constants it's easier to begin with and convert from the
number of bits. Consider the opposite. Given
constant ALIGN_BYTES = 8
there are these two ways one might convert that to alignment bits.
constant ALIGN_BITS = Log2RoundedUp(ALIGN_BYTES)
constant ALIGN_BITS = Log2ButErrorIfNotPowerOfTwo(ALIGN_BYTES)
IOW (1) there are two possible interpretations of the conversion and,
perhaps worse, (2) either would need a special function to implement it.
This is all completely trivial to implement in your
compiler/interpreter. Users are not interested in the number of zero
bits in addresses - and they are not interested in the effort it takes
to implement a feature. If you want a programming language that is more
than a toy, a learning experiment, or a one-man show, then you must prioritise the effort of the user by many orders of magnitude over the convenience of the implementer.
On 27/11/2021 19:55, Bart wrote:
Yet C breaks that rule all the time. Just today I needed to type:
unsigned char to mean byte or u8
unsigned long lont int to mean u64 [typo left in]
printf("....\n", ...) to mean println ...
If you needed to type those to mean something else, that is /purely/ a problem with the programmer, not with the language. The language and
its standard libraries provides everything you need in order to write
these things in the way you want. As long as the language makes that practically possible (and in the first two examples at least, extremely simple), the language does all it needs.
No language will /ever/ mean you can trivially write all the code you
want to write! Obviously when you are doing a one-man language with one designer, one user, and one type of code, and are happy to modify the language to suit the program you are writing, you can come quite close.
But for real languages developed and implemented by large numbers of
people and used by huge numbers of people, that does not happen.
As so often happens, in your manic obsession to rail against C, you completely missed the point. Oh, and you also missed that in this
newsgroup I have repeatedly said that people should study popular and successful languages like C and C++ (and others) in order to learn from
them and take inspiration from them, and to aim to make something
/better/ for their particular purposes and requirements.
Yes you could use and uint8_t uint64_t, but that still needs:
#include <stdint.h>
to be remembered to add at the top of every module
Do you have any idea how pathetic and childish that sounds? Presumably
not, or you wouldn't have written it. So let me inform you, again, that continually whining and crying about totally insignificant
inconveniences does nothing to help your "down with C" campaign.
Shifted punctuation is worse.
So you'd rather write "x - -y" than "x + y", because it avoids the shift
key? That seems like a somewhat questionable choice of priorities.
* An alternative to that god-forsaken, error prone syntax
* Freedom from case-sensitivity
* 1-based arrays!
* An ACTUAL byte/u8 type without all the behind-the-scenes
nonsense, and the need for stdint/inttypes etc
* 64-bit integer types as standard
* A grown-up Print feature
* etc etc
What /are/ the actual alternatives available as the next C replacement;
Rust and Zig? You're welcome to them!
If there were a significant number of people who wanted a language with
these features, there would be one.
On 28/11/2021 13:46, David Brown wrote:
On 28/11/2021 10:33, James Harris wrote:
On 27/11/2021 15:17, David Brown wrote:
So for me, your "alignbits 3" is just wrong - it makes no sense. You >>>> are trying to say it should be aligned with 8-byte alignment, also
known
as 64-bit alignment. Obviously I can figure out what you meant - there >>>> really isn't any other possibility for "alignbits 3". But if you had >>>> written "alignbits 8", I would take that to mean a packed or unaligned >>>> declaration, not one with 256-byte alignment.
BTW, you may be assuming octet addressing. That's not always the case.
On that, I wonder if I could persuade you to think in terms of the
number of bits. AISI there are two ways one can specify alignment: a
power of two number of bytes that the alignment has to be a multiple of
and the number of zero bits on the RHS.
Those are equivalent in terms of the actual implementation, but not in
the way a programmer is likely to think (or want to think). The whole
point of a programming language above the level of assembly is that the
programmer doesn't think in terms of underlying representations in bits
and bytes, but at a higher level, in terms of values and the meanings of
the values.
That's all very well but if you are thinking about alignment of values
or structures you are already working at a low level.
Further, say you had your alignment in the way you prefer, i.e. as a
number of bytes such as 8. What would you write if you wanted to apply a commensurate shift? To get from 8 to 3 you'd need some sort of
log-base-2 function of the type I showed earlier. Which would you want a language to provide?
All in all, I put it to you that going from 3 to 8 is easier. :-)
If I write "int * p = &x;", I think of "p" as a pointer to
the variable "x". I don't think about whether it is 64-bit or 32-bit,
or whether it is an absolute address or relative to a base pointer, or
how it is translated via page tables. Considering the number of zero
bits in the representation of the address is at a completely different
level of abstraction from what I would see as relevant in a programming
language.
Well, if an address is guaranteed to be at a certain alignment then asm programmers may store flags in the lower bits. AFAICS that's not too
easy to do in C so C programmers don't think in those terms - perhaps
putting the flags in a separate integer on their own. But there can be
value in using such bits and some hardware structures already include
them. Specifying an address as aligned can make low bits available.
At the end of the day, confining layout details to /declarations/ means
that the body of an algorithm can still work with the elements which
make sense for the task in hand, leaving the compiler to handle the
details of accessing them.
When specifying constants it's easier to begin with and convert from the >>> number of bits. Consider the opposite. Given
constant ALIGN_BYTES = 8
there are these two ways one might convert that to alignment bits.
constant ALIGN_BITS = Log2RoundedUp(ALIGN_BYTES)
constant ALIGN_BITS = Log2ButErrorIfNotPowerOfTwo(ALIGN_BYTES)
IOW (1) there are two possible interpretations of the conversion and,
perhaps worse, (2) either would need a special function to implement it. >>>
This is all completely trivial to implement in your
compiler/interpreter. Users are not interested in the number of zero
bits in addresses - and they are not interested in the effort it takes
to implement a feature. If you want a programming language that is more
than a toy, a learning experiment, or a one-man show, then you must
prioritise the effort of the user by many orders of magnitude over the
convenience of the implementer.
I was talking about the facilities being made available to programmers,
not just those I would use internally!
There are a few with such features, unfortunately not all in the same language! (Ada has the first 3 of my list, but also has an impossible
type system.)
On 28/11/2021 17:26, Bart wrote:
There are a few with such features, unfortunately not all in the same
language! (Ada has the first 3 of my list, but also has an impossible
type system.)
You really do think the world should revolve around /you/, don't you?
You probably also write letters to your local newspaper complaining that
the breakfast cereals you personally prefer are on the top shelf rather
than at a more convenient height.
Most people would be very happy to be in the position where the most difficult part of their job was having to press the shift key several
times per day.
There is always going to be a huge spread between beginners (including
those that never get beyond beginner stages no matter how long they
spend), average and expert programmers. This is perhaps an unusual
aspect of programming as a profession and hobby. Imagine there were
such a spread amongst professional football ("soccer", for those living
in the ex-colonies) players. On the same team as Maradonna you'd have someone who insists on picking up and carrying the ball, since it
clearly works, and someone who could be outrun by an asthmatic snail.
On 28/11/2021 10:33, James Harris wrote:
Unless you are designing a language to compete with Bart for the record
of fewest users,
On 28/11/2021 17:24, David Brown wrote:
On 28/11/2021 17:26, Bart wrote:
There are a few with such features, unfortunately not all in the same
language! (Ada has the first 3 of my list, but also has an impossible
type system.)
You really do think the world should revolve around /you/, don't you?
You probably also write letters to your local newspaper complaining that
the breakfast cereals you personally prefer are on the top shelf rather
than at a more convenient height.
Most people would be very happy to be in the position where the most
difficult part of their job was having to press the shift key several
times per day.
Look: when I first started programming, then these characteristics were common:
* Case insensitive (in code, file system and CLIs)
* 1-based indexing, with A[i,j] for 2D accesses
* Keyword-based block delimiters (do...end, not {...})
* Proper Read A, B, C and Print A, B, C features ...
Why SHOULDN'T I be allowed to have my own preferences, and why SHOULDN'T
I complain when those have been marginalised in favour of inferior
practices?
Getting back to what this is about, which was your suggestion that C is
so perfect, it is pointless to create something new unless it comes with
a raft of advanced, heavy features, then why SHOULDN'T there be an alternative systems language with it's OWN set of characteristics?
This group is also about discussing aspect of language design. If you
want to talk about some of your own ideas, regardless of whether you're
going to implement them, then that would great.
However you seem intent on trashing everyone's ideas and aspirations.
On 28/11/2021 13:46, David Brown wrote:
There is always going to be a huge spread between beginners (including
those that never get beyond beginner stages no matter how long they
spend), average and expert programmers. This is perhaps an unusual
aspect of programming as a profession and hobby. Imagine there were
such a spread amongst professional football ("soccer", for those living
in the ex-colonies) players. On the same team as Maradonna you'd have
someone who insists on picking up and carrying the ball, since it
clearly works, and someone who could be outrun by an asthmatic snail.
Hm. I'm not sure this is the best analogy you've ever
produced! Every sport and hobby has beginners and experts;
and it is at least as unusual in programming as in most other
spheres to find world-class experts and novices in the same
team [to the extent to which programming is even a team game!].
In programming,
you get people making a living as programmers despite being completely incompetent.
And even amongst people who do a reasonable job, you can
get an order of magnitude difference in productivity.
On 28/11/2021 20:25, Bart wrote:
Why should anyone care?
When I started watching TV, there were three channels, and most TV's
were black and white and about as deep as they were high.
All languages and all OSes were using the same hardware. Yet Unix+C went* Case insensitive (in code, file system and CLIs)
That stems from a time when computers had six bits for a character
because 8 bits would cost too much, and people used teletype instead of screens and keyboards.
If you have trouble getting your cases right,
you are in the wrong job.
* 1-based indexing, with A[i,j] for 2D accesses
1-based counting is good for everyday counting, not for programming.
* Keyword-based block delimiters (do...end, not {...})
That comes from a time when keyboards with symbols such as { } were
considered advanced and modern. (Hence those monstrosities, the
trigraph and digraph.) Oh, I forgot - you find it such an effort to
press the "shift" key on your keyboard.
* Proper Read A, B, C and Print A, B, C features ...
What a pointless and meaningless statement. There are a hundred and one different ways to do "proper" read and print, with everyone having their
own ideas about what is best.
Because you are wrong.
And you are a margin of /one/, because you believe that languages should follow exactly what /you/ want in all aspects, with a total disregard
for anyone else.
Yes, you can have your opinion. Yes, you can make your own language the
way /you/ want it. Yes, you can give suggestions and ideas based on
these in a discussion about languages. No, you can't tell people that
you alone are right, and the rest of the world is wrong, and expect to
be taken seriously.
Getting back to what this is about, which was your suggestion that C is
so perfect, it is pointless to create something new unless it comes with
a raft of advanced, heavy features, then why SHOULDN'T there be an
alternative systems language with it's OWN set of characteristics?
I /could/ explain what I had written earlier. But what would be the
point? It would just repeat the same things I wrote before. You didn't
read them then, why should I think you'll read them now?
I /have/ been discussing ideas and suggestions here. Some have been of interest to James, others not - which is fine. And I write comments
aimed at making him (or anyone else interested in languages) think about
how the language might be used - because that's what's important. I am
not the one who thinks every thread is an opportunity for a new anti-C rant.
On 29/11/2021 09:05, David Brown wrote:
On 28/11/2021 20:25, Bart wrote:
Why should anyone care?
When I started watching TV, there were three channels, and most TV's
were black and white and about as deep as they were high.
In 1962 we had a TV with only 1 channel, in black and white and with 405 lines.
In the same year, Lawrence of Arabia was released in cinemas in 70mm
format (somewhat beyond 4K quality). The screen was pretty flat too!
Not sure how such things are relevant, my remarks are about
characteristics of programming languages, not hardware.
All languages and all OSes were using the same hardware. Yet Unix+C went* Case insensitive (in code, file system and CLIs)
That stems from a time when computers had six bits for a character
because 8 bits would cost too much, and people used teletype instead of
screens and keyboards.
for case-sensitivity, other made a different choice.
A /choice/. That doesn't make it right and the others wrong.
I used machines with both upper and lower case capability from 1982; I
still prefered case-insensitivity because it was generally better and
more user-friendly.
If you have trouble getting your cases right,
you are in the wrong job.
If you have trouble thinking up distinct identifiers in examples like this:
Abc abc = ABC;
then /you're/ in the wrong job!
* 1-based indexing, with A[i,j] for 2D accesses
1-based counting is good for everyday counting, not for programming.
Bollocks. In any case, you snipped my remark that I implement N-based
arrays, so that I can use 0-based /as needed/, and have always done.
You haven't explained why A[i][j] is better than A[i,j].
* Keyword-based block delimiters (do...end, not {...})
That comes from a time when keyboards with symbols such as { } were
So you see it as progress that {,} with their innumerable issues were introduced. Because this:
} else {
or:
}
else {
or:
} else
{
or:
}
else
} # (oops!)
etc. is SO much better than just:
else
You must be delusional.
considered advanced and modern. (Hence those monstrosities, the
trigraph and digraph.) Oh, I forgot - you find it such an effort to
press the "shift" key on your keyboard.
* Proper Read A, B, C and Print A, B, C features ...
What a pointless and meaningless statement. There are a hundred and one
different ways to do "proper" read and print, with everyone having their
own ideas about what is best.
This is just pure jealousy. Show me the C code needed to do the
equivalent of this (without knowing the types of a, b, c other than they
are numeric):
print "?"
readln a, b, c
println a, b, c
Here the language provides informal line-based i/o, as might be useful
for interactive programs, or reading/writing files, while still allowing
more precise control as needed.
Because you are wrong.
And you are a margin of /one/, because you believe that languages should
follow exactly what /you/ want in all aspects, with a total disregard
for anyone else.
What exactly are the choices for someone in 2021 who wants to use (or is required to use) a language like C, but favours even one of my characteristics?
Yes, you can have your opinion. Yes, you can make your own language the
way /you/ want it. Yes, you can give suggestions and ideas based on
these in a discussion about languages. No, you can't tell people that
you alone are right, and the rest of the world is wrong, and expect to
be taken seriously.
But YOU are allowed to say that:
* Case-insensitivity is wrong
* 1-based is wrong
* A[i,j] is wrong
* Anything other than {...} blocks is wrong
* Easy read/print statements in a language are wrong
* Line-based i/o is wrong
* Left-to-right type syntax is wrong. (Did you say that, or decided not
to mention that one?!)
All things that C doesn't have.
Actually, Ada and Fortran are still around, are case-insensitive, are N-based, and don't use brace syntax.
Lua doesn't use braces for blocks. It is also 1-based.
Also 1-based are Julia, Mathematica, and Matlab ("Learn some maths"? Sure!)
Julia doesn't use braces either.
These are all characterics that still exist across languages, but not necessarily within one system languages which is where I need them.
Getting back to what this is about, which was your suggestion that C is
so perfect, it is pointless to create something new unless it comes with >>> a raft of advanced, heavy features, then why SHOULDN'T there be an
alternative systems language with it's OWN set of characteristics?
I /could/ explain what I had written earlier. But what would be the
point? It would just repeat the same things I wrote before. You didn't >> read them then, why should I think you'll read them now?
I'll repeat what you said:
"Given the vast benefits of C in terms
of existing implementation, code, experience and information, why would anyone bother with a different compiled language unless it let them do
things that you cannot easily do in C?"
You are clearly saying, don't bother creating an alternative to C unless
it actually does something different.
I disagreed: you CAN have an alternative that, while it does the same
things, can achieve that differently.
I listed some things out of many dozens. You of course with disagree
with every one of them.
Doesn't matter what it is:
C does X C's way is perfect
Bart does Y Bart is WRONG, and in a minority of one
Even when I show that other languages, old or new, also do Y. Or when I
give an example of Y clearly being better than X.
My dislike of C is rational. Your loyalty to it, and hatred of anyone
who dares to badmouth it, is irrational.
I /have/ been discussing ideas and suggestions here. Some have been of
interest to James, others not - which is fine. And I write comments
aimed at making him (or anyone else interested in languages) think about
how the language might be used - because that's what's important. I am
not the one who thinks every thread is an opportunity for a new anti-C
rant.
No. Your message is 'Just don't bother trying to rewrite C', presumably because it is perfect.
C is still VERY widely used, but you don't believe in an alternative.
You want people to continue driving a Model T, unless the new car can
also fly!
On 2021-11-29 12:09, David Brown wrote:
In programming,
you get people making a living as programmers despite being completely
incompetent.
Reminds me of politicians, pop musicians, journalists, economists, environmentalists... (put quotation marks as appropriate)
And even amongst people who do a reasonable job, you can
get an order of magnitude difference in productivity.
That is the 80/20 law.
But I agree with you, incompetence is strong with programmers...
On 28/11/2021 15:54, James Harris wrote:
On 28/11/2021 13:46, David Brown wrote:
On 28/11/2021 10:33, James Harris wrote:
On 27/11/2021 15:17, David Brown wrote:
Further, say you had your alignment in the way you prefer, i.e. as a
number of bytes such as 8. What would you write if you wanted to apply a
commensurate shift? To get from 8 to 3 you'd need some sort of
log-base-2 function of the type I showed earlier. Which would you want a
language to provide?
Again, I want /you/ to think about what /your/ users will actually need
and use. When would they need this? Is it really something people will need? I believe you are trying to optimise for non-existent use-cases, instead of realistic ones. If you believe otherwise, please say so -
perhaps with examples or justification. (It's your language, you don't /have/ to justify your choice of features, but it makes it easier to
give helpful suggestions.)
And of course there is nothing to stop you doing the equivalent of
#define struct_align_needed 3
alignas(1 < struct_align_needed) struct S s;
or whatever. In other words, if you really need to go from 3 to 8, then
you can happily do that even if your "align" method takes an 8 rather
than a 3.
When specifying constants it's easier to begin with and convert from the >>>> number of bits. Consider the opposite. Given
constant ALIGN_BYTES = 8
there are these two ways one might convert that to alignment bits.
constant ALIGN_BITS = Log2RoundedUp(ALIGN_BYTES)
constant ALIGN_BITS = Log2ButErrorIfNotPowerOfTwo(ALIGN_BYTES)
Programmers don't need these - it's not something they have to do. And
if they /do/, then they can do so with :
constant ALIGN_BITS = 3
constant ALIGN_BYTES = 1 << ALIGN_BITS
or maybe:
constant ALIGN_BYTES = 8
constant ALIGN_BITS = 3
static_assert(ALIGN_BYTES == 1 << ALIGN_BITS,
"Failed alignment sanity check")
You are inventing non-existent problems here.
On 29/11/2021 14:06, Bart wrote:
A /choice/. That doesn't make it right and the others wrong.
Case insensitive doesn't work when you go beyond the UK/US alphabet.
The complications for various languages are immense. In German, the
letter ß traditionally capitalises as SS - one letter turns into two.
In Turkish, "i" and "I" are two completely different letters, with their opposite cases being "İ" and "ı". It quickly becomes ridiculous when
you need to support multiple languages. On the other hand,
case-sensitive naming is usually just done as binary comparison.
So unless you think that everyone should be forced to write a limited
form of UK or US English and that ASCII is good enough for everyone, case-sensitive is the only sane choice for file systems.
If you have trouble thinking up distinct identifiers in examples like this: >>
Abc abc = ABC;
then /you're/ in the wrong job!
That's a strawman, and you know it.
But if you have just one starting point, 0 is the sensible one. You
might not like the way C handles arrays (and I'm not going to argue
about it - it certainly has its cons as well as its pros), but even you
would have to agree that defining "A[i]" to be the element at "address
of A + i * the size of the elements" is neater and clearer than
one-based indexing.
print "?"
readln a, b, c
println a, b, c
In C, you don't work with variables whose types are unknown.
You are under the delusion that there is one "correct" interpretation
here. You think that /your/ ideas are the only "obvious" or "proper"
way to handle things. In reality, there are dozens of questions that
could be asked here, including:
Does there have to be a delimiter between the inputs? Does it have to
be comma, or space, or newline?
than one? Are numbers treated differently in the input? Would an input
of "true" be treated as a string or a boolean? Are there limits to the sizes? How are errors in the input, such as end-of-file or ctrl-C
treated? How do you handle non-ASCII strings?
Should there be spaces between the outputs? Newlines? Should the
newline be a CR, an LF, CR+LF, or platform specific? What resolution or format should be used for the numbers? If someone had entered "0x2c"
for one of the inputs, is that a string or a number - and if it is a
number, should it be printed in hex or in decimal?
Should the output go to the "standard out" stream, assuming that is
supported by the language and the OS?
The "standard error" stream?
All things that C doesn't have.
Only you are arguing about C here - only you seem to imagine people
think it is perfect. It is far and away the most successful programming language, massively used and massively popular,
You are clearly saying, don't bother creating an alternative to C unless
it actually does something different.
Yes. Surely that is obvious? There is no point in re-inventing the
same wheel everyone else already uses - you have to bring something new
to the table.
I disagreed: you CAN have an alternative that, while it does the same
things, can achieve that differently.
No one will use it. So what's the point?
Should I change the
tiny, cheap microcontrollers we use to embedded Windows systems as that
is the only target you support?
For C, I have the standards documents
and reference sites, and compilers and libraries that follow these specifications, and an endless supply of knowledgeable users for help, advice, or hire - for your language, we have one guy off the internet
who regularly fails to answer simple questions about the language he
wrote without trying it to see the result.
So, again, what is the point of a language that is roughly like C but
with a few technical improvements and perhaps a nicer syntax (in some people's opinion) ?
I hope you were not suggesting that /your/ language is somehow moreActually it is. Why, in what way is C (the language, not all those shiny
modern than C!
On 29/11/2021 11:40, Dmitry A. Kazakov wrote:
On 2021-11-29 12:09, David Brown wrote:
In programming,
you get people making a living as programmers despite being completely
incompetent.
Reminds me of politicians, pop musicians, journalists, economists,
environmentalists... (put quotation marks as appropriate)
And even amongst people who do a reasonable job, you can
get an order of magnitude difference in productivity.
That is the 80/20 law.
But I agree with you, incompetence is strong with programmers...
That's no good. We cannot have agreement on Usenet. ;-) So let me
suggest that both of you have gone off the point (fine and permissible
but a deviation nonetheless).
What we were talking about was David espousing a language feature which
was "not for the average programmer" and saying (AIUI) that it was fine
to have average and expert programmers use different features. I
disagree with that premise.
Instead, a language should
(ideally) be simple enough that both average and expert programmers can
work with the same code.
This is, again, about a language being a medium in which a programmer communicates. That communication can be with other programmers, not just
with a compiler. (A lofty goal and perhaps unachievable but a very
important goal to keep in mind, IMO.)
On 2021-11-29 23:15, James Harris wrote:
What we were talking about was David espousing a language feature
which was "not for the average programmer" and saying (AIUI) that it
was fine to have average and expert programmers use different
features. I disagree with that premise.
It is OK even for experts to use different language features. It depends
on the task. Furthermore there are SW development roles like SW
architect etc requiring higher qualification and the corresponding
language parts for these.
Instead, a language should (ideally) be simple enough that both
average and expert programmers can work with the same code.
If the underlying concepts are inherently complex the language cannot simplify them enough.
On 30/11/2021 07:46, Dmitry A. Kazakov wrote:
On 2021-11-29 23:15, James Harris wrote:
...
What we were talking about was David espousing a language feature
which was "not for the average programmer" and saying (AIUI) that it
was fine to have average and expert programmers use different
features. I disagree with that premise.
It is OK even for experts to use different language features. It
depends on the task. Furthermore there are SW development roles like
SW architect etc requiring higher qualification and the corresponding
language parts for these.
AISI that's only true if the language is complex enough to have parts
which are not needed in normal programming. Are those parts really needed?
Instead, a language should (ideally) be simple enough that both
average and expert programmers can work with the same code.
If the underlying concepts are inherently complex the language cannot
simplify them enough.
Interesting comment. Which concepts cannot be simplified?
On 29/11/2021 15:19, David Brown wrote:
On 29/11/2021 14:06, Bart wrote:
A /choice/. That doesn't make it right and the others wrong.
Case insensitive doesn't work when you go beyond the UK/US alphabet.
The complications for various languages are immense. In German, the
letter ß traditionally capitalises as SS - one letter turns into two.
In Turkish, "i" and "I" are two completely different letters, with their
opposite cases being "İ" and "ı". It quickly becomes ridiculous when
you need to support multiple languages. On the other hand,
case-sensitive naming is usually just done as binary comparison.
So unless you think that everyone should be forced to write a limited
form of UK or US English and that ASCII is good enough for everyone,
case-sensitive is the only sane choice for file systems.
URLs are case-insensitive for the first part. So are email addresses and usernames. And usually, people's names when stored in a computer system.
And addresses and postcodes. And movie and book titles. Etc.
Those I guess are immune to the problems of Unicode.
I feel that file names, which could be used to represent all those
examples, and the commands of CLIs, should be the same.
If you have trouble thinking up distinct identifiers in examples like
this:
Abc abc = ABC;
then /you're/ in the wrong job!
That's a strawman, and you know it.
I see it all the time in C. Example from raylib.h:
typedef struct CharInfo {
int value; // Character value (Unicode) int offsetX; // Character offset X when drawing int offsetY; // Character offset Y when drawing int advanceX; // Character advance position X Image image; // Character image data
} CharInfo;
'Image image'; just try saying it out loud!
But if you have just one starting point, 0 is the sensible one. You
might not like the way C handles arrays (and I'm not going to argue
about it - it certainly has its cons as well as its pros), but even you
would have to agree that defining "A[i]" to be the element at "address
of A + i * the size of the elements" is neater and clearer than
one-based indexing.
That's a crude way of defining arrays. A[i] is simply the i'th element
of N slots, you don't need to bring offsets into it.
With 0-based, there's a disconnect between the ordinal number of the
element you want, and the index that needs to be used. So A[2] for the
3rd element.
print "?"
readln a, b, c
println a, b, c
In C, you don't work with variables whose types are unknown.
You may know the types, but they shouldn't affect how you write Read and Print. In C it does, and needs extra maintenance.
You are under the delusion that there is one "correct" interpretation
here. You think that /your/ ideas are the only "obvious" or "proper"
way to handle things. In reality, there are dozens of questions that
could be asked here, including:
Print is one of the most diverse features among languages. Your
objections would apply to every language. Many have Print similar to
mine, for example there might be 'println'; so what newline should be
used (one of your questions)?
What I'm showing is a sensible set of defaults.
Does there have to be a delimiter between the inputs? Does it have to
be comma, or space, or newline?
Think about it: this is for user input, it needs to fairly forgiving.
Using character-based input as C prefers is another problem when trying
to do interactive input. Programs can appear to hang as they silently
wait for that missing number on the line, while extra numbers screw up
the following line.
Are these ignored if there are more
than one? Are numbers treated differently in the input? Would an input >> of "true" be treated as a string or a boolean? Are there limits to the
sizes? How are errors in the input, such as end-of-file or ctrl-C
treated? How do you handle non-ASCII strings?
Yeah, carry on listing so many objections, that in the end the language provides nothing. And requires a million programmers to each reinvent line-based i/o from first principles.
You are just making excuses why your favourite languages don't provide
such features.
Should there be spaces between the outputs? Newlines? Should the
newline be a CR, an LF, CR+LF, or platform specific? What resolution or
format should be used for the numbers? If someone had entered "0x2c"
for one of the inputs, is that a string or a number - and if it is a
number, should it be printed in hex or in decimal?
Usually such input is not language source code, it might be something
like a config file or maybe a log or transaction file.
If your requirements demand a full-blown language tokeniser, then you're doing it wrong; you don't parse source code using a Read statement!
Should the output go to the "standard out" stream, assuming that is
supported by the language and the OS?
It goes to the console unless the program specifies otherwise; that's
pretty standard.
The "standard error" stream?
stderror is an invention of C (or Unix, one of those) and is actually
quite difficult to make use of outside that language.
All things that C doesn't have.
Only you are arguing about C here - only you seem to imagine people
think it is perfect. It is far and away the most successful programming
language, massively used and massively popular,
Great. That means there is still a place for a systems language at this crude, lower level.
It also means there is room for alternatives. Even if it means the alternative is something that is implemented on top of C because all the tools are in place.
You are clearly saying, don't bother creating an alternative to C unless >>> it actually does something different.
Yes. Surely that is obvious? There is no point in re-inventing the
same wheel everyone else already uses - you have to bring something new
to the table.
I invented /my/ first wheel because I didn't have any!
Then I found that my wheels was smaller, simpler, faster and generally a better fit than other solutions.
I disagreed: you CAN have an alternative that, while it does the same
things, can achieve that differently.
No one will use it. So what's the point?
/I/ will use it. And I will get a kick out of using it. After all not
many get to use their own languages for 100% of their work.
Should I change the
tiny, cheap microcontrollers we use to embedded Windows systems as that
is the only target you support?
Mine aren't general purpose in the sense that they are for my own use,
and they target whatever hardware I happen to be using, which currently
is Win64. So I'm not here to flog my language. Only discussing portable ideas.
However previous versions have targetted:
CPU Size OS
PDP10 36-bit TOPS10(?) (Not my lang, but first time self-hosted) Z80 8-bit None
Z80 OS/M (CP/M ripoff)
Z80 (PCW)
8088/86 16-bit MSDOS (plus None for some projects)
80386 32-bit MSDOS/Windows
x64 64-bit Windows (current)
(C32) 32-bit Windows/Linux, x86/ARM32 (Versions with C targets) (C64) 64-bit Windows/Linux, x64/ARM64
If I wanted, I could adapt my language to a small device, but it would
have to work as a cross-compiler, and I'd need a minimum spec.
BTW, would any of C#, Java, D, Rust, Zig, Odin, Go (or Algol68) work on
those microcontrollers of yours?
For C, I have the standards documents
and reference sites, and compilers and libraries that follow these
specifications, and an endless supply of knowledgeable users for help,
advice, or hire - for your language, we have one guy off the internet
who regularly fails to answer simple questions about the language he
wrote without trying it to see the result.
Yeah, and on Reddit, there's an endless stream of the same questions
about C due to all its quirks!
And for you, I bet I could find a choice macro whose output you probably wouldn't be able to guess without trying it out.
So, again, what is the point of a language that is roughly like C but
with a few technical improvements and perhaps a nicer syntax (in some
people's opinion) ?
Well, the language exists. It is a joy to use. It is easy to navigate.
It is easy to type. It has modules. You don't need declarations, just definitions. It has out-of-order everything. It fixes 100 annoyances of
C. It provides a whole-program compiler. It builds programs very
quickly. It has a self-contained one-file implementation. It has a
companion scripting language in the same syntax and with higher level
types.
So, I should just delete a language I've used for 40 years and just code
in C with all those brackets, braces and semicolons like every other
palooka who needs to use an off-the-shelf language?
I should sell my familiar, comfortable car and drive that Model T? It
would be more like getting the bus; I'd rather walk!
I hope you were not suggesting that /your/ language is somehow moreActually it is. Why, in what way is C (the language, not all those shiny
modern than C!
new IDEs), more modern than the language I have?
On 29/11/2021 23:40, Bart wrote:
You are a product of your environment (this is not a criticism, it is
human nature). You whole experience, especially in anything computer-related, has been in ASCII.
A large proportion of it has been
from a time when computers couldn't do anything else, and all the rest
has been using English-language systems with keyboards that are simple
ASCII only. You've never been able to type "naïve" or "café" with the correct English-language spelling, without jumping through hoops with a "character map" program. You've (almost) never used a command line
terminal that can work with non-ASCII characters.
This means that for you, working with case-insensitive strings is easy.
It's a bit of extra effort in the code, but not much. And it doesn't
cause confusion or annoyance. In the wider world, however, it is a very different matter - it is either language-specific and potentially complicated, or if it is supposed to support multiple languages it is /extremely/ complicated. And that means it is usually wrong.
But for commands, file names, program identifiers? Why would you want
them to be case insensitive? I mean, I agree that you don't want
commands "Copy", "copy" and "COPY" that all do different things. But
given a command "copy", why would you ever want to type "COPY"?
Given
a variable "noOfWhatsits", what is the benefit of letting "NOofwhatSitS"
mean the same?
If a language (or project) uses a convention that types start with a
capital and variables start with a small letter, then this is perfectly clear.
C is not a language with overloads, OOP or generics (beyond the limited _Generic expression). You /always/ need to track your types, and you /always/ need to write things in different ways for different types.
I don't write "What is your name? Hello <name>" programs - I haven't
done that since I was ten.
But if I did, I wouldn't write it in C - as
C is a terrible language for handling general input.
I guess a rough
equivalent to your program, written in my favourite language for such
tasks, might be :
a, b, c = input("? ").split()
print(a, b, c)
On 29/11/2021 23:40, Bart wrote:
But for commands, file names, program identifiers? Why would you want
them to be case insensitive? I mean, I agree that you don't want
commands "Copy", "copy" and "COPY" that all do different things. But
given a command "copy", why would you ever want to type "COPY" ? Given
a variable "noofwhatsits", what is the benefit of letting "noofwhatsits"
mean the same?
On 30/11/2021 13:58, David Brown wrote:
On 29/11/2021 23:40, Bart wrote:
But for commands, file names, program identifiers? Why would you want
them to be case insensitive? I mean, I agree that you don't want
commands "Copy", "copy" and "COPY" that all do different things. But
given a command "copy", why would you ever want to type "COPY" ? Given
a variable "noofwhatsits", what is the benefit of letting "noofwhatsits"
mean the same?
I've normalised both of your 'noofwhatsits' to have the same
capitalisation, ie. none.
Can you remember what the original was?
No? That's the probem.
The thing is, I can remember words and phrases, but I easily forget capitalisation, and underscores, another thing I avoid.
Yet one or two languages make underscores non-significant; a bit like
making letter case for A-Z/a-z non-significant. (And exactly like making underscores in numeric literals non-significant.)
And also, a bit like Algol68 making white space in identifiers non-significant: abc, def and abc def are three disinct identifiers; abcdef, abc def and a b c d e f are the same one.
So, my treatment of capitalisation is like Nim's(?) underlines, and
Algol68's embedded spaces; it is an optional style that can be used to enhance readability, or enforce naming guidelines.
No one suggests that Nim users will spend their time writing umpteen variations of the same name by playing with "_"; or whether Algol68
users will do the same with spaces.
BTW, C also is also case-insensitive in a few areas:
X ABCDEF P Any mix can be used in hex literals
x abcdef p
E/e Exponents
U/u L/l Numeric suffix
A bit radical of it to let the user choose between upper and lower case,
and let that make no difference!
On 30/11/2021 21:36, Bart wrote:
On 30/11/2021 13:58, David Brown wrote:
On 29/11/2021 23:40, Bart wrote:
But for commands, file names, program identifiers? Why would you want
them to be case insensitive? I mean, I agree that you don't want
commands "Copy", "copy" and "COPY" that all do different things. But
given a command "copy", why would you ever want to type "COPY" ? Given >>> a variable "noofwhatsits", what is the benefit of letting "noofwhatsits" >>> mean the same?
I've normalised both of your 'noofwhatsits' to have the same
capitalisation, ie. none.
Can you remember what the original was?
Yes. noOfWhatsits.
No? That's the probem.
No problem. The capitalisation was part of the identifier, and done intentionally. Perhaps you think that when a language is
case-sensitive, people pick their capitalisations randomly?
In the same way, no one using a case-sensitive language spends their
time making mixed-up case identifiers just to cause confusion.
And having worked with badly written code in case-insensitive languages
(such as Pascal), I can tell you it is /seriously/ confusing when the
same identifier is cased in different ways.
On 30/11/2021 21:44, David Brown wrote:
On 30/11/2021 21:36, Bart wrote:
On 30/11/2021 13:58, David Brown wrote:
On 29/11/2021 23:40, Bart wrote:
But for commands, file names, program identifiers? Why would you want >>>> them to be case insensitive? I mean, I agree that you don't want
commands "Copy", "copy" and "COPY" that all do different things. But >>>> given a command "copy", why would you ever want to type "COPY" ? Given >>>> a variable "noofwhatsits", what is the benefit of letting
"noofwhatsits"
mean the same?
I've normalised both of your 'noofwhatsits' to have the same
capitalisation, ie. none.
Can you remember what the original was?
Yes. noOfWhatsits.
No? That's the probem.
No problem. The capitalisation was part of the identifier, and done
intentionally. Perhaps you think that when a language is
case-sensitive, people pick their capitalisations randomly?
The Windows API contains 10,000 functions with specific capitalisations.
In the same way, no one using a case-sensitive language spends their
time making mixed-up case identifiers just to cause confusion.
Didn't I give you an example?
When I use my tool to convert C headers to
my syntax, I need to go through and fix all the clashes.
And having worked with badly written code in case-insensitive languages
(such as Pascal), I can tell you it is /seriously/ confusing when the
same identifier is cased in different ways.
And you don't find other people's C code confusing at all?
I've just done an interesting experiment on two of my programs: I took
the source code and a 100% lower case version and 100% upper case.
One program still worked with either version. The other worked after
tweaking one line to do with char constants.
I then tried the same experiment with a C version of the same program;
both versions failed, one on line 1, the other on line 4.
So, which version was more resilient to changes of case?
The experiment shows that you can much more easily refactor the case-insensitive language to use consistent capitalisation in a style
that you prefer, than case-sensitive.
I just have my preferences and you have yours.
On 01/12/2021 00:52, Bart wrote:
I just have my preferences and you have yours.
Yes, and that's fine. But drop the delusion that your unusual
collection of personal opinions is the absolute truth of how programming languages should be.
On 01/12/2021 08:15, David Brown wrote:
On 01/12/2021 00:52, Bart wrote:
I just have my preferences and you have yours.
Yes, and that's fine. But drop the delusion that your unusual
collection of personal opinions is the absolute truth of how programming
languages should be.
Here's a summary of what I've been talking about:
C (eg) Me
Case-sensitive Yes No
0-based Yes No (both 1-based and N-based)
Braces Yes No (keyword block delimiters)
Library Read/Print Yes No (read/print *statements*)
Char-based text i/o Yes No (line-oriented i/o)
Millions of ";" Yes No (line-oriented source)
It's just struck me that all the languages corresponding to the
left-hand column are generally more rigid and inflexible**.
The ones having attributes from the right are more forgiving, more
tolerant, and therefore more user-friendly. That would be a desirable attribute of a scripting language.
Since I develop both a compiled and scripting language which have the
same syntax, it's natural they should share the same attributes.
(** Except that when it comes to C, compilers for it tend to be too lax
in unsafe ways. You've got to get that semicolon just right, but never
mind that you've missed out a return statement in that non-void function!)
On 01/12/2021 11:44, Bart wrote:
On 01/12/2021 08:15, David Brown wrote:
On 01/12/2021 00:52, Bart wrote:
I just have my preferences and you have yours.
Yes, and that's fine. But drop the delusion that your unusual
collection of personal opinions is the absolute truth of how programming >>> languages should be.
Here's a summary of what I've been talking about:
C (eg) Me
Case-sensitive Yes No
0-based Yes No (both 1-based and N-based)
Braces Yes No (keyword block delimiters)
Library Read/Print Yes No (read/print *statements*) >> Char-based text i/o Yes No (line-oriented i/o)
Millions of ";" Yes No (line-oriented source) >>
It's just struck me that all the languages corresponding to the
left-hand column are generally more rigid and inflexible**.
The ones having attributes from the right are more forgiving, more
tolerant, and therefore more user-friendly. That would be a desirable
attribute of a scripting language.
Words like "flexible" are of questionable value - they mean different
things to different people. To me, C (and other languages with similar attributes to those you list here - C is an example, nothing more) is
more flexible. Being case-sensitive is more flexible than
case-insensitive because it lets you choose capitalisation that conveys
more information to the user.
Having 0-based arrays is more flexible
than 1-based arrays because it is easier to work with more complex structures.
(Allowing a choice of starting values, and other indexing
types, is much more flexible.)
Use of statement terminators or
separators (C has statement terminators, Pascal has statement
separators) makes the language more flexible because your source code
layout can match the structure of the code you want to express in the
way you want to write it, rather than being forced into lines.
Then there is the question of "tolerance" and "forgiving", and whether
that makes a language "user friendly". Here I can accept that your
language may be more "tolerant" and "forgiving", but that's based
entirely on your judgement - nothing on the list here is, IMHO, a matter
of "tolerance".
Since I develop both a compiled and scripting language which have the
same syntax, it's natural they should share the same attributes.
I disagree. They might share some aspects, but you have different uses
and different needs for a compiled language and a scripting language (otherwise, why have two languages at all?).
On 29/11/2021 14:06, Bart wrote:
This is just pure jealousy. Show me the C code needed to do the
equivalent of this (without knowing the types of a, b, c other than they
are numeric):
print "?"
readln a, b, c
println a, b, c
You are under the delusion that there is one "correct" interpretation
here. You think that /your/ ideas are the only "obvious" or "proper"
way to handle things. In reality, there are dozens of questions that
could be asked here, including:
Does there have to be a delimiter between the inputs? Does it have to
be comma, or space, or newline? Are these ignored if there are more
than one? Are numbers treated differently in the input? Would an input
of "true" be treated as a string or a boolean? Are there limits to the sizes?
On 29/11/2021 15:19, David Brown wrote:
On 29/11/2021 14:06, Bart wrote:
This is just pure jealousy. Show me the C code needed to do the
equivalent of this (without knowing the types of a, b, c other than they >>> are numeric):
print "?"
readln a, b, c
println a, b, c
You are under the delusion that there is one "correct" interpretation
here. You think that /your/ ideas are the only "obvious" or "proper"
way to handle things. In reality, there are dozens of questions that
could be asked here, including:
Does there have to be a delimiter between the inputs? Does it have to
be comma, or space, or newline? Are these ignored if there are more
than one? Are numbers treated differently in the input? Would an input >> of "true" be treated as a string or a boolean? Are there limits to the
sizes?
This also comes up in command-line parameters to shell commands.
There you can also ask all your questions. The difference is that rather
than not make itemised parameters available at all (eg. as a single
string), it decides on sensible defaults.
But they are still not as sensible as what I use for Read. In Windows or Linux, a command like:
prog a b c
returns those three args as 3 string parameters "a", "b", c". This:
prog a,b,c
returns one arg of "a,b,c". Here:
prog a, b, c
it results in 3 parameters "a," "b," "c" (notice the trailing commas).
prog "a b" c
gives 2 params "a b" and "c", without the quotes. So better than your
Python example. Here however:
prog *.c
Windows give one parameter "*.c", Linux gives *240* parameters. When I
try this:
prog *.c -option
Windows gives me "*.c" and "-option", but Linux now gives 241
parameters; information has been lost.
Anyway, imagine what a nuisance it would have been in C's main() was
defined like this:
int main(char* cmdline) {}
Just one string that you had to parse yourself.
When C decides to do something that is convenient, then that is great.
If I decide to do that, you have 101 reasons why it is a terrible idea.
NIH syndrome?
So the /shell/ is the bit that does the wildcard expansion.
Could this have been done differently? Sure.
Is this part
of the great conspiracy where everything in the computer world is made because of C, is worse because of C, and designed that way with the sole intention of annoying Bart? No.
On 06/12/2021 19:58, Bart wrote:
NIH syndrome?
It is not "C" that decides this. It is the OS conventions that is in
charge of passing information to the start of the program, in
cooperation with the runtime startup code. It is no coincidence that
you get the same arguments in argv in C and in sys.argv in Python.
So the /shell/ is the bit that does the wildcard expansion. It is
normal for shells on *nix to expand wildcards, and normal for the more minimal "command prompt" in DOS and Windows not to expand wildcards.
But you can have a shell in *nix that does not expand them, and a shell
in Windows that does.
It is the /OS/ and the the link-loader that splits command lines into
parts and passes them to the start of the program, regardless of the
language of the program.
Could this have been done differently? Sure. Could it have been done better? Other ways might have had some advantages, and some
disadvantages - better in some ways, less good in others. Is this part
of the great conspiracy where everything in the computer world is made because of C, is worse because of C, and designed that way with the sole intention of annoying Bart? No.
That might be the case on Unix where where the OS and C are so
intertwined that that you don't know where one ends and the other begins.
On 2021-12-07 08:14, David Brown wrote:
So the /shell/ is the bit that does the wildcard expansion.
That was a quite a problem back then. The damn thing ran out of memory expanding *'s on i368 25Mz machines we used.
Could this have been done differently? Sure.
In a well-designed system you would have a standard system library to
process the command line in a unified way. UNIX was a mixed bag trying
and failing to do both. In the end nobody respected any conventions and
UNIX utilities have totally unpredictable syntax of arguments.
[ Though I think UNIX missed an opportunity to make it even worse.
Consider if it not only expanded file lists but also opened the files
and passed the file descriptors to the process! ]
Is this part
of the great conspiracy where everything in the computer world is made
because of C, is worse because of C, and designed that way with the sole
intention of annoying Bart? No.
It is much bigger than Bart, the conspiracy, I mean... (:-))
On 07/12/2021 08:54, Dmitry A. Kazakov wrote:
On 2021-12-07 08:14, David Brown wrote:
So the /shell/ is the bit that does the wildcard expansion.
That was a quite a problem back then. The damn thing ran out of memory
expanding *'s on i368 25Mz machines we used.
With big enough sets of files or command lines, /something/ is going to
run out of memory!
[ Though I think UNIX missed an opportunity to make it even worse.
Consider if it not only expanded file lists but also opened the files
and passed the file descriptors to the process! ]
That would not make any sense - command line parameters are not
necessarily files!
On 07/12/2021 08:54, Dmitry A. Kazakov wrote:
On 2021-12-07 08:14, David Brown wrote:
So the /shell/ is the bit that does the wildcard expansion.
That was a quite a problem back then. The damn thing ran out of memory
expanding *'s on i368 25Mz machines we used.
With big enough sets of files or command lines, /something/ is going to
run out of memory!
In a well-designed system you would have a standard system library to
process the command line in a unified way. UNIX was a mixed bag trying
and failing to do both. In the end nobody respected any conventions and
UNIX utilities have totally unpredictable syntax of arguments.
It is far from being "totally unpredictable" - there are conventions
that are followed by most programs.
[ Though I think UNIX missed an opportunity to make it even worse.
Consider if it not only expanded file lists but also opened the files
and passed the file descriptors to the process! ]
That would not make any sense - command line parameters are not
necessarily files!
On 07/12/2021 09:57, David Brown wrote:
You said this:
It is the /OS/ and the the link-loader that splits command lines into parts and passes them to the start of the program, regardless of the language of the program.
That appears to be incorrect.
It might be happy coincidence that on Unix, at the entry point to a
program in any language, the parameter stack happens to contain suitable values of argc and argv, just like you get with C's main(); what a bit
of luck!
But I haven't seen that in Windows (or any previous OSes I've used).
Can you point me to a link which says that Windows does exactly the
same, or please say you were mistaken.
On 07/12/2021 10:22, Bart wrote:
That might be the case on Unix where where the OS and C are so
intertwined that that you don't know where one ends and the other begins.
No, /you/ don't know where one ends and the other begins - because you
have worked yourself into such an obsessive hatred of both
refuse to learn anything about either. Please don't judge others by
your own wilful ignorance - there are countless millions who manage to program in C and work with *nix (the two being independent in practice).
There's nothing wrong with preferring other languages and/or other
OS's, but your struggles with C and your dislike of *nix are a personal matter for you.
Please, find something new and interesting to post about rather than
your misconceptions, misunderstandings and FUD about languages and
systems that you don't like. It would be nice to get back to some
positive discussions.
It is the /OS/ and the the link-loader that splits command lines into
parts and passes them to the start of the program, regardless of the language of the program.
So the /shell/ is the bit that does the wildcard expansion. It is
normal for shells on *nix to expand wildcards, and normal for the more minimal "command prompt" in DOS and Windows not to expand wildcards.
But you can have a shell in *nix that does not expand them, and a shell
in Windows that does.
On 07/12/2021 10:56, Dmitry A. Kazakov wrote:
On 2021-12-07 11:33, Bart wrote:
On 07/12/2021 09:57, David Brown wrote:
You said this:
It is the /OS/ and the the link-loader that splits command lines into >>> > parts and passes them to the start of the program, regardless of the >>> > language of the program.
That appears to be incorrect.
Nope, it is perfectly correct. If external command line parsing
happens, then it is ultimately the OS that pushes the results to the
program.
On Windows it pushes nothing. Language start-up code needs to do the
work behinds the scenes so that user-programs can use entry-point
functions like:
main(argc, argv)
WinMain(Hinstance, etc)
Yes, it is part of the language. It is NOT the OS as David Brown stated.
It might be on Unix since Unix and C are so chummy.
On 2021-12-07 11:33, Bart wrote:
On 07/12/2021 09:57, David Brown wrote:
You said this:
It is the /OS/ and the the link-loader that splits command lines into
parts and passes them to the start of the program, regardless of the
language of the program.
That appears to be incorrect.
Nope, it is perfectly correct. If external command line parsing happens,
then it is ultimately the OS that pushes the results to the program.
It
a part of the interface between C's run-time and the OS.
Other languages
do more or less the same, e.g. see Ada RM A.15 The package Command_Line.
It might be happy coincidence that on Unix, at the entry point to a
program in any language, the parameter stack happens to contain
suitable values of argc and argv, just like you get with C's main();
what a bit of luck!
But I haven't seen that in Windows (or any previous OSes I've used).
Can you point me to a link which says that Windows does exactly the
same, or please say you were mistaken.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv?view=msvc-170
https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170
On 2021-12-07 12:22, Bart wrote:
On 07/12/2021 10:56, Dmitry A. Kazakov wrote:
On 2021-12-07 11:33, Bart wrote:
On 07/12/2021 09:57, David Brown wrote:
You said this:
It is the /OS/ and the the link-loader that splits command linesinto
parts and passes them to the start of the program, regardless of the >>>> > language of the program.
That appears to be incorrect.
Nope, it is perfectly correct. If external command line parsing
happens, then it is ultimately the OS that pushes the results to the
program.
On Windows it pushes nothing. Language start-up code needs to do the
work behinds the scenes so that user-programs can use entry-point
functions like:
main(argc, argv)
WinMain(Hinstance, etc)
Yes and that was the point. This happens *before* main() is called.
Yes, it is part of the language. It is NOT the OS as David Brown
stated. It might be on Unix since Unix and C are so chummy.
It is specified by the language and fulfilled by the OS.
Maybe, you
meant something like the context where parsing to happen:
Linux - The caller process
Windows - The callee process
xxx - The system kernel, maybe VxWorks would fall into this category, I am not sure
?
This is kind of pointless distinction, especially because processes in
Linux and Windows are very different.
It is the /OS/ and the the link-loader that splits command lines into
parts and passes them to the start of the program, regardless of the language of the program.
On 07/12/2021 12:00, Dmitry A. Kazakov wrote:
On 2021-12-07 12:22, Bart wrote:
On 07/12/2021 10:56, Dmitry A. Kazakov wrote:
On 2021-12-07 11:33, Bart wrote:
On 07/12/2021 09:57, David Brown wrote:
You said this:
It is the /OS/ and the the link-loader that splits command lines >>>>> into
parts and passes them to the start of the program, regardless of >>>>> the
language of the program.
That appears to be incorrect.
Nope, it is perfectly correct. If external command line parsing
happens, then it is ultimately the OS that pushes the results to the
program.
On Windows it pushes nothing. Language start-up code needs to do the
work behinds the scenes so that user-programs can use entry-point
functions like:
main(argc, argv)
WinMain(Hinstance, etc)
Yes and that was the point. This happens *before* main() is called.
But *after* execution commences at the program's official entry point,
by the language's startup code.
What it comes down is that, if you are implementing a language, these argc/argv values don't magically appear on the stack, not on Windows.
The language must arrange for that to happen.
The only WinAPI function I know of that gives that info is
GetCommandLine, which delivers a single string you have to process.
If you know of a better WinAPI function on Windows, or of some exported
data from a Windows DLL that provides the same info, or perhaps of some
data block within the loaded PE image that contains it, then I will use
that instead.
Maybe, you meant something like the context where parsing to happen:
Linux - The caller process
Windows - The callee process
xxx - The system kernel, maybe VxWorks would fall into this >> category, I am not sure
?
This is kind of pointless distinction, especially because processes in
Linux and Windows are very different.
Well, I was responding to this:
DB:
It is the /OS/ and the the link-loader that splits command lines into parts and passes them to the start of the program, regardless of the language of the program.
The distinction was important since it is this very process that is
commonly done on Unix and/or C, which is equivalent to what I do with
Read on every line. Apparently it's OK when C (and/or Unix) does it on
the command line, but not OK when a language does it on any input line.
On 2021-12-07 14:57, Bart wrote:
Yes and that was the point. This happens *before* main() is called.
But *after* execution commences at the program's official entry point,
by the language's startup code.
The official entry point of a C console program is main().
What it comes down is that, if you are implementing a language, these
argc/argv values don't magically appear on the stack, not on Windows.
The language must arrange for that to happen.
The linker, there is a switch to instruct the MS linker which CRT to
link to the executable. E.g. one can link one that skips command line
parsing altogether.
The only WinAPI function I know of that gives that info is
GetCommandLine, which delivers a single string you have to process.
If you know of a better WinAPI function on Windows, or of some
exported data from a Windows DLL that provides the same info, or
perhaps of some data block within the loaded PE image that contains
it, then I will use that instead.
CommandLineToArgv[A|W]
Why do you think it should be physically stored in the process address
space in the first place? It might be the case for a very primitive OS
UNIX was when it was developed. These days it could be anywhere. You
know there is GetCommandLineA and GetCommandLineW, which one is a fake?
Why do you even care?
Maybe, you meant something like the context where parsing to happen:
Linux - The caller process
Windows - The callee process
xxx - The system kernel, maybe VxWorks would fall into this >>> category, I am not sure
?
This is kind of pointless distinction, especially because processes
in Linux and Windows are very different.
Well, I was responding to this:
DB:
It is the /OS/ and the the link-loader that splits command lines into
parts and passes them to the start of the program, regardless of the
language of the program.
The distinction was important since it is this very process that is
commonly done on Unix and/or C, which is equivalent to what I do with
Read on every line. Apparently it's OK when C (and/or Unix) does it on
the command line, but not OK when a language does it on any input line.
I have no idea what this is supposed to mean.
In any case, fetching the command params is done after the application
has started running.
What it comes down is that, if you are implementing a language, these
argc/argv values don't magically appear on the stack, not on Windows.
The language must arrange for that to happen.
The linker, there is a switch to instruct the MS linker which CRT to
link to the executable. E.g. one can link one that skips command line
parsing altogether.
I don't use a linker...
But if what you say is correct, then this is still code that is within
the application.
The only WinAPI function I know of that gives that info is
GetCommandLine, which delivers a single string you have to process.
If you know of a better WinAPI function on Windows, or of some
exported data from a Windows DLL that provides the same info, or
perhaps of some data block within the loaded PE image that contains
it, then I will use that instead.
CommandLineToArgv[A|W]
This would be the next step /after/ calling GetCommandLine.
This subthread is about the similarity between:
- Command line parsing (chopping one input line into separate args)
- My language's Readln which reads separate items from one input line
DB said the latter can't possibly work because of too many unknowns. Yet
it hasn't stopped shells using command line parameters.
On 2021-12-07 17:54, Bart wrote:
In any case, fetching the command params is done after the application
has started running.
No, the process /= application. There is a lot of things happening
between creation of a process and the application running on the context
of that process (or processes).
DB said the latter can't possibly work because of too many unknowns.
Yet it hasn't stopped shells using command line parameters.
He is right.
1. If the OS does not impose a specific way of treating parameters,
there is no safe way to process arguments.
2. If the OS, as Linux does, requires parameters pre-parsed outside the process, there are again limits to what could be done. E.g. in Linux
there is no reliable way to get the original command line it simply
might not exist.
In both cases there is absolutely no guarantee of any correspondence
between the "perceived" command line and what the process gets.
On 07/12/2021 19:31, Dmitry A. Kazakov wrote:
On 2021-12-07 17:54, Bart wrote:
In any case, fetching the command params is done after the
application has started running.
No, the process /= application. There is a lot of things happening
between creation of a process and the application running on the
context of that process (or processes).
OK, it has to load the PE and do a bunch of fixups, but eventually it
will pass control to the entry point.
Then, where are the command line parameters to be found?
I can tell you they are not on the stack, which is where they must be
if C's main(argc, argv) is to work properly.
They have to be put there Windows will not do that. The
application's language's startup code must do it.
That's the bit /I/ write.
The point is that C, somehow, ended up with a scheme where that one
line of commands WAS processed into convenient chunks for the
application work work.
But I can see that I'm banging my head against a brick wall:
* No one here is ever going to admit that Bart's Readln statements
might actually be a good idea, despite C command-line processing
doing pretty much the same thing.
* And apparently no one is going to admit that that command-line
processing is not actually done automatically by Windows; it is up to
the startup code of a language implementation to get it sorted
So, why can't a language also specify a set of defaults for proper line-reading routines:
readln a, b, c
But I can see that I'm banging my head against a brick wall:
* No one here is ever going to admit that Bart's Readln statements
might actually be a good idea, despite C command-line processing
doing pretty much the same thing.
On 07/12/2021 21:49, Bart wrote:
So, why can't a language also specify a set of defaults for proper
line-reading routines:
readln a, b, c
But I can see that I'm banging my head against a brick wall:
* No one here is ever going to admit that Bart's Readln statements
might actually be a good idea, despite C command-line processing
doing pretty much the same thing.
You are not the only one who feels like he is banging his head against a wall. You misinterpret everything though your paranoia.
Your "readln" could be a perfectly good solution - for /your/ language,
and /your/ needs. Something similar could be useful in wider contexts.
Where you are wrong, however, is in your believe that it is somehow
better than any other solution, or that it covers other peoples' needs,
or that it is somehow "fundamental" and something that should be part of
any language.
It doesn't cover typing, formatting, separators, syntax matching,
errors, or any of a dozen other possible requirements. If you don't
need any of that - you've just got a little script or a dedicated
program run in a specific way - then that's fine. People who need
something more, can't use it.
And no, just because you don't like C's input facilities does not mean
your methods are naturally superior.
And just because someone says your readln is too limited and simplistic,
does not mean they think C's alternatives are good or complete.
A low-level language needs basic, raw input facilities that you can use
to build the high-level input concepts that you need for your use. It
does not need high-level input facilities - those should be in libraries
so the user can choose what they need at the time (either from standard libraries of common solutions, or roll their own specialist one).
A simple, limited high-level language can get away with saying "this is
what you get - take it or leave it". Much of the programming world left
such philosophies behind decades ago, but if you want to hang onto it
with your own language, that's up to you - that's an advantage of having
your own language.
On 2021-12-07 10:44, David Brown wrote:
On 07/12/2021 08:54, Dmitry A. Kazakov wrote:
[ Though I think UNIX missed an opportunity to make it even worse.
Consider if it not only expanded file lists but also opened the files
and passed the file descriptors to the process! ]
That would not make any sense - command line parameters are not
necessarily files!
They are, unless introduced by a symbol of a key, e.g. /a, -a, --a etc,
so was the "convention." I never liked it, BTW.
On 07/12/2021 10:14, Dmitry A. Kazakov wrote:
On 2021-12-07 10:44, David Brown wrote:
On 07/12/2021 08:54, Dmitry A. Kazakov wrote:
...
[ Though I think UNIX missed an opportunity to make it even worse.
Consider if it not only expanded file lists but also opened the files
and passed the file descriptors to the process! ]
That would not make any sense - command line parameters are not
necessarily files!
They are, unless introduced by a symbol of a key, e.g. /a, -a, --a
etc, so was the "convention." I never liked it, BTW.
What convention would you prefer? I have tried to come up with something better but without success.
BTW, words on a command line don't have to be file names.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 185 |
Nodes: | 16 (1 / 15) |
Uptime: | 03:38:25 |
Calls: | 3,676 |
Calls today: | 2 |
Files: | 11,149 |
Messages: | 3,447,258 |