What do you think would be best as a power operator? Or should power be calculated by a function as in C?
For decades programming languages have used an 'E notation' to indicate "times 10 to the power of" as in
1e3 1 times 10 to the power of 3
4.5e-2 4.5 times 10 to the power of -2
I think it goes back as far as Fortran and maybe even further into early assembly languages but is it the best way?
I came up with (not implemented yet) something else. IMO it's better but
see what you think. I would express the above two numbers as
10^3 10 to the power of 3
4.5x10^-2 4.5 times 10 to the power of -2
(Yes, that's a lower-case x,)
Two advantages (AISI):
1. It looks closer to what a mathematician would write.
2. It includes the base so bases other than 10 would be possible, if required, but the presence of the base is no impediment as even if it's always 10 it helps make the number look more natural.
One thing I should mention that may be a bit controversial is that in
keeping with other operators space matters.
10^3
is a literal integer meaning 1000 whereas
10 ^ 3
is an expression which would evaluate to 1000. Space must be on both
sides of ^ or neither. Both of
10^ 3
10 ^3
would be invalid.
On 2021-11-08 20:46, James Harris wrote:
10^3 10 to the power of 3
4.5x10^-2 4.5 times 10 to the power of -2
(Yes, that's a lower-case x,)
You can use the Unicode symbol ⋅ instead (U+22C5). There exists ⨯ (U+2A2F) too, but that is vector product.
Two advantages (AISI):
1. It looks closer to what a mathematician would write.
In this case you must orient rather on physicists and chemists.
2. It includes the base so bases other than 10 would be possible, if
required, but the presence of the base is no impediment as even if
it's always 10 it helps make the number look more natural.
Just apply the base to the exponent as Ada does:
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
One thing I should mention that may be a bit controversial is that in
keeping with other operators space matters.
10^3
is a literal integer meaning 1000 whereas
10 ^ 3
That would be an argument against using ^ for both.
Note that the same
issue apply to unary - and +. This the reason why
+10
is not a literal in Ada, it is an expression.
Note also how this is connected to the approach to the types of the
literals. You need silly rules like below:
is an expression which would evaluate to 1000. Space must be on both
sides of ^ or neither. Both of
10^ 3
10 ^3
would be invalid.
because you could not consistently fold constant expressions making all
cases equal. Ada has no such problem, e.g.
-32768
is perfectly OK for a 16-bit 2's complement integer regardless the fact
that the literal 32768 is out of the range.
Exponentiation would have the same problem as -, though much more
rarely, of course.
Just apply the base to the exponent as Ada does:
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
On 08/11/2021 20:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
I avoided mentioning numbers with different bases because it was too
much to show at once. Besides, it looked potentially confusing to have a number base and an exponent base. But since you bring it up my notation
for that binary number is
2'111'x2^7
On 08/11/2021 20:26, Dmitry A. Kazakov wrote:
On 2021-11-08 20:46, James Harris wrote:
In this case you must orient rather on physicists and chemists.
LOL! Why is that?
2. It includes the base so bases other than 10 would be possible, if
required, but the presence of the base is no impediment as even if
it's always 10 it helps make the number look more natural.
Just apply the base to the exponent as Ada does:
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
I avoided mentioning numbers with different bases because it was too
much to show at once. Besides, it looked potentially confusing to have a number base and an exponent base. But since you bring it up my notation
for that binary number is
2'111'x2^7
Note that the same issue apply to unary - and +. This the reason why
+10
is not a literal in Ada, it is an expression.
What's the problem?
FWIW I wanted to be able to write explicitly unsigned integer literals
and so use + as follows.
10 weak signed integer of value 10
-10 weak signed integer of value -10
+10 weak unsigned integer (of value 10)
Again, that sounds interesting but it appears to defy logic. What does
it mean?
On 08/11/2021 19:46, James Harris wrote:
What do you think would be best as a power operator? Or should power
be calculated by a function as in C?
Don't copy C.
It's pow() function works for one type at a time. You will need multiple versions for different types, just like you have to with abs: abs()
labs(), llabs(), fabs(), fabs().
There are no versions of pow() for ints
that I'm aware of.
If you like 'pow', just use that with function-like syntax, but make it overloaded like '+' and '*'.
For a symbolic operator, either ** or ^ is fine.
On 08/11/2021 21:04, Bart wrote:
On 08/11/2021 19:46, James Harris wrote:
What do you think would be best as a power operator? Or should power
be calculated by a function as in C?
Don't copy C.
I too think an operator would be nice.
It's pow() function works for one type at a time. You will need multiple
versions for different types, just like you have to with abs: abs()
labs(), llabs(), fabs(), fabs().
Or if you live in this century, you use <tgmath.h> and it's all just
fabs(), pow(), etc., for any floating point types.
On 08/11/2021 20:52, James Harris wrote:
On 08/11/2021 20:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
I avoided mentioning numbers with different bases because it was too
much to show at once. Besides, it looked potentially confusing to have
a number base and an exponent base. But since you bring it up my
notation for that binary number is
2'111'x2^7
What /is/ the number? Is it 7 * 2**7 or 5 x 2**7? Having two 7s is
confusing!
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:(Surely you mean 7 * 2**7 ?)
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
Ada's system for non-decimal numbers has always struck me as flexible,
but possibly the ugliest and most difficult to read and write method I
have ever seen.
How often does anyone need a base other than 2, 10, or 16 ? If you are
into computer palaeontology, perhaps you also want octal - but that's stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
I have a hard time seeing how it would be possible to get something more convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
Other bases
don't turn up in real code, nor do floating point in anything other than decimal.
You'll want a digit separator, however - underscore is
probably the best choice.
(I'm omitting C's octals and hexadecimal floating point notations, and I don't think the type suffixes are a good solution.)
On 08/11/2021 21:25, David Brown wrote:
On 08/11/2021 21:04, Bart wrote:
On 08/11/2021 19:46, James Harris wrote:
What do you think would be best as a power operator? Or should power
be calculated by a function as in C?
Don't copy C.
I too think an operator would be nice.
It's pow() function works for one type at a time. You will need multiple >>> versions for different types, just like you have to with abs: abs()
labs(), llabs(), fabs(), fabs().
Or if you live in this century, you use <tgmath.h> and it's all just
fabs(), pow(), etc., for any floating point types.
If it's only for floats, how many are there? There's only float and
double unless you're interested in complex.
tgmath.h is anyway not universal. tcc doesn't have it. MSVC warns its
version is not compatible with C99 (possibly due to not have _Generic).
(You have to use ctgmath.h, for C++.)
So it's still messy, and not an approach to be copied.
On 2021-11-08 22:37, David Brown wrote:
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:(Surely you mean 7 * 2**7 ?)
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
Yes.
Ada's system for non-decimal numbers has always struck me as flexible,
but possibly the ugliest and most difficult to read and write method I
have ever seen.
How often does anyone need a base other than 2, 10, or 16 ? If you are
into computer palaeontology, perhaps you also want octal - but that's
stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
I have a hard time seeing how it would be possible to get something more
convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
And how would by do:
16#0.FF03_8A90_FE1E#E-5
p instead of E looks totally out of place.
Other bases
don't turn up in real code, nor do floating point in anything other than
decimal.
Maybe, but it is simpler to have them for the regularity sake.
You'll want a digit separator, however - underscore is
probably the best choice.
Yes, like in Ada.
(I'm omitting C's octals and hexadecimal floating point notations, and I
don't think the type suffixes are a good solution.)
A Unicode alternative would be using the mathematical notation for the
base:
1101₂
Exponents would be superscript as James suggested:
0.FF03_8A90_FE1E₁ ₆16⁵
Not very readable in a fixed font.
P.S. I actually used such stuff in the UI, e.g. to annotate axes in
graphs and for measurement units. You really want to see m/s² rather
than m/(s^2) or whatever.
templates, or whatever. (It should not, however, be done with built-in functions or operators - these are library functions in any
well-designed language.)
On 2021-11-08 21:52, James Harris wrote:
In this case you must orient rather on physicists and chemists.
LOL! Why is that?
Who else would ever use such numbers? (:-)
But how would you explain a non-medicated person why
a-10
must be illegal?
Again, that sounds interesting but it appears to defy logic. What does
it mean?
It is quite logical to me that
-32768
and
- 32768
mean exactly same and the second would not suddenly overflow.
On 08/11/2021 23:18, Dmitry A. Kazakov wrote:
On 2021-11-08 22:37, David Brown wrote:
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:(Surely you mean 7 * 2**7 ?)
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
Yes.
Ada's system for non-decimal numbers has always struck me as flexible,
but possibly the ugliest and most difficult to read and write method I
have ever seen.
How often does anyone need a base other than 2, 10, or 16 ? If you are >>> into computer palaeontology, perhaps you also want octal - but that's
stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
I have a hard time seeing how it would be possible to get something more >>> convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
And how would by do:
16#0.FF03_8A90_FE1E#E-5
p instead of E looks totally out of place.
When would you ever need it? Who has /ever/ had need of writing a hexadecimal fraction?
Other bases
don't turn up in real code, nor do floating point in anything other than >>> decimal.
Maybe, but it is simpler to have them for the regularity sake.
Not if it means the common cases of binary and hex integers are so
hideous to work with. Have an extra mess to allow base 13 floating
point if you want, but don't drag binary and hex into it.
A Unicode alternative would be using the mathematical notation for the
base:
1101₂
That would work, except that almost no one could type it. (Even on
*nix, few people have a compose key enabled, and few of them know that ₂
is compose + underscore + 2.)
Unicode can be fine for text strings - I agree that ms⁻² or m/s² is
nice. But it is not a good choice for key parts of a language.
On 08/11/2021 21:39, Dmitry A. Kazakov wrote:
On 2021-11-08 21:52, James Harris wrote:
But how would you explain a non-medicated person why
a-10
must be illegal?
If it's meant to be the name of an identifier it would presumably be undeclared so the compiler would report it as such.
If, on the other hand, it's meant to be a subtraction but lacks required whitespace the compiler could still report it. In fact, it would be easy enough for the compiler to provide apropos hints to people coming from
other languages.
Again, that sounds interesting but it appears to defy logic. What
does it mean?
It is quite logical to me that
-32768
and
- 32768
mean exactly same and the second would not suddenly overflow.
Didn't you say they were int 16s in which such a number would be invalid?
On 2021-11-08 22:37, David Brown wrote:
I have a hard time seeing how it would be possible to get something more
convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
And how would by do:
16#0.FF03_8A90_FE1E#E-5
A Unicode alternative would be using the mathematical notation for the
base:
1101₂
Exponents would be superscript as James suggested:
0.FF03_8A90_FE1E₁ ₆16⁵
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
How often does anyone need a base other than 2, 10, or 16 ?
If you are
into computer palaeontology, perhaps you also want octal - but that's stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
I have a hard time seeing how it would be possible to get something more convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
Other bases
don't turn up in real code, nor do floating point in anything other than decimal. You'll want a digit separator, however - underscore is
probably the best choice.
(I'm omitting C's octals and hexadecimal floating point notations, and I don't think the type suffixes are a good solution.)
On 2021-11-08 23:56, David Brown wrote:
On 08/11/2021 23:18, Dmitry A. Kazakov wrote:
On 2021-11-08 22:37, David Brown wrote:
Other bases
don't turn up in real code, nor do floating point in anything other
than
decimal.
Maybe, but it is simpler to have them for the regularity sake.
Not if it means the common cases of binary and hex integers are so
hideous to work with. Have an extra mess to allow base 13 floating
point if you want, but don't drag binary and hex into it.
The beauty is in the eye of beholder. I find 0xFE hideous and illogical.
Yes. I am against Unicode in the programming language even in the string literals.
On 2021-11-09 09:14, James Harris wrote:
On 08/11/2021 21:39, Dmitry A. Kazakov wrote:
On 2021-11-08 21:52, James Harris wrote:
But how would you explain a non-medicated person why
a-10
must be illegal?
If it's meant to be the name of an identifier it would presumably be
undeclared so the compiler would report it as such.
If, on the other hand, it's meant to be a subtraction but lacks
required whitespace the compiler could still report it. In fact, it
would be easy enough for the compiler to provide apropos hints to
people coming from other languages.
What kind of hints?
On 08/11/2021 22:43, David Brown wrote:
templates, or whatever. (It should not, however, be done with built-in
functions or operators - these are library functions in any
well-designed language.)
Why?
+ and * aren't usually library functions, what's special about **?
These operations are fundamental. My Casio calculator has dedicated
buttons for Abs, **, sqrt, square, log, sin and so on.
And what would you be missing out on if they /were/ built-in?
Anyone can add versions implemented via user-functions if they really
want; vice-versa is a little harder.
On 09/11/2021 00:52, Bart wrote:
On 08/11/2021 22:43, David Brown wrote:
templates, or whatever. (It should not, however, be done with built-in >>> functions or operators - these are library functions in any
well-designed language.)
Why?
+ and * aren't usually library functions, what's special about **?
"pow" could be an operator - that's not unreasonable. I really meant
the others maths functions.
These operations are fundamental. My Casio calculator has dedicated
buttons for Abs, **, sqrt, square, log, sin and so on.
We are discussing programming languages, not calculators.
And what would you be missing out on if they /were/ built-in?
Anyone can add versions implemented via user-functions if they really
want; vice-versa is a little harder.
There are many reasons to choose to implement all the various
mathematical functions as library functions (preferably a language
standard library):
It keeps the language itself smaller, making it easier to document, implement, use, and update.
A language for modern times needs namespaces, libraries or modules,
a
way of defining simple functions that gives the compiler full insight
(like inline functions) to avoid function call overheads and to allow
extra knowledge,
and a way of using a single function declaration with
multiple types, using either generic definitions or specialised definitions.
These are, I think, required features for a useful modern language. If
you don't have those, you might as well not bother (unless the language
is /very/ niche).
And once you have them, putting abs, log, sin, and anything else into a library is easy.
You might even want to make operators fully programmable, and then
"power" can be an operator defined in the library.
On 08/11/2021 21:37, David Brown wrote:
I have a hard time seeing how it would be possible to get something more
convenient and unambiguous than 123.6e5, 0xbeef, 0b1101. Other bases
don't turn up in real code,
I use base 1'000'000'000 in one of my libraries. But it doesn't have
language support!
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:(Surely you mean 7 * 2**7 ?)
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
Ada's system for non-decimal numbers has always struck me as flexible,
but possibly the ugliest and most difficult to read and write method I
have ever seen.
How often does anyone need a base other than 2, 10, or 16 ?
If you are
into computer palaeontology, perhaps you also want octal - but that's stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
I have a hard time seeing how it would be possible to get something more convenient and unambiguous than 123.6e5, 0xbeef, 0b1101. Other bases
don't turn up in real code,
On 09/11/2021 11:05, David Brown wrote:
On 09/11/2021 00:52, Bart wrote:
On 08/11/2021 22:43, David Brown wrote:
templates, or whatever. (It should not, however, be done with built-in >>>> functions or operators - these are library functions in any
well-designed language.)
Why?
+ and * aren't usually library functions, what's special about **?
"pow" could be an operator - that's not unreasonable. I really meant
the others maths functions.
These operations are fundamental. My Casio calculator has dedicated
buttons for Abs, **, sqrt, square, log, sin and so on.
We are discussing programming languages, not calculators.
You're missing the point of the calculator: there are limited number of dedicated buttons, but they decided Abs etc were fundamental enough to
have their own button.
Similar to how I decided they were fundamental enough to be
dedicated built-in operators.
And what would you be missing out on if they /were/ built-in?
Anyone can add versions implemented via user-functions if they really
want; vice-versa is a little harder.
There are many reasons to choose to implement all the various
mathematical functions as library functions (preferably a language
standard library):
It keeps the language itself smaller, making it easier to document,
implement, use, and update.
Why is that important, considering that adding those built-ins amounts
to a few 10s of KB, but typical implementations run to 10s or 100s of MB?
Since the language needs those functions, it still needs to add them but
now needs headers, templates, generics, ... a whole raft of machinery.
And for the user? They have to muck around doing stuff like this:
#include <tgmath.h> // for fabs
#include <stdlib.b> // for abs, labs, llabs
Then need to decide exactly which alternate to apply, and then, if a
type T changes from int to long int, change 100 instances of abs to labs.
I think I'll stick with my approach, thanks.
A language for modern times needs namespaces, libraries or modules,
Namespaces: check
Libraries: check (even if rather meagre ATM)
Modules: check
a
way of defining simple functions that gives the compiler full insight
(like inline functions) to avoid function call overheads and to allow
extra knowledge,
Whole program compilation: check (but not taking advantage yet)
and a way of using a single function declaration with
multiple types, using either generic definitions or specialised
definitions.
Generics: [pause to switch to my dynamic language] check
These are, I think, required features for a useful modern language. If
you don't have those, you might as well not bother (unless the language
is /very/ niche).
And once you have them, putting abs, log, sin, and anything else into a
library is easy.
With the library again! I've had abs, log, sin etc as builtins since the early 80s. That was when I had to implement float arithmetic in
software. Now that /was/ a library, but used to transparently support
A+B*C in the language, just like I do now with sin etc.
Since my compilers have always had poor optimisers, the advantage of a built-in is that it makes it easier to generate inline code, rather than
have to try and inline a function. Which would anyway take extra resources.
So if I now do:
real x, y
y := abs(x)
The IR is:
push x r64
abs r64
pop y r64
And the x64 code is:
mov xmm4, R.x # R.x R.y are xmm registers
andpd xmm4, [...]
mov R.y, xmm54
(This could be optimised better to two instructions)
You might even want to make operators fully programmable, and then
"power" can be an operator defined in the library.
And again! You've been coding in C too long. I bet that if C had had
'pow' as a built-in operator from the start, then you would have a
different view now.
On 09/11/2021 11:36, Bart wrote:
On 08/11/2021 21:37, David Brown wrote:
...
I have a hard time seeing how it would be possible to get something more >>> convenient and unambiguous than 123.6e5, 0xbeef, 0b1101. Other bases
don't turn up in real code,
I use base 1'000'000'000 in one of my libraries. But it doesn't have
language support!
And you would want to write constants in that base...?!
On 08/11/2021 21:37, David Brown wrote:
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
...
How often does anyone need a base other than 2, 10, or 16 ?
You mean you don't write out many gene sequences? ;-)
If you are
into computer palaeontology, perhaps you also want octal - but that's
stretching things (I believe most cases of C octal constants, such as
0123, are mistakes - the programmer probably mean 123).
That problem wasn't in BCPL which allowed, AIUI, any of
#O100
#o100
#100
but the problem was introduced in B which had the rule: "An octal
constant is the same as a decimal constant except that it begins with a zero".
It's curious as to how popular octal was back then that languages made
it the easiest to type.
I have a hard time seeing how it would be possible to get something more
convenient and unambiguous than 123.6e5, 0xbeef, 0b1101.
If you are talking about C having those I am surprised to see the 0b notation. When was it introduced?
It took me a long time and many iterations to come up with a good
notation for numbers in bases other than decimal (a case of lots of work
to make something that looks simple) but I am pleased with the result.
Your two non-decimals would be
0xbeef --> 16'beef'
0b1101 --> 2'1101'
IMO the result is logical, flexible and readable but YMMV. And, yes, it
uses underscore for digit separation.
Other bases
don't turn up in real code, nor do floating point in anything other than
decimal. You'll want a digit separator, however - underscore is
probably the best choice.
(I'm omitting C's octals and hexadecimal floating point notations, and I
don't think the type suffixes are a good solution.)
Agreed.
On 09/11/2021 13:12, Bart wrote:
You're missing the point of the calculator: there are limited number of
dedicated buttons, but they decided Abs etc were fundamental enough to
have their own button.
It is a /calculator/. Either it is a dedicated function on a button, or
it doesn't happen. It is not a programming language!
You might as well
try to tell us that "purple" is a "fundamental colour" because you have
a purple crayon in your pencil case.
Generics: [pause to switch to my dynamic language] check
An unwillingness to use your own features: check
And again! You've been coding in C too long. I bet that if C had had
'pow' as a built-in operator from the start, then you would have a
different view now.
I code in many languages.
Drag yourself out of your ancient history,
and you'll maybe see it makes little sense to put everything into one
pot.
itself, and everything else in libraries.
really have much in the way of fundamental types, but provides a way to
make the types you need. That makes it more flexible and powerful than languages with fixed integer types.
Again, I'm not reimplementating Ada.
It's okay - it's better than Ada, IMHO, since the apostrophe is not as
dense a character as the hash in Ada.
This is the big new idea which is better than my '1980s' language, which
is so easy to implement.
On 09/11/2021 15:18, Bart wrote:
Again, I'm not reimplementating Ada.
No, you are not. Ada is a language lots of people use. Your languages
have one aim, and one aim only - to be languages that suit /you/.
But really, this thread is not about what /you/ use for your old
languages designed in the 80's using ideas from the 60's.
It is about
what makes sense for James to use in his language, or what other people
think might be good in other languages.
On 2021-11-09 18:28, Bart wrote:
This is the big new idea which is better than my '1980s' language,
which is so easy to implement.
You know what? Ford model T is pretty easy to build. Would you start
building such cars to compete with Elon?
There are certain expectations people have buying a car today.
is true for programming languages.
On 08/11/2021 22:56, Bart wrote:
tgmath.h is anyway not universal. tcc doesn't have it. MSVC warns its
version is not compatible with C99 (possibly due to not have _Generic).
(You have to use ctgmath.h, for C++.)
I have little interest in half-baked sort-of-C compilers. MSVC has traditionally had terrible C support
- perhaps because they want users
to think C is bad and choose lock-in C# instead. I have heard that the
more recent versions of MSVC are better, but have not tried them myself.
tcc is a toy
DB hasn't answered yet, perhaps you can: what exactly is the problem
with having SQRT, say, as a built-in function or operator in a language?
Someone give me a convincing answer, and I will change my
implementation, provided it doesn't involve reimplementing the whole of
C++, and making my build-times 100 times slower.
On 2021-11-09 19:33, Bart wrote:
DB hasn't answered yet, perhaps you can: what exactly is the problem
with having SQRT, say, as a built-in function or operator in a language?
Occam's Razor and you cannot really have it.
You can have an operator with the name sqrt, but you cannot have sqrt
itself. Would you implement matrix sqrt for all possible combinations of matrix index and matrix elements? Complex sqrt with two branches? There
are thousands of different sqrt's, there are specialized low accuracy variants for graphic rendering, the number of variants is basically
infinite
On 09/11/2021 15:18, Bart wrote:
Again, I'm not reimplementating Ada.
But really, this thread is not about what /you/ use for your old
languages designed in the 80's using ideas from the 60's. It is about
what makes sense for James to use in his language, or what other people
think might be good in other languages.
On 09/11/2021 20:59, Dmitry A. Kazakov wrote:
On 2021-11-09 19:33, Bart wrote:
DB hasn't answered yet, perhaps you can: what exactly is the problem
with having SQRT, say, as a built-in function or operator in a language?
Occam's Razor and you cannot really have it.
You can have an operator with the name sqrt, but you cannot have sqrt
itself. Would you implement matrix sqrt for all possible combinations
of matrix index and matrix elements? Complex sqrt with two branches?
There are thousands of different sqrt's, there are specialized low
accuracy variants for graphic rendering, the number of variants is
basically infinite
You can make the same remarks about multiply:
On 09/11/2021 15:31, David Brown wrote:
On 09/11/2021 15:18, Bart wrote:
Again, I'm not reimplementating Ada.
No, you are not. Ada is a language lots of people use. Your languages
have one aim, and one aim only - to be languages that suit /you/.
Actually, lots of people could use my language designs too. They just
need a decent implementation.
With C, lots of people have put in that work (it must be the most
implemented language on the planet).
Now you might want to tell me why my way of making available **, sqrt
and sin is completely unsuitable for EVERYONE except me. I don't get it.
Come on, what would they be missing out on if my way wasn't just a copy
of how C does everything.
(Which BTW is a sham; gcc compiling C treats abs etc as though they are built-ins just like mine.
It knows the advantages that my approach brings, such as being able
reduce constant expressions involving those ops. But it still has to
work within C's ancient framework, so it has to make a show of them
being user-functions and allow people to override them with their own versions.)
But really, this thread is not about what /you/ use for your old
languages designed in the 80's using ideas from the 60's.
It is about
what makes sense for James to use in his language, or what other people
think might be good in other languages.
OK, so your idea is for:
* The language to know NOTHING about abs, sqrt, sin etc
* They should be user-functions like any other, which just reside in
some standard library
* The language needs to acquire function overloading, or some generic features, to make those functions work on different types
* The language possibly needs an inline assembler so that those
functions can be implemented efficiently where there are special
instructions available
* The language needs advanced optimisation methods, link-time optimising
etc so that the code for some of these function can be inlined
* The language needs even more advanced techniques such as C++'s
constexpr, so that constant expressions involving abs, sqrt etc can be reduced to a constant value
This is the big new idea which is better than my '1980s' language, which
is so easy to implement.
James can make up his own mind of course. My suggestion is to make a lot
of these built-ins, so that those big features above are not essential
just to get sqrt working.
On 08/11/2021 22:43, David Brown wrote:
On 08/11/2021 22:56, Bart wrote:
tgmath.h is anyway not universal. tcc doesn't have it. MSVC warns its
version is not compatible with C99 (possibly due to not have _Generic).
(You have to use ctgmath.h, for C++.)
I have little interest in half-baked sort-of-C compilers. MSVC has
traditionally had terrible C support
So, MSVC doesn't count.
- perhaps because they want users
to think C is bad and choose lock-in C# instead. I have heard that the
more recent versions of MSVC are better, but have not tried them myself.
tcc is a toy
So, tcc doesn't count.
(And it's definitely not a toy - try writing something half as good. It
turns working C code into executable binary code that runs at half the
speed of -O3.
But it checks fewer things, and has the odd thing missing - like
tgmath.h. For building debugged code and doing it quickly, it is does
that job well.)
I've just now tried Clang. That is, Clang running on Windows, part of an large LLVM installation, and with links into MSBUILD tools.
With this program:
#include <tgmath.h>
It gives 20 errors before it give up.
I guess, Clang doesn't count either! Apparently the only one that counts
is yours.
Somehow I don't get the impression that C has solved the problem of overloading pow(), even for the two float types that most people use.
But you seem to like blaming implementations and OSes instead of blaming
the language.
Mine runs on Windows and yet overloaded ** runs fine.
On 09/11/2021 18:28, Bart wrote:
Now you might want to tell me why my way of making available **, sqrt
and sin is completely unsuitable for EVERYONE except me. I don't get it.
It is unsuitable as a way of designing a language.
For /users/ of a
language, it usually makes little difference if "abs" is a built-in
function or a library function.
For people involved in implementing,
porting, expanding, documenting, standardising, testing, it is a very different matter.
You seem to have a serious aversion to all kinds of structure and modularisation.
I don't know why - perhaps it is a background in
assembly programming where everything is held at very flat levels.
Maybe you are
just used to working on your own, doing everything yourself.
Whatever it is, you prefer to have everything together in one lump. For
a little system with few users,
That is not an advantage you get from having these functions built into
the language - even in C there is no problem optimising maths functions.
* The language to know NOTHING about abs, sqrt, sin etc
Yes.
* The language needs to acquire function overloading, or some generic
features, to make those functions work on different types
No - the language should not need to "acquire" anything. Unless you are talking about a small scripting language or other niche language, if it
can't handle generic or templated code, there's no point in creating it
in the first place. (Well, fun or learning is always a good reason, but
then none of this matters.)
* The language possibly needs an inline assembler so that those
functions can be implemented efficiently where there are special
instructions available
Yes, that is reasonable if the language is to be low-level and efficient.
* The language needs advanced optimisation methods, link-time optimising
etc so that the code for some of these function can be inlined
I thought we were talking about languages that could have efficient code generation anyway. Was that wrong?
A BASIC-like language is not too hard to implement (though certainly not trivial, especially if you insist on implementing it without using
higher level languages or ready-made tools) - but what is the point,
except for fun and learning?
Being able to find square roots is irrelevant for most programs,
and no
one will miss an "abs" function - it is the features of the language
that are important.
On 09/11/2021 20:14, Bart wrote:
On 08/11/2021 22:43, David Brown wrote:
On 08/11/2021 22:56, Bart wrote:
tgmath.h is anyway not universal. tcc doesn't have it. MSVC warns its
version is not compatible with C99 (possibly due to not have _Generic). >>>> (You have to use ctgmath.h, for C++.)
I have little interest in half-baked sort-of-C compilers. MSVC has
traditionally had terrible C support
So, MSVC doesn't count.
Should we blame the language C because MS knowingly and intentionally
makes a bad implementation of it?
- perhaps because they want users
to think C is bad and choose lock-in C# instead. I have heard that the >>> more recent versions of MSVC are better, but have not tried them myself. >>>
tcc is a toy
So, tcc doesn't count.
Correct.
(And it's definitely not a toy - try writing something half as good. It
turns working C code into executable binary code that runs at half the
speed of -O3.
But it checks fewer things, and has the odd thing missing - like
tgmath.h. For building debugged code and doing it quickly, it is does
that job well.)
It's a toy.
Toys can be fun, but no one - not even tcc's developers - would think of
it as a major compiler or a reference for a complete implementation of
modern C.
Oh, and tcc is a compiler - not a library. Of course it doesn't have <tgmath.h> or any other library files.
No, I blame /you/ and your amazing talent for failing to set up working
C toolchains on Windows. I just spent 30 seconds installing clang for windows, and it had no problem with a file containing nothing but
#include <tgmath.h>. (As expected.)
On 2021-11-09 22:45, Bart wrote:
On 09/11/2021 20:59, Dmitry A. Kazakov wrote:
On 2021-11-09 19:33, Bart wrote:
DB hasn't answered yet, perhaps you can: what exactly is the problem
with having SQRT, say, as a built-in function or operator in a
language?
Occam's Razor and you cannot really have it.
You can have an operator with the name sqrt, but you cannot have sqrt
itself. Would you implement matrix sqrt for all possible combinations
of matrix index and matrix elements? Complex sqrt with two branches?
There are thousands of different sqrt's, there are specialized low
accuracy variants for graphic rendering, the number of variants is
basically infinite
You can make the same remarks about multiply:
Yes, but multiplication is much easier to implement and you cannot do
much without it. It is a fundamental operation.
P.S. I remember that some early IBM machines did not have multiplication
and division.
On 10/11/2021 14:02, Bart wrote:
They just give low-priority to C, and decided to go with their own idea
of it. Good for them.
No, not good for them (though presumably they /thought/ it would be good
for them) - and certainly not good for anyone else.
There are good
reasons why people like standards, and one of the worst things about MS
is how rarely they follow them (even for the standards they make).
With functions like SQRT and SIN, if you only have one float type, then probably there's little difference if they are operators in the
language, or user-code functions, provided they are always there ready-to-use.
Ones like SQR (square) and ABS will generally work on both ints and
floats, so they will need the auto-overloading that language-supported operators provide.
On 10/11/2021 12:03, David Brown wrote:
On 09/11/2021 20:14, Bart wrote:
On 08/11/2021 22:43, David Brown wrote:
On 08/11/2021 22:56, Bart wrote:
tgmath.h is anyway not universal. tcc doesn't have it. MSVC warns its >>>>> version is not compatible with C99 (possibly due to not have
_Generic).
(You have to use ctgmath.h, for C++.)
I have little interest in half-baked sort-of-C compilers. MSVC has
traditionally had terrible C support
So, MSVC doesn't count.
Should we blame the language C because MS knowingly and intentionally
makes a bad implementation of it?
At least in this case you can't claim that MSVC is a one-person toy
product that no one else uses.
They just give low-priority to C, and decided to go with their own idea
of it. Good for them.
- perhaps because they want users
to think C is bad and choose lock-in C# instead. I have heard that the >>>> more recent versions of MSVC are better, but have not tried them
myself.
tcc is a toy
So, tcc doesn't count.
Correct.
(And it's definitely not a toy - try writing something half as good. It
turns working C code into executable binary code that runs at half the
speed of -O3.
But it checks fewer things, and has the odd thing missing - like
tgmath.h. For building debugged code and doing it quickly, it is does
that job well.)
It's a toy.
In the same way that a bike is a toy compared with a car then.
Toys can be fun, but no one - not even tcc's developers - would think of
it as a major compiler or a reference for a complete implementation of
modern C.
You are just being snobbish. Here are two versions of one of my programs:
C:\oldqx>dir *.exe
18/10/2021 00:12 885,248 one.exe
18/10/2021 00:06 857,600 two.exe
One is compiled with gcc, one with tcc. Both work fine and give the same results:
C:\oldqx>one fib
fib(36) = 14930352
C:\oldqx>two fib
fib(36) = 14930352
Can you tell which is which? Does it matter?
Perhaps if I tell you that one.exe took 15.5 seconds to build
[optimised, which would be the main point in using it], and two.exe took
0.1 seconds, it might give you a clue.
I want that toy!
Oh, and tcc is a compiler - not a library. Of course it doesn't have
<tgmath.h> or any other library files.
I don't care. I just want to call abs(). What the hell do I need to know about tgmath for anyway?
No, I blame /you/ and your amazing talent for failing to set up working
C toolchains on Windows. I just spent 30 seconds installing clang for
windows, and it had no problem with a file containing nothing but
#include <tgmath.h>. (As expected.)
Which means of course that it works for everyone, since there is only
one version. My version cames as part of a LLVM download, and uses a combination of LLVM headers, and headers which are part of MSVC/MSBUILD.
This is something I stated, since rextester.com's clang works.
Whatever, the fact is that all this ******* about with how 'abs' or
'pow' is implemented in C, means that it might not work on your
installation.
On 10/11/2021 14:02, Bart wrote:
I don't care. I just want to call abs(). What the hell do I need to know
about tgmath for anyway?
I know you don't care - you are proud of your ignorance in how the C
language and how C implementations work.
It means it works for people other than you.
No, it might not work on /your/ installation. Other people manage fine.
You seem to forget that - getting working C implementations is not
rocket science. Breaking them as successfully and repeatedly as you do, /that/ takes some skill.
On 10/11/2021 16:31, David Brown wrote:
On 10/11/2021 14:02, Bart wrote:
It means it works for people other than you.
No, it might not work on /your/ installation. Other people manage fine.
You seem to forget that - getting working C implementations is not
rocket science. Breaking them as successfully and repeatedly as you do,
/that/ takes some skill.
OK, YOU tell ME exactly how I managed to get the list of errors below,
since you're so much more skilled than I am:
The input is a file C:\c\c.c that contains:
#include <tgmath.h>
Installed is a 1.7GB installation of LLVM that includes clang.exe. And a 2.8GB, 14,000-file installion of MSBuild tools or what is necessary to
run MSVC.
My contention is that it is how this language implements fundemental
features that makes it particularly prone to things going wrong like this.
Yours I already know:
* Bart doesn't know what the hello he's doing
* Microsoft don't know what the hell they're doing
* Windows is rubbish anyway
-------------------------------------------
In file included from c.c:1:
C:\LLVM\lib\clang\11.0.0\include\tgmath.h:72:50: error: passing
'_Complex float' to parameter of incompatible type '_Fcomplex' (aka
'struct _C_float_complex')
__tg_acos(float _Complex __x) {return cacosf(__x);} ^~~
On 10/11/2021 19:14, Bart wrote:
In file included from c.c:1:
C:\LLVM\lib\clang\11.0.0\include\tgmath.h:72:50: error: passing
'_Complex float' to parameter of incompatible type '_Fcomplex' (aka
'struct _C_float_complex')
__tg_acos(float _Complex __x) {return cacosf(__x);}
^~~
I can only guess at what you have been doing to get your system so mixed
up. But one guess would be that you are mixing C and C++ in some way ("struct _C_float_complex" looks a bit like a C++ complex number type,
since these are handled by classes in C++ rather than a fundamental type
like in C).
The other guess is that you are using <tgmath.h> designed for one
compiler with a different compiler, since <tgmath.h> is usually
implemented in a compiler-specific manner. For example, maybe you are
using MSVC libraries with clang, but these are not expected to work
unless you run clang via an MSVC front-end.
Personally, on my Windows system I did this :
pacman -Ss clang
30 seconds or so later, after installation of clang...
clang -c c.c
On 10/11/2021 18:56, David Brown wrote:
On 10/11/2021 19:14, Bart wrote:
[Compiling tgmath.h]
In file included from c.c:1:
C:\LLVM\lib\clang\11.0.0\include\tgmath.h:72:50: error: passing
'_Complex float' to parameter of incompatible type '_Fcomplex' (aka
'struct _C_float_complex')
__tg_acos(float _Complex __x) {return cacosf(__x);}
^~~
I can only guess at what you have been doing to get your system so mixed
up. But one guess would be that you are mixing C and C++ in some way
("struct _C_float_complex" looks a bit like a C++ complex number type,
since these are handled by classes in C++ rather than a fundamental type
like in C).
The other guess is that you are using <tgmath.h> designed for one
compiler with a different compiler, since <tgmath.h> is usually
implemented in a compiler-specific manner. For example, maybe you are
using MSVC libraries with clang, but these are not expected to work
unless you run clang via an MSVC front-end.
Personally, on my Windows system I did this :
pacman -Ss clang
30 seconds or so later, after installation of clang...
clang -c c.c
My Clang is:
clang version 11.0.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\LLVM\bin
The only working version I can try is from rextester.com, which says:
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
(What does your say?)
Clang is rather peculiar: it is a parasitical compiler that piggy-backs
onto other compilers. The first version I used on Windows, required gcc installed, and utilised its headers, linker etc. (I didn't find out for
two years; I thought I had two separate compilers!)
Then it changed its allegiance to MSVC, when it stopped working
completely for several years since it could never properly sync to my
MSVC installation.
Eventually I must have done something right, or the LLVM clang is
different, as a year ago it managed to work - a miracle!
(But I'm still surprised that a 1700MB compiler installation doesn't
come with its own headers and stuff.)
My clang is on my old Windows 7 PC. I have a new PC now with Windows 10,
but I haven't bothered with MSVC or clang.
Maybe if I used your pacman it would work like yours.
But, W10 says 'pacman' is not recognised. On WSL, it says it's not
installed but can be with 'apt install'. If this is how you got clang,
then you're not running clang under actual Windows, so your comparison
would be invalid.
My Clang is:
clang version 11.0.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\LLVM\bin
clang version 11.0.0
Target: x86_64-pc-windows-msys
Thread model: posix
InstalledDir: /usr/bin
So, the same compiler but targeting msys run-time rather than msvc's C runtime.
The only working version I can try is from rextester.com, which says:
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Why do you insist on using rextester.com
(What does your say?)
Clang is rather peculiar: it is a parasitical compiler that piggy-backs
onto other compilers. The first version I used on Windows, required gcc
installed, and utilised its headers, linker etc. (I didn't find out for
two years; I thought I had two separate compilers!)
No, it is not "peculiar" - it is a C and C++ compiler.
This has been explained to you countless times. But you are so utterly convinced that /your/ choice of structuring - compiler and library
rolled into one - is the only "correct" way that you can't seem to
understand this.
and guides, and get the
setup wrong again and again. (In reality, there are pros and cons of
making complete packages with everything in the toolchain from one
place. Different arrangements are useful for different purposes.)
Then it changed its allegiance to MSVC, when it stopped working
completely for several years since it could never properly sync to my
MSVC installation.
clang did not "change allegiance". MSVC choose to start supporting
clang as an alternative to their own C compiler.
I've recommended using msys2 / mingw-64 to you before.
On 11/11/2021 10:53, David Brown wrote:
This has been explained to you countless times. But you are so utterly
convinced that /your/ choice of structuring - compiler and library
rolled into one - is the only "correct" way that you can't seem to
understand this.
It is the typical way that any compiler comes on Windows. Even gcc is
usually obtained as self-contained bundle (what good is it otherwise?).
On 11/11/2021 10:53, David Brown wrote:
My Clang is:
clang version 11.0.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\LLVM\bin
clang version 11.0.0
Target: x86_64-pc-windows-msys
Thread model: posix
InstalledDir: /usr/bin
Thanks.
So, the same compiler but targeting msys run-time rather than msvc's C
runtime.
Try deleting msys' gcc installation, and see if it still works. If it
does try deleting msys' standard C headers, if they come with that product.
The only working version I can try is from rextester.com, which says:
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Why do you insist on using rextester.com
Because that is a known working product isolated from my machine.
(What does your say?)
Clang is rather peculiar: it is a parasitical compiler that piggy-backs
onto other compilers. The first version I used on Windows, required gcc
installed, and utilised its headers, linker etc. (I didn't find out for
two years; I thought I had two separate compilers!)
No, it is not "peculiar" - it is a C and C++ compiler.
It IS peculiar, at least on Windows, where the OS doesn't natively
provide C headers, assemblers, link tools etc. Because it uses those of another installed C compiler (was gcc/mingw, now MSVC).
I haven't seen that on any other C compiler for Windows, which are all self-contained.
I call that peculiar. You of are course have to be contrary.
(I have seen that behaviour in languages like Rust, but that is also associated with LLVM.)
This has been explained to you countless times. But you are so utterly
convinced that /your/ choice of structuring - compiler and library
rolled into one - is the only "correct" way that you can't seem to
understand this.
It is the typical way that any compiler comes on Windows. Even gcc is
usually obtained as self-contained bundle (what good is it otherwise?).
Imagine if clang was still dependent on a gcc/mingw installation. And gcc/mingw decided to do the same thing - not bother with as, ld, headers
etc; let's piggyback on clang's!
You don't see a problem there?
and guides, and get the
setup wrong again and again. (In reality, there are pros and cons of
making complete packages with everything in the toolchain from one
place. Different arrangements are useful for different purposes.)
Then it changed its allegiance to MSVC, when it stopped working
completely for several years since it could never properly sync to my
MSVC installation.
clang did not "change allegiance". MSVC choose to start supporting
clang as an alternative to their own C compiler.
CL.EXE is still a thing ATM. It is not clang.exe which is a gcc clone.
But something clearly changed inside clang, for it to switch from a gcc installation to msvc. This is also a detail they didn't disclose to anyone.
I've recommended using msys2 / mingw-64 to you before.
Someone says 'X doesn't work on Windows'.
You say, 'Nope, X works fine on Windows. You must be a fool'.
Then it turns on you haven't run X on Windows at all, it is one of
Cygwin or MSYS2 or WSL, which all drag diferent elements of Unix.
That seems to be point that YOU repeatedly fail to understand.
The ludicrousness of effectively having to switch OSes just to enable a working abs() or pow() function in a language seems to have escaped you
too.
Here is an extract from a stackoverflow question:
"I'd like to use clang without GCC on Linux and without MSVC on Windows..."
On 11/11/2021 12:41, Bart wrote:
Let me try to explain what I mean by that. A "package manager" is not
just format for zipping up files for a program. It handles downloading packages from one or more repositories, tracking a database of installed packages, ensuring dependencies are in place before installing packages, updates, upgrades, start/stop scripts, installation scripts for setup
and configuration, and many other things.
A quick check shows that on both my Linux mint system, and the
pacman-handled
Why do you insist on using rextester.com
Because that is a known working product isolated from my machine.
I know why you use such an online compiler site (or at least, I know
some of the reasons - there can be many). My question is why you use rextester.com, when AFAICS godbolt.org is very much better.
In the C world, it is /Windows/ that is peculiar because it does not
have a system compiler, system libraries, system headers.
This does not make clang "peculiar", unless you insist on pretending it
is something that it is not.
I call that peculiar. You of are course have to be contrary.
Understanding what a "compiler" is does not make me contrary.
I quickly and easily installed clang and all necessary dependencies. It
also does not take long to google for "how do I install clang on
Windows?".
When you said you used 'pacman' to install and run X on 'Windows', you
should have made it clear that this wasn't a native Windows program.
And C is peculiar from other languages in having this strange
eco-system, and being so intimately tied up with Unix. (A language
that's supposed to be so portable!)
You don't like those because they don't conform; they dare to do
something different to how it works on Unix; and you find them unusable
to the extend that you have to work within a Unix bubble, even under
Windows.
This group is not about just C or Unix, and should not just be about industrial-scaled languages, implementations and toolchains.
I quickly and easily installed clang and all necessary dependencies. It
also does not take long to google for "how do I install clang on
Windows?".
You mean true Windows, or Cygwin or MSYS or WSL?
Notice that Unix has now also managed to corrupt Windows so that it is
no longer one product.
On 2021-11-11 19:26, Bart wrote:
When you said you used 'pacman' to install and run X on 'Windows', you
should have made it clear that this wasn't a native Windows program.
MSYS pacman is a native Windows program that depends on kernel32.dll, ntdll.dll, advapi32.dll etc, all Windows' stuff. Go and check
C:\msys64\usr\bin\pacman.exe
yourself.
And C is peculiar from other languages in having this strange
eco-system, and being so intimately tied up with Unix. (A language
that's supposed to be so portable!)
C is tied to the host operating system. So is Ada or any language that supports systems programming.
You don't like those because they don't conform; they dare to do
something different to how it works on Unix; and you find them
unusable to the extend that you have to work within a Unix bubble,
even under Windows.
Are you aware that a huge number of C applications target embedded
systems with no or very rudimentary OS?
You mean true Windows, or Cygwin or MSYS or WSL?
Cygwin and MSYS are Windows-native. You are thoroughly confused.
Notice that Unix has now also managed to corrupt Windows so that it is
no longer one product.
As if Windows ever was. One of real Windows' strengths is layered architecture that supports various hardware and software environments, coexisting and interacting.
On 11/11/2021 19:38, Dmitry A. Kazakov wrote:
On 2021-11-11 19:26, Bart wrote:
When you said you used 'pacman' to install and run X on 'Windows',
you should have made it clear that this wasn't a native Windows program.
MSYS pacman is a native Windows program that depends on kernel32.dll,
ntdll.dll, advapi32.dll etc, all Windows' stuff. Go and check
C:\msys64\usr\bin\pacman.exe
yourself.
One of the first hits on 'what is pacman package manager' said:
"pacman is a utility which manages software packages in Linux."
That it necessarily has to be built as an executable to run on Windows
is no surprise; MSYS is not WSL.
Is it possible to run Clang-msys outside of MSYS? Can I build an
executable with Clang-msys, and send it to someone with a Windows
machine but no MSYS?
And C is peculiar from other languages in having this strange
eco-system, and being so intimately tied up with Unix. (A language
that's supposed to be so portable!)
C is tied to the host operating system. So is Ada or any language that
supports systems programming.
My systems language also started on a machine with no OS.
You don't like those because they don't conform; they dare to do
something different to how it works on Unix; and you find them
unusable to the extend that you have to work within a Unix bubble,
even under Windows.
Are you aware that a huge number of C applications target embedded
systems with no or very rudimentary OS?
Yes there are lots of hacked versions about for specialist devices.
(BTW, how many of those actually /run/ the compiler on the target device?)
But there are a million ways that the C language /is/ closely tied to
Unix and Unix-like OSes.
Look at how much trouble Linux-originated C compilers have in adapting
to Windows, and cutting all those ties to the Linux eco-system.
By contrast, I can go the other way with little trouble.
You mean true Windows, or Cygwin or MSYS or WSL?
Cygwin and MSYS are Windows-native. You are thoroughly confused.
Tell me why Cygwin and MSYS are even necessary.
However it works, it works. In the past I've sent endless binaries to
people with Windows machines, and they Just Work, with these provisos:
Built Runs on Runs on
as Win32 Win64
Win16 Y N
Win32 Y Y
Win64 N Y
Contrast the millions of versions of Linux and Unix.
On 2021-11-11 21:45, Bart wrote:
Look at how much trouble Linux-originated C compilers have in adapting
to Windows, and cutting all those ties to the Linux eco-system.
This has nothing to with compilers. It is about the tools all unrelated
to C, people, of admittedly poor taste, wanted to keep on using under Windows. I cannot blame them. sh is garbage, but comparing to Windows
cmd it is a candidate for Nobel price.
By contrast, I can go the other way with little trouble.
No, you cannot, as you have nothing comparable to these tools.
On 11/11/2021 21:26, Dmitry A. Kazakov wrote:
On 2021-11-11 21:45, Bart wrote:
Look at how much trouble Linux-originated C compilers have in
adapting to Windows, and cutting all those ties to the Linux eco-system.
This has nothing to with compilers. It is about the tools all
unrelated to C, people, of admittedly poor taste, wanted to keep on
using under Windows. I cannot blame them. sh is garbage, but comparing
to Windows cmd it is a candidate for Nobel price.
By contrast, I can go the other way with little trouble.
No, you cannot, as you have nothing comparable to these tools.
We're talking about a compiler: a program that translates input files to output files.
Is it possible to run Clang-msys outside of MSYS? Can I build an
executable with Clang-msys, and send it to someone with a Windows
machine but no MSYS?
I do not use clang. But you can use MSYS GCC GNAT for building an
application in Ada and use that application on any Windows machine,
provided you supply the run-time libraries like libgcc_s_seh-1.dll etc.
Before you
This has nothing to with compilers. It is about the tools all unrelated
to C, people, of admittedly poor taste, wanted to keep on using under Windows. I cannot blame them. sh is garbage, but comparing to Windows
cmd it is a candidate for Nobel price.
On 11/11/2021 21:26, Dmitry A. Kazakov wrote:
Is it possible to run Clang-msys outside of MSYS? Can I build an
executable with Clang-msys, and send it to someone with a Windows
machine but no MSYS?
I do not use clang. But you can use MSYS GCC GNAT for building an
application in Ada and use that application on any Windows machine,
provided you supply the run-time libraries like libgcc_s_seh-1.dll etc.
Interesting. So GNAT could be used to compile itself, or Clang can build itself, and have that new compiler be usable outside of MSYS.
But since you mention 'sh' or whatever the program is in the Linux that serves the same purpose as Windows' cmd, isn't that case-sensitive?
That is, the commands must have exactly the right case, otherwise it has
no idea what you mean. And filenames must be exactly right too, as there
can be 64 variations of hello.c in the same folder.
That is also the home of gcc with its idiotic habit of compiling any
program into a.out (so wiping out the last a.out you spent so long compiling!). Other compilers such as clang and tcc are then obliged to
follow suit, so that decades later it still works the same stupid way.
On 2021-11-12 14:55, Bart wrote:
On 11/11/2021 21:26, Dmitry A. Kazakov wrote:
Is it possible to run Clang-msys outside of MSYS? Can I build an
executable with Clang-msys, and send it to someone with a Windows
machine but no MSYS?
I do not use clang. But you can use MSYS GCC GNAT for building an
application in Ada and use that application on any Windows machine,
provided you supply the run-time libraries like libgcc_s_seh-1.dll etc.
Interesting. So GNAT could be used to compile itself, or Clang can
build itself, and have that new compiler be usable outside of MSYS.
Again, you are confused. MSYS' GCC *is* a Windows application, look for gcc.exe.
But since you mention 'sh' or whatever the program is in the Linux
that serves the same purpose as Windows' cmd, isn't that case-sensitive?
It is a meaningless question.
That is also the home of gcc with its idiotic habit of compiling any
program into a.out (so wiping out the last a.out you spent so long
compiling!). Other compilers such as clang and tcc are then obliged to
follow suit, so that decades later it still works the same stupid way.
Wrong. The *compiler* compiles into an object file *.o.
You are confusing compiler with linker and other pre-linking stages. You
are free to use whatever linker you want.
On 12/11/2021 14:30, Dmitry A. Kazakov wrote:
On 2021-11-12 14:55, Bart wrote:
On 11/11/2021 21:26, Dmitry A. Kazakov wrote:
Interesting. So GNAT could be used to compile itself, or Clang canIs it possible to run Clang-msys outside of MSYS? Can I build an
executable with Clang-msys, and send it to someone with a Windows
machine but no MSYS?
I do not use clang. But you can use MSYS GCC GNAT for building an
application in Ada and use that application on any Windows machine,
provided you supply the run-time libraries like libgcc_s_seh-1.dll etc. >>>
build itself, and have that new compiler be usable outside of MSYS.
Again, you are confused. MSYS' GCC *is* a Windows application, look
for gcc.exe.
You're confused I think:
* Some programs, eg P, a compiler, need to run with MSYS installed
* That program P can build another program Q, that can run without MSYS installed (according to you)
* Then, can program P build a new version of P, as P', that can also run without MSYS installed?
* If so, my question was, why don't they just make P' available instead
of P?
But since you mention 'sh' or whatever the program is in the Linux
that serves the same purpose as Windows' cmd, isn't that case-sensitive?
It is a meaningless question.
So, whether Linux' terminal, sh, bash, whatever you want to call it, is case-sensitive, is meaningless?
I don't think so! But I already know the answer; pretty much everthing
is, and thus user-unfriendly. Fortunately the people behind Google
search were more sensible.
That is also the home of gcc with its idiotic habit of compiling any
program into a.out (so wiping out the last a.out you spent so long
compiling!). Other compilers such as clang and tcc are then obliged
to follow suit, so that decades later it still works the same stupid
way.
Wrong. The *compiler* compiles into an object file *.o.
You are confusing compiler with linker and other pre-linking stages.
You are free to use whatever linker you want.
And you are being pedantic. 'gcc' is a compiler driver, a program that
turns .c files into executables.
The name of that executable will be a.out on Linux unless you specify otherwise.
On 2021-11-12 17:08, Bart wrote:
You're confused I think:
* Some programs, eg P, a compiler, need to run with MSYS installed
GCC does not require MSYS installed. If you knew Windows, you would also
know that installation is basically non-existent under Windows. You can
place an executable anywhere. Except very rare cases when an application requires some system service running, which is not the case for GCC.
In short, you can copy the MSYS folder, uninstall it and then use the copy.
* That program P can build another program Q, that can run without
MSYS installed (according to you)
GCC builds native Windows applications that run without MSYS.
* Then, can program P build a new version of P, as P', that can also
run without MSYS installed?
You can bootstrap GCC.
* If so, my question was, why don't they just make P' available
instead of P?
Because it is already there. Again, GCC does not need MSYS. Specifically
you can call it from cmd as any normal application.
Less lucky people will use make, cmake whatever.
Nobody sane would use naked compiler/binder/linker for anything bigger
than hello-world.
The name of that executable will be a.out on Linux unless you specify otherwise.
This doesn't help the exasperated user who for the millionth time has
to type "-oprog" for no good reason.
I specifically make tools to be as easy to use as compiling hello-world.
Can gprbuild just be given a .c file? If not that then's an extra obstacle.
On 11/11/2021 15:44, David Brown wrote:
On 11/11/2021 12:41, Bart wrote:
Let me try to explain what I mean by that. A "package manager" is not
just format for zipping up files for a program. It handles downloading
packages from one or more repositories, tracking a database of installed
packages, ensuring dependencies are in place before installing packages,
updates, upgrades, start/stop scripts, installation scripts for setup
and configuration, and many other things.
Let me explain how I do things: when I supply a product as simple as a language compiler (translate some input files into one output file), I provide just one EXE file.
That is it.
You just have to copy it anywhere, and run it. No dependences, no
install, no compiling, no configuration, no package managers; it just
works.
A quick check shows that on both my Linux mint system, and the
pacman-handled
When you said you used 'pacman' to install and run X on 'Windows', you
should have made it clear that this wasn't a native Windows program.
Why do you insist on using rextester.com
Because that is a known working product isolated from my machine.
I know why you use such an online compiler site (or at least, I know
some of the reasons - there can be many). My question is why you use
rextester.com, when AFAICS godbolt.org is very much better.
I didn't know until recently recently that godbolt could run code. But
its main purpose seems to be to display the generated code, and to
suppport a million different compilers.
rextester is much simpler to use and it only compiles and runs.
In the C world, it is /Windows/ that is peculiar because it does not
have a system compiler, system libraries, system headers.
Windows is a consumer product made to run ready-made applications.
But, presumably you're talking about a C compiler and C headers; why C?
This does not make clang "peculiar", unless you insist on pretending it
is something that it is not.
It is peculiar in being different from other compilers.
And C is peculiar from other languages in having this strange
eco-system, and being so intimately tied up with Unix. (A language
that's supposed to be so portable!)
Yet, others have developed C implementations to exist outside of Unix.
You don't like those because they don't conform; they dare to do
something different to how it works on Unix; and you find them unusable
to the extend that you have to work within a Unix bubble, even under
Windows.
That's fine - you can do what you like. But it doesn't mean that those
other ways of doing things are all Wrong, and Unix's is Right.
I call that peculiar. You of are course have to be contrary.
Understanding what a "compiler" is does not make me contrary.
I've written a dozen or two compilers including a C compiler (and
assorted assemblers and linkers and interpreters).
I might understand what is essential in a program that turns source code
into executable code.
You might understand how your Unix-centric, C-centric compilers written
by large teams are organised.
This group is not about just C or Unix, and should not just be about industrial-scaled languages, implementations and toolchains.
I quickly and easily installed clang and all necessary dependencies. It
also does not take long to google for "how do I install clang on
Windows?".
You mean true Windows, or Cygwin or MSYS or WSL?
Notice that Unix has now also managed to corrupt Windows so that it is
no longer one product.
Fortunately by the time Unix has completely taken over the world, I'll
be dead.
On 2021-11-12 18:49, Bart wrote:
I specifically make tools to be as easy to use as compiling hello-world.
Good for you, but I am perfectly capable to typing "Hello World" without
any compiler.
Specifically for "Hello World" I suggest Notepad++. You can create a new
tab in it. Then type there "Hello World" just *once*, and enjoy the
sight without even saving it into the file. Notepad++ will keep that for
you forever, between sessions! Can your compiler that? (:-))
You are free to illustrate easiness of using your tools on an example of
a GTK application targeted for Windows and Linux. Show one
release/deployment cycle.
Can gprbuild just be given a .c file? If not that then's an extra
obstacle.
No, its purpose software developing. People understood long ago, that
naked compiler/linker is unsuitable for anything serious.
On 12/11/2021 16:08, Bart wrote:
The name of that executable will be a.out on Linux unless you specify
otherwise.
If you compile together "fred.c", "jim.c", "bart.c", "andy.c" "dmitri.c" and "uncletomcobleyandall.c", what /should/ a resulting
executable be called if not "a.out"?
This doesn't help the exasperated user who for the millionth time has
to type "-oprog" for no good reason.
Personally, I usually type "make" for anything but the most
trivial of projects.
If you are easily exasperated, programming is really not a suitable
career.
On 11/11/2021 19:26, Bart wrote:
You are simply making up feeble excuses because you won't accept that
other people can run these compilers on Windows while you fail to do so.
(Again, I'm not suggesting that installing clang on Windows is as easy
as it could be - merely that it works perfectly well once you learn the
two steps "install msys2", "use msys2 to install clang".)
You have a bee in your bonnet about any tool that started off on a *nix system.
I've written a dozen or two compilers including a C compiler (and
assorted assemblers and linkers and interpreters).
You demonstrate again and again that you have little understanding of
what a C compiler is, what the phrase "C implementation" means,
Windows. If you can't use Windows, and won't use Linux, maybe you
should try a Mac.
On 12/11/2021 18:16, David Brown wrote:
On 11/11/2021 19:26, Bart wrote:
You are simply making up feeble excuses because you won't accept that
other people can run these compilers on Windows while you fail to do so.
I claimed that a version of Clang couldn't compile tgmath.h on Windows.
You claimed that it did, and that I was a fool.
Then it turned out you were running a different version of Clang. And
one running inside a special environment within Windows, called MSYS.
Anyone (not just me) downloading clang from the LLVM site, would likely
see the same issue I did.
(Again, I'm not suggesting that installing clang on Windows is as easy
as it could be - merely that it works perfectly well once you learn the
two steps "install msys2", "use msys2 to install clang".)
Why does it need msys2?
If I sent you a Win64 executable, there would no provisos.
From Wikipedia:
"MSYS2 ("minimal system 2") is a software distribution and a development platform for Microsoft Windows, based on Mingw-w64 and Cygwin, that
helps to deploy code from the Unix world on Windows."
I noticed the word Unix in there; what's that got to do with the price
of fish? We were trying to get C to run an overloaded version of pow()!
You have a bee in your bonnet about any tool that started off on a *nix
system.
Because it usually causes me a lot of grief, and extra hassle.
I've developed my tools to be largely independent of OS, even Windows.
People who work on Unix tend to do the opposite: develop their tools to
be highly dependent on Unix. That's why you have all those add-ons for Windows to try and emulate that environment.
I'm surprised you don't get that.
But look at compiling these programs:
gcc fred.c jim.c
gcc bart.c
gcc andy.c other.c
The end result is a single file a.out; how stupid is that?
Supposed
bart.c was 1000000 lines
and takes ages to compile, then it just
overwrites it while building an unrelated program?
Personally, I usually type "make" for anything but the mostYes, what about the millions of times you're building a one-file
trivial of projects.
throwaway program? Then surely that can be no confusion about what
the executable might be called.
After installing, then:
make hello
didn't work. And with:
make hello.c
it said "No rule to make target 'hello.c'"
On 12/11/2021 18:04, Dmitry A. Kazakov wrote:
On 2021-11-12 18:49, Bart wrote:
I specifically make tools to be as easy to use as compiling hello-world.
Good for you, but I am perfectly capable to typing "Hello World"
without any compiler.
You are misunderstanding again. Presumably, deliberately. Suppose you
could do this:
gcc hello.c -ohello.exe
and then you could do this:
gcc python.c -opython.exe
Then you can just run Python, yes?
Specifically for "Hello World" I suggest Notepad++. You can create a
new tab in it. Then type there "Hello World" just *once*, and enjoy
the sight without even saving it into the file. Notepad++ will keep
that for you forever, between sessions! Can your compiler that? (:-))
You are free to illustrate easiness of using your tools on an example
of a GTK application targeted for Windows and Linux. Show one
release/deployment cycle.
GTK is a nightmare with any language: 700 headers, 350,000s line of declarations, 55 DLL libraries.
I got as far as reducing that lot to
25,000 lines of declarations in my language, with 4000 lines of C macros
yet to be translated manually.
Now let me guess, you've used GTK, but you didn't have to translate
10,000 functions into bindings for your own language? Lucky you!
Can gprbuild just be given a .c file? If not that then's an extra
obstacle.
No, its purpose software developing. People understood long ago, that
naked compiler/linker is unsuitable for anything serious.
They were wrong.
Or they are the sort of people who devise all these
bloated applications that are complicated enough that you need
additional build tools to handle.
I've never used anything beyond a bare compiler, and a crude IDE
On 12/11/2021 18:19, Bart wrote:
But look at compiling these programs:
gcc fred.c jim.c
gcc bart.c
gcc andy.c other.c
The end result is a single file a.out; how stupid is that?
Set up and use a makefile, and it will all work. The real stupidity is having three unrelated projects in one directory.
Supposed
bart.c was 1000000 lines
There's another stupidity. Who in his right mind writes
and compiles a single module of 1000000 lines?
Make a typo/thinko
anywhere in that unreadable mass of code and you have to edit a
1000000-line file and recompile.
Split it up into logical bits
and use a makefile. [Personally, I think no program /should/ be
that big. That's why we get bug-ridden utilities and failed
projects in our health/defence/... services.] [Of course, people
like certain contributors to this group -- no names, no pack
drill -- like to construct million-line files consisting of
1000000 copies of "a = b + c" so that they can point out that
their compilers can compile and run that in 0.123 microseconds.
We can safely discount that as not a serious project.]
and takes ages to compile, then it just
overwrites it while building an unrelated program?
Bad project management.
Personally, I usually type "make" for anything but the mostYes, what about the millions of times you're building a one-file
trivial of projects.
throwaway program? Then surely that can be no confusion about what
the executable might be called.
My one-file throwaway programs are compile-and-go, so I
don't care what the executable [if there is one] is called, it
will get deleted after running [if not by me, or by "a68g", then
by my nightly clean-up daemons].
After installing, then:
make hello
didn't work. And with:
make hello.c
it said "No rule to make target 'hello.c'"
You are so resistant to reading instruction manuals that
I do have a word of advice: please, never try to use a chainsaw.
[As you perhaps have realised before or since, you don't need to
/make/ "hello.c" -- it's an /input/ file. Unless, of course, you
intend to construct "hello.c" by some process or other, in which
case you need to tell "make" what that process is.]
But you're avoiding the question. It seems to be like you're just
making excuses for a program that you're so used to, you accept it
without question.
If gcc had worked differently, taking the default output file name
from the first input file (as does my bcc, lccwin, DMC, PellesC,
MSVC, even tcc when on Windows), would it have caused you any grief?
Would you have had to waste time typing -oa.out to get your prefered
output? I guess not.
I think you're just cross that A68G didn't make it to the first, easy
hurdle of compiling 20,000 lines; [...].
Oh, right. I thought you were suggesting 'make' as an alternate wayAfter installing, then:You are so resistant to reading instruction manuals that
make hello
didn't work. And with:
make hello.c
it said "No rule to make target 'hello.c'"
to compile programs.
It took me a few seconds to see if it was clever enough to see
'prog.c' and recognise that it should invoke a C compiler; why not?> But apparently it wasn't.
OK, the .c extension is clearly not enough of a clue!
On 12/11/2021 20:07, Bart wrote:
The clang build in the msys2 package repository is configured to use
msys libraries. The clang build distributed with MSVC is configured to
use MSVC libraries. That should not be a big surprise to anyone who understands what a C compiler is and how it relates to libraries.
People who work on Unix tend to do the opposite: develop their tools to
be highly dependent on Unix. That's why you have all those add-ons for
Windows to try and emulate that environment.
I'm surprised you don't get that.
I don't "get it", because it is simply bollocks. It's not even wrong,
On 2021-11-12 19:36, Bart wrote:
On 12/11/2021 18:04, Dmitry A. Kazakov wrote:
On 2021-11-12 18:49, Bart wrote:
I specifically make tools to be as easy to use as compiling
hello-world.
Good for you, but I am perfectly capable to typing "Hello World"
without any compiler.
You are misunderstanding again. Presumably, deliberately. Suppose you
could do this:
gcc hello.c -ohello.exe
and then you could do this:
gcc python.c -opython.exe
Then you can just run Python, yes?
Nope. Python comes with a huge library of loadable and precompiled
modules. Your example does not make sense.
GtkAda bindings are generated from C headers. But that is beyond the
point, which is that Notepad++ is a better tool for "Hello World" than
your compiler while both are unsuitable for real-life software developing.
On 12/11/2021 20:17, Dmitry A. Kazakov wrote:
On 2021-11-12 19:36, Bart wrote:
On 12/11/2021 18:04, Dmitry A. Kazakov wrote:
On 2021-11-12 18:49, Bart wrote:
I specifically make tools to be as easy to use as compiling
hello-world.
Good for you, but I am perfectly capable to typing "Hello World"
without any compiler.
You are misunderstanding again. Presumably, deliberately. Suppose you
could do this:
gcc hello.c -ohello.exe
and then you could do this:
gcc python.c -opython.exe
Then you can just run Python, yes?
Nope. Python comes with a huge library of loadable and precompiled
modules. Your example does not make sense.
I'm talking about the binaries that constitute that product. Bonus
content in the form of programs in the language is a separate matter.
GtkAda bindings are generated from C headers. But that is beyond the
point, which is that Notepad++ is a better tool for "Hello World" than
your compiler while both are unsuitable for real-life software
developing.
I'm not sure what point you are trying to make.
That an application, in combination with suitable tools, can be as easy
and almost as quick to build as a hello-world program, does not mean the application IS hello-world.
On 12/11/2021 20:03, David Brown wrote:
On 12/11/2021 20:07, Bart wrote:
People who work on Unix tend to do the opposite: develop their tools to
be highly dependent on Unix. That's why you have all those add-ons for
Windows to try and emulate that environment.
I'm surprised you don't get that.
I don't "get it", because it is simply bollocks. It's not even wrong,
It is exactly what I have observed.
Just look at how many open source programs require you to run
'./configure' as the first step (configure is a shell script for Linux).
Perhaps you've been immersed in Unix-like systems so long that you just
take the existence of these dependencies for granted. The only form of Windows you've used are special versions that provide the special
environment you expect.
On 2021-11-14 22:58, Bart wrote:
I'm talking about the binaries that constitute that product. Bonus
content in the form of programs in the language is a separate matter.
Stop embarrassing yourself. Install Python under Windows, go to the installation folder and see what it entails.
That an application, in combination with suitable tools, can be as
easy and almost as quick to build as a hello-world program, does not
mean the application IS hello-world.
I somehow missed your post illustrating deployment of a GTK-based
project...
Here's something a bit lighter than what we are discussing in other
threads - a nice, friendly syntax issue. :-)
I think it goes back as far as Fortran and maybe even further into early assembly languages but is it the best way?
I came up with (not implemented yet) something else. IMO it's better but
see what you think. I would express the above two numbers as
10^3 10 to the power of 3 4.5x10^-2 4.5 times 10 to the
power of -2
(Yes, that's a lower-case x,)
On Mon, 08 Nov 2021 19:46:35 +0000, James Harris wrote:
Here's something a bit lighter than what we are discussing in other
threads - a nice, friendly syntax issue. :-)
;-)
I think it goes back as far as Fortran and maybe even further into early
assembly languages but is it the best way?
No. For over half a century, Algol has used a distinct character, and it
has been in Unicode for quite some time: "⏨" (U+23E8) as in 1⏨3.
I came up with (not implemented yet) something else. IMO it's better but
see what you think. I would express the above two numbers as
10^3 10 to the power of 3 4.5x10^-2 4.5 times 10 to the
power of -2
(Yes, that's a lower-case x,)
Why a lowercase x for multiplication, Unicode has × ?
For the expression of numbers, I believe nothing beats Unicode:
N_A = 6,02214076 ·10²³ mol⁻¹. (Why Unicode Consortium wastes time adding
silly emojis instead of making sure useful symbols like subscript capital letter A are included, I don't know.)
On 15/11/2021 14:21, Lasse Hillerøe Petersen wrote:
On Mon, 08 Nov 2021 19:46:35 +0000, James Harris wrote:
Here's something a bit lighter than what we are discussing in other
threads - a nice, friendly syntax issue. :-)
;-)
I think it goes back as far as Fortran and maybe even further into
early assembly languages but is it the best way?
No. For over half a century, Algol has used a distinct character, and
it has been in Unicode for quite some time: "⏨" (U+23E8) as in 1⏨3.
A few things to say to that:
* Not all powers are of 10. For example, if the number is in hex then
the base might be 16.
* Accessing Unicode characters can be a challenge - e.g. remembering
U+23E8, for example.
* Some Unicode characters look like each other, meaning that code which
used them could have a syntax error while looking perfect to a human
reader.
Unicode is OK for typesetting, i.e. converting text which is already
correct into a form for human readership. But as above it can cause
problems when going from 'human' to text when that text has to be
processed meaningfully, as is especially true of program source.
I'd have your Avogadro's constant as
6.02214076x10^-23
which is not too bad, is it?!
On 15/11/2021 14:21, Lasse Hillerøe Petersen wrote:
For the expression of numbers, I believe nothing beats Unicode:
N_A = 6,02214076 ·10²³ mol⁻¹. (Why Unicode Consortium wastes time adding
silly emojis instead of making sure useful symbols like subscript capital
letter A are included, I don't know.)
Unicode is OK for typesetting, i.e. converting text which is already
correct into a form for human readership. But as above it can cause
problems when going from 'human' to text when that text has to be
processed meaningfully, as is especially true of program source.
I'd have your Avogadro's constant as
6.02214076x10^-23
which is not too bad, is it?!
On 15/11/2021 08:02, Dmitry A. Kazakov wrote:
I somehow missed your post illustrating deployment of a GTK-based
project...
I don't have many apps but here is a toy program that loads and displays images, and allows some basic editing; I'm not sure what you mean by release/deployment, but I run it in production as follows:
C:\demo>bmed # (script that invokes the following)
C:\demo>c:\qx\qq c:\m\bmedit.qa
(I then get a simple GUI window with a CLI. After typing 'load card2',
it displays:
https://github.com/sal55/langs/blob/master/demo.png
)
what exactly is the problem
with having SQRT, say, as a built-in function or operator in a language?
Someone give me a convincing answer, and I will change my
implementation, provided it doesn't involve reimplementing the whole of
C++, and making my build-times 100 times slower.
On 09/11/2021 18:33, Bart wrote:
...
what exactly is the problem with having SQRT, say, as a built-in
function or operator in a language?
As in the "Common operators" thread, SQRT is or can defined as part of
the type of its operand. For example,
int a
float b
complex c
sqrt(a) <== invalid, no such function for type int
sqrt(b) <== invokes the float sqrt
sqrt(c) <== invokes the complex sqrt
where
type float
function sqrt
....
type complex
function sqrt
....
and type int has no sqrt function.
On Mon, 15 Nov 2021 21:52:57 +0000, James Harris wrote:
On 15/11/2021 14:21, Lasse Hillerøe Petersen wrote:
On Mon, 08 Nov 2021 19:46:35 +0000, James Harris wrote:
No. For over half a century, Algol has used a distinct character, and
it has been in Unicode for quite some time: "⏨" (U+23E8) as in 1⏨3.
A few things to say to that:
* Not all powers are of 10. For example, if the number is in hex then
the base might be 16.
All the more reason to use a normal notation with proper superscript.
1 KiB = 2¹° B = 4×16² B = 400₁₆
Of course, if you use for example the C notation of 0x prefix (not saying
it is a good idea) your "hexadecimal scientific notation" should _still_
use ⏨ - as 0x10 = 16. :-)
* Accessing Unicode characters can be a challenge - e.g. remembering
U+23E8, for example.
Have a character menu in the editor where you can pick them out,
this is
not a character issue, but a user interface issue.
Use the correct
symbols, that's why we have them! I find it strange that normal people
have _no_ problems using all sorts of weird emojis in text messages on
their smartphones, but to use well-defined, standard symbols in programs
is soooo haaaard.
* Some Unicode characters look like each other, meaning that code which
used them could have a syntax error while looking perfect to a human
reader.
Says you, who just suggested to "abuse" the likeness of the lowercase x
to ×? :-)
I'd have your Avogadro's constant as
6.02214076x10^-23
which is not too bad, is it?!
In an 8-bit world of ISO-8859-1, I'd find it passable but unsatisfying.
But we live in the world where Unicode exists, has nearly all the symbols
you could ever want, and now seems to be set on a path to revert the evolution of writing back to the hieroglyphs of ancient Egypt with
emojis.
I do not advocate going APL
On 23/11/2021 18:05, James Harris wrote:
On 09/11/2021 18:33, Bart wrote:
SQRT isn't a great example, as it doesn't have a special version for
ints, but let's go with it.
Suppose we implement it via user=code, so we'd start off with these
versions:
function sqrt_f64(f64 x)f64 =
....
end
function sqrt_f32(f32 x)f32 =
....
end
First problem is what to put in place of ....: a loop to do it the hard
way, or a call to a library routine, or maybe inline assembly, so
needing that first item on my list.
Next is that we want to be able to write:
sqrt(x)
and not either sqrt_f32 or sqrt_f64, which means function overloading; another item (on a previous list I think). This is not an easy feature,
esp. with multiple parameters.
Now it works, the problem is that it generates code that is a call to sqrt_f32 or sqrt_64; function inlining is needed. So that sqrt(x) is
turned into whatever was the body of the function:
(a) Inline ASM (specifically, sqrt_ss/sqrt_sd x64 instructions)
(b) A call to a library routine
(c) An algorithm.
(a) would probably be OK, but (b) and (c) are going to be awkward to
turn into the same code as (a). (c) would also require a decent
optimiser. Actually, quite difficult /unless/ the compiler has special knowledege of SQRT. But if it has, then why is it wasting its timing
going through the stages above?
The is a further problem, which is that when you write:
sqrt(9.0)
you really want that turned into the literal 3.0. That might be possible
when the body is (c), and you've implemented 'constexpr', which involves interpreting the algorithm at compile-time time, in the hope it will
finish in reasonable time.
I can see that you just want to brush all this aside, things I consider
MAJOR language features and that are complex to implement.
With my simple approach, then sqrt(x) is trivially turned into a sqrt_sd instruction for example, and sqrt(9.0) is turned into 3.0.
Yes it would be nice for a language to be able to do this for arbitrary user-functions. And if it did, it would be tempting to think about implementing most of the built-in functions the same way.
Except that it make the language many times harder to implement, and it
would run more slowly (for example needing to interpret user-code via constexpr all over the place). You'd be implementing a poor version of C++.
On 23/11/2021 19:24, Bart wrote:
On 23/11/2021 18:05, James Harris wrote:
On 09/11/2021 18:33, Bart wrote:
...
SQRT isn't a great example, as it doesn't have a special version for
ints, but let's go with it.
Suppose we implement it via user=code, so we'd start off with these
versions:
function sqrt_f64(f64 x)f64 =
....
end
function sqrt_f32(f32 x)f32 =
....
end
First problem is what to put in place of ....: a loop to do it the
hard way, or a call to a library routine, or maybe inline assembly, so
needing that first item on my list.
Oh, no. I'd literally have the IR able to understand square roots or
raising to the power of 0.5 so the .... in your first example would be something like
IR.power(f64, x1, x, 0.5)
That would tell the IR stage to create a node in the tree equivalent to
x1 = f64.power(x, 0.5)
Next is that we want to be able to write:
sqrt(x)
and not either sqrt_f32 or sqrt_f64, which means function overloading;
another item (on a previous list I think). This is not an easy
feature, esp. with multiple parameters.
The front end would have to work out whether to use f32 or f64, and it
would enter that in to the tree.
Now it works, the problem is that it generates code that is a call to
sqrt_f32 or sqrt_64; function inlining is needed. So that sqrt(x) is
turned into whatever was the body of the function:
(a) Inline ASM (specifically, sqrt_ss/sqrt_sd x64 instructions)
(b) A call to a library routine
(c) An algorithm.
(a) would probably be OK, but (b) and (c) are going to be awkward to
turn into the same code as (a). (c) would also require a decent
optimiser. Actually, quite difficult /unless/ the compiler has special
knowledege of SQRT. But if it has, then why is it wasting its timing
going through the stages above?
As above, it wouldn't! It'd retain the power(x, 0.5) until later. If
it's still there at codegen time and the target machine had a sqrt instruction then you could expect that that's what would be emitted.
The is a further problem, which is that when you write:
sqrt(9.0)
you really want that turned into the literal 3.0. That might be
possible when the body is (c), and you've implemented 'constexpr',
which involves interpreting the algorithm at compile-time time, in the
hope it will finish in reasonable time.
I can see that you just want to brush all this aside, things I
consider MAJOR language features and that are complex to implement.
No! Things like this would be handled in later stages of the compiler.
With my simple approach, then sqrt(x) is trivially turned into a
sqrt_sd instruction for example, and sqrt(9.0) is turned into 3.0.
So would mine!
Yes it would be nice for a language to be able to do this for
arbitrary user-functions. And if it did, it would be tempting to think
about implementing most of the built-in functions the same way.
Except that it make the language many times harder to implement, and
it would run more slowly (for example needing to interpret user-code
via constexpr all over the place). You'd be implementing a poor
version of C++.
See above. What I am suggesting would push your concerns nearer code generation. The function of the parser (including pre-supplied and user-provided type definitions) would be to get the /semantics/ of the language properly loaded into an IR tree. Then most of the compiler
would perform transformations on that tree.
On 23/11/2021 23:12, James Harris wrote:
On 23/11/2021 19:24, Bart wrote:
On 23/11/2021 18:05, James Harris wrote:
On 09/11/2021 18:33, Bart wrote:
...
SQRT isn't a great example, as it doesn't have a special version for
ints, but let's go with it.
First problem is what to put in place of ....: a loop to do it the
hard way, or a call to a library routine, or maybe inline assembly,
so needing that first item on my list.
Oh, no. I'd literally have the IR able to understand square roots or
raising to the power of 0.5 so the .... in your first example would be
something like
IR.power(f64, x1, x, 0.5)
That would tell the IR stage to create a node in the tree equivalent to
x1 = f64.power(x, 0.5)
So you /would/ have a class of operators which are specially known to
the language and compiler (it has to be both)?
I can see that you just want to brush all this aside, things I
consider MAJOR language features and that are complex to implement.
No! Things like this would be handled in later stages of the compiler.
But it still needs to be special. Suppose a language had sqrt() but a
user performed an experiment where they created a user-function called trqs(), perhaps overloaded, which does exactly what sqrt does, except
its body does not make use of sqrt() (so gives no clues as to what it
does).
Then, would these pairs of expressions:
sqrt(x)
trqs(x)
sqrt(9.0)
trqs(9.0)
end up generating identical native code? And if they do, how much more compilation resources would be involving in dealing with trqs rather
than sqrt?
Remember trqs is just one of 1000 user functions.
On 24/11/2021 00:20, Bart wrote:
The language would define and handle the syntax but would not have a
Scooby Doo about concepts such as floats or square roots!
Knowledge of floats and what "sqrt" means would be in the code for the
float type, and would be user-readable.
The IR would know about (and offer primitives for) floats and powers.
And the type would use the primitives to build the IR tree.
Note that the IR would offer /primitives/. It would not necessarily
offer each function that the type wanted. But each function of the type
would be expressible in terms of the IR's primitives - as in this case.
Remember trqs is just one of 1000 user functions.
Well, as above I would have sqrt effect square root by telling the IR to raise the operand to the power of 0.5. How would trqs do it?
On 24/11/2021 07:58, James Harris wrote:
On 24/11/2021 00:20, Bart wrote:
The language would define and handle the syntax but would not have a
Scooby Doo about concepts such as floats or square roots!
Knowledge of floats and what "sqrt" means would be in the code for the
float type, and would be user-readable.
The IR would know about (and offer primitives for) floats and powers.
And the type would use the primitives to build the IR tree.
So your language would know about powers, if not square roots?
Note that the IR would offer /primitives/. It would not necessarily
offer each function that the type wanted. But each function of the
type would be expressible in terms of the IR's primitives - as in this
case.
Remember trqs is just one of 1000 user functions.
Well, as above I would have sqrt effect square root by telling the IR
to raise the operand to the power of 0.5. How would trqs do it?
OK, so let's say my trqs routine was one of these: (forget overloads for now):
function trqs_1(real x)real =
pow(x, 0.5) # uses C's pow()
end
function trqs_2(real x)real =
x**0.5 # uses built-in **
end
On 24/11/2021 11:23, Bart wrote:
On 24/11/2021 07:58, James Harris wrote:
On 24/11/2021 00:20, Bart wrote:
The language would define and handle the syntax but would not have a
Scooby Doo about concepts such as floats or square roots!
Knowledge of floats and what "sqrt" means would be in the code for
the float type, and would be user-readable.
The IR would know about (and offer primitives for) floats and powers.
And the type would use the primitives to build the IR tree.
So your language would know about powers, if not square roots?
No, the language wouldn't know about either. What the language would
know would be expression syntax - but knowledge of what any
subexpressions /mean/ would be contained in the /types/, as in the
example below.
Note that the IR would offer /primitives/. It would not necessarily
offer each function that the type wanted. But each function of the
type would be expressible in terms of the IR's primitives - as in
this case.
Remember trqs is just one of 1000 user functions.
Well, as above I would have sqrt effect square root by telling the IR
to raise the operand to the power of 0.5. How would trqs do it?
OK, so let's say my trqs routine was one of these: (forget overloads
for now):
function trqs_1(real x)real =
pow(x, 0.5) # uses C's pow()
end
function trqs_2(real x)real =
x**0.5 # uses built-in **
end
I cannot see how those would add anything to the IR tree. Maybe you have something else in mind but AISI the type definition which would be run
as part of the front end of the compiler to build the IR tree. The type definition would not evaluate functions but would, instead, tell the IR
stage what to add to the parse tree. For example,
type float
function trsq(float) -> float
IR.power(0.5)
The IR.power routine would add a power node to the tree.
On 26/11/2021 16:42, James Harris wrote:
On 24/11/2021 11:23, Bart wrote:
On 24/11/2021 07:58, James Harris wrote:
On 24/11/2021 00:20, Bart wrote:
type float
function trsq(float) -> float
IR.power(0.5)
The IR.power routine would add a power node to the tree.
I'm confused: is 'power' here known to the language or not? Or are you distinguishing between the language visible to the user, and the IR used
by the language implementation?
In the latter case, in which language would IR.power be written?
What
appears in the user code?
If I use this example in my user-code:
2.0*pi*sqrt(3.5/9.8)
Then the final AST node is just this:
const: 3.754921 r64
This is even before it gets to the IR, which in my case is linear VM code.
If I use my first trqs version, which emulates a language that doesn't natively know anything about sqrt or power, then it's the usual AST containing a call to trqs() which in turn calls an external function
called pow().
Then that reduction is not possible.
On 26/11/2021 18:03, Bart wrote:
I'm confused: is 'power' here known to the language or not? Or are you
distinguishing between the language visible to the user, and the IR
used by the language implementation?
My intended approach is perhaps a bit unusual (as mentioned below) but
still follows the conventional front end, back end model. There could be
any number of front ends (one for each language to be compiled) and
multiple back ends (one for each target machine for which asm is to be generated). Front ends and back ends are intended to be small and
simple. All the real intelligence in the compiler would be in the IR.
Given that, to answer your question my /language/ would essentially know nothing about floats or powers or trig functions, etc. What the language would understand, however, would be syntax. So in
a + b * c ** d
the language would know from precedence rules that c ** d had to be
executed first but it wouldn't know what ** meant. So how would that be converted to a power operation? If c and d were floats then you could
imagine that the type float would have a definition for ** which took
two floats as input and produced a float as output, i.e.
**(float, float) --> float
The definition would invoke the IR routine using the IR.power()
statement I showed earlier. You could think of that as telling the IR to
add a node to the tree to raise the 'current value' to the power inside
the parens and make the result the new 'current value'. To be clear, the
IR would not do any calculations at that point. All it would do would be
to add a node to the tree.
Can you see from that how:
1. the language would know nothing about powers
2. the type float would know what a power was
If I use this example in my user-code:
2.0*pi*sqrt(3.5/9.8)
Then the final AST node is just this:
const: 3.754921 r64
This is even before it gets to the IR, which in my case is linear VM
code.
Essentially, mine should generate the same output. The only differences
would be that I would have the front end load the bare expression into
the IR, and the constant expression would be resolved by transformations
on the IR. AISI it's better to put such optimisations in the 'middle
end' as they can apply to a wider number of situations.
A front end would check legality of the source code and implement
source --> IR
such that the IR becomes a structured version of the source program. All kinds of transformations would be applied to the IR. Then whatever back
end was being used would implement
IR --> asm
The IR is intended to be independent of any source language. It would include a range of primitives such as addition, power, trig functions
etc for basic (scalar) types: ints, floats, and maybe a few others.
On 26/11/2021 21:34, James Harris wrote:
On 26/11/2021 18:03, Bart wrote:
I'm confused: is 'power' here known to the language or not? Or are
you distinguishing between the language visible to the user, and the
IR used by the language implementation?
My intended approach is perhaps a bit unusual (as mentioned below) but
still follows the conventional front end, back end model. There could
be any number of front ends (one for each language to be compiled) and
multiple back ends (one for each target machine for which asm is to be
generated). Front ends and back ends are intended to be small and
simple. All the real intelligence in the compiler would be in the IR.
Given that, to answer your question my /language/ would essentially
know nothing about floats or powers or trig functions, etc. What the
language would understand, however, would be syntax. So in
a + b * c ** d
the language would know from precedence rules that c ** d had to be
executed first but it wouldn't know what ** meant. So how would that
be converted to a power operation? If c and d were floats then you
could imagine that the type float would have a definition for ** which
took two floats as input and produced a float as output, i.e.
**(float, float) --> float
The definition would invoke the IR routine using the IR.power()
Wait - where is this definition, somewhere inside the front end or back
end? As it seems that somewher in the language implementation is the knowledge that ** must mean exponentiation.
statement I showed earlier. You could think of that as telling the IR
to add a node to the tree to raise the 'current value' to the power
inside the parens and make the result the new 'current value'. To be
clear, the IR would not do any calculations at that point. All it
would do would be to add a node to the tree.
Can you see from that how:
1. the language would know nothing about powers
2. the type float would know what a power was
That doesn't make sense. You say the language has a bunch of operators,
say A B C D E, with no assigned meaning except it knows that they're operators, the number of operands (?), that they are infix, and their relative precedences.
But then another part of the implementation decides that E with float operands should mean power.
Well, it looks like in the end it all comes down to the same thing, if
you can get the same results, at least with x ** y, even if you like to pretend the language is unaware of the meaning of ** (I hope the
language docs say something about it, other than it's a handy
coincidence that it ends up as 'power'!)
At least that one doesn't need expressing in user code, which would
require more effort to reduce to a single IR operation, if the start
point is a call to a user-defined function which contains multiple IR ops.
On 08/11/2021 21:37, David Brown wrote:....
On 08/11/2021 21:26, Dmitry A. Kazakov wrote:
Just apply the base to the exponent as Ada does:(Surely you mean 7 * 2**7 ?)
2#111#e7
means 5 * 2**7. That is why it is E and not 10 in Ada.
Ada's system for non-decimal numbers has always struck me as flexible,
but possibly the ugliest and most difficult to read and write method I
have ever seen.
How often does anyone need a base other than 2, 10, or 16 ?
You can have it for fun, or just for completeness:
println 0x100
println 2x100
println 4x100
println 0x100.1....
println 2x100.1
println 4x100.1
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 292 |
Nodes: | 16 (2 / 14) |
Uptime: | 208:24:17 |
Calls: | 6,618 |
Files: | 12,168 |
Messages: | 5,317,095 |