• #### Re: Power operator and replacement for E exponent notation

From Bart@21:1/5 to James Harris on Mon Nov 8 20:04:24 2021
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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to All on Mon Nov 8 19:46:35 2021
Here's something a bit lighter than what we are discussing in other
threads - a nice, friendly syntax issue. :-)

Exponent notation
-----------------

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,)

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.

Power operator
--------------

The reason for bringing this up now is that in another thread we got on
to discussing a power operator. I was using ** such that "A squared"
would be

A ** 2

However, I am not sure that looks very consistent with the above
notation so I currently have "A squared" as

A ^ 2

That said, I am not going to use x as a multiplication sign so it's not
fully compatible.

What do you think would be best as a power operator? Or should power be calculated by a function as in C?

Spaced out
----------

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.

That's it. Two (or is it three?) issues. Feel free to comment on or
criticise any of them. I can take it!

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to James Harris on Mon Nov 8 21:26:38 2021
On 2021-11-08 20:46, James Harris wrote:

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,)

You can use the Unicode symbol ⋅ instead (U+22C5). There exists ⨯
(U+2A2F) too, but that is vector product.

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.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Dmitry A. Kazakov on Mon Nov 8 20:52:00 2021
On 08/11/2021 20:26, Dmitry A. Kazakov wrote:
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.

Too much like APL!

1. It looks closer to what a mathematician would write.

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

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.

Opinion noted. It sounds as though you see no problem with having

10^3
10 ** 3

and that may make life simpler in some ways.

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)

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.

Again, that sounds interesting but it appears to defy logic. What does
it mean?

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Dmitry A. Kazakov on Mon Nov 8 22:37:15 2021
On 08/11/2021 21: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.

(Surely you mean 7 * 2**7 ?)

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.)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Mon Nov 8 21:27:31 2021
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!

Assuming it is the former, then the number is 896. (BTW my Casio uses ^
for 'to the power of'.)

I would write that entirely in base 2 as the single literal:

2x111e111

This yields 896.0, a float. But I can emulate your example:

2x111*2**7

in this case yielding an integer 896

Once again, don't copy C in this regard, where this:

0x100p10

is the literal 262144.0. This was a surprise to my, since when I write:

0x100p10

I get:

4722366482869645200000.0

Note that my literal is 100% hex, so 0x100p10 means:

256 * 16 ** 16

In C, 0x100p10 means:

256 * 2 * 10

So it's using 3 different bases: hex for the 0x100 part, base 2 (what
you raise to the power), and base 10 for the exponent!

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to James Harris on Mon Nov 8 22:39:48 2021
On 2021-11-08 21:52, James Harris wrote:
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?

Who else would ever use such numbers? (:-)

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

The point is that it does not make much sense to have the exponent
different from the base. The numeric model suggests that the exponent
shifts the mantissa by digits:

2#111#e2 = 2#11100#e0

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?

You stated it yourself, the problem is with the blanks inside the literals:

+ // Children, let me tell you a wonderful story
//
// ...
//
// And they lived happily ever after.
10

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)

A normal reader would expect +10 be signed because you specified that
damned sign!

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.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Bart on Mon Nov 8 22:25:02 2021
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.

There are no versions of pow() for ints
that I'm aware of.

Not in the standard library, no. It has always struck me as an odd
omission (though I don't believe I have needed integer powers in my own
code, except for powers of 2).

If you like 'pow', just use that with function-like syntax, but make it overloaded like '+' and '*'.

Yes, as it is in C (and C++). But go the whole way and cover integer
types as well as floating point types.

For a symbolic operator, either ** or ^ is fine.

I think ** is the more common choice, especially if the language also
wants an operator for xor.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Mon Nov 8 21:56:48 2021
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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to Bart on Mon Nov 8 22:57:07 2021
On 2021-11-08 22:27, Bart wrote:
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!

7 * 2**7. 5 was a typo error.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to David Brown on Mon Nov 8 23:18:34 2021
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:

2#111#e7

means 5 * 2**7. That is why it is E and not 10 in Ada.

(Surely you mean 7 * 2**7 ?)

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.

(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.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Bart on Mon Nov 8 23:43:29 2021
On 08/11/2021 22:56, Bart wrote:
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.

float, double, long double, float _Complex, double _Complex, long double _Complex. The complex types are there, whether you are interested in
them or not.

(I prefer C++'s handling of complex numbers - it makes more sense to
have them as library classes than built-in language types.)

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 - or, at best, a niche tool aimed at minimal size rather
than properly supporting C standards. tgmath.h is part of C99 - a
standard that is two decades old, and which has been superseded twice!
A toolchain that doesn't support it can't call itself C.

(<tgmath.h> precedes _Generic by over a decade. One of the motivations
for _Generic was to allow a <tgmath.h> implementation without needing
compiler extensions, but compilers had <tgmath.h> long before _Generic.)

And no, you don't need to use <ctgmath.h> in C++. In every C++
toolchain known to man, you can use <tgmath.h>. You can alternatively
use <ctgmath> - there is no ".h" in the C++ standard headers.

However, the normal C++ method is to include <cmath> and use overloaded std::pow - the powf and powl (and similarly for fabs and all the others)
are only included for convenience of compatibility.

So it's still messy, and not an approach to be copied.

Don't copy the implementation details from C - copy the user-level
usage. Have "pow" (and "abs", and the rest) as functions that can take
any arithmetic type and adapt to that type. It doesn't matter if this
is done by _Generic, compiler extensions, overloaded functions, function templates, or whatever. (It should not, however, be done with built-in functions or operators - these are library functions in any
well-designed language.)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Dmitry A. Kazakov on Mon Nov 8 23:56:33 2021
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:

2#111#e7

means 5 * 2**7. That is why it is E and not 10 in Ada.

(Surely you mean 7 * 2**7 ?)

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

In C, you could have

(double) 0xff03'8a90'fe1e / 0x1'0000'0000'0000 / 0x10'0000

Yes, I'd write such a monstrosity using a normal hexadecimal number that
is then scaled. How I would write the scaling - dividing by separate
hex numbers, or by a (1ul << (48 + 20)), or something else, would depend
on the context. And I can't imagine any context where such a thing
would exist.

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.

You'll want a digit separator, however - underscore is
probably the best choice.

Yes, I know. C++ could not use underscore, since that had another
meaning, so they picked ' (as used in a few countries). C is following
in the up-coming C23 standard.

(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₂

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.)

Exponents would be superscript as James suggested:

0.FF03_8A90_FE1E₁ ₆16⁵

Not very readable in a fixed font.

Or writeable.

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.

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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Mon Nov 8 23:52:39 2021
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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 08:14:57 2021
On 08/11/2021 21:39, Dmitry A. Kazakov wrote:
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?

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?

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to David Brown on Tue Nov 9 08:47:38 2021
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:
On 08/11/2021 21: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.

(Surely you mean 7 * 2**7 ?)

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?

Rarely. One case I had was tabulating floating-point constants that need
to be exact. IEEE 754 would be binary, but I remember, some

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.

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.)

Yes. I never managed to learn that trick. I open some Unicode HTTP page
or Windows Character Map and copy paste from there.

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.

Yes. I am against Unicode in the programming language even in the string literals.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to James Harris on Tue Nov 9 10:00:12 2021
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? I see two compelling alternatives:

1. Sorry guys, I could not do it right.

2. Piss off, moron!

(:-))

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?

But it would be valid, that is the whole point!

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 08:23:14 2021
On 08/11/2021 22:18, Dmitry A. Kazakov wrote:
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

FWIW my version of that would be similar:

16'0.FF03_8A90_FE1E'x16^-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⁵

I suggested an 'up arrow' but not a literal superscript. IMO all code
should be in universal old ASCII.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to David Brown on Tue Nov 9 09:05:08 2021
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.

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.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 09:35:11 2021
On 09/11/2021 07:47, Dmitry A. Kazakov wrote:
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.

You do? In Ada that's 16#FE#, isn't it, which surely looks worse.

...

Yes. I am against Unicode in the programming language even in the string literals.

Definitely!

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 09:29:19 2021
On 09/11/2021 09:00, Dmitry A. Kazakov wrote:
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?

A standard error message followed by a hint for people coming from other languages. For example, the report might be

Syntax error: invalid character ('-') in name
If you mean minus then remember to include space before and after

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Bart on Tue Nov 9 12:05:05 2021
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.

It makes it easier to have alternative implementations of the functions
for different needs.

It makes it easier to add new functions.

It means you can have separate namespaces and not pollute the global
namespace with rarely-used keywords.

It makes it vastly easier to have different people implementing the
language, and mathematical functions.

Remember, your language is an oddity. It is a /personal/ language - it
makes no difference to you whether a feature is in the language, the
library, or the user code, because it is all part of the same soup.
That is not the case for most languages.

We are not living in the 1960's, trying to re-invent BASIC - nor in the
1970's re-inventing C.

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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Tue Nov 9 12:12:17 2021
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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Tue Nov 9 11:47:16 2021
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...?!

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Tue Nov 9 11:36:14 2021
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:

2#111#e7

means 5 * 2**7. That is why it is E and not 10 in Ada.

(Surely you mean 7 * 2**7 ?)

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 5x100
println 6x100
println 7x100
println 8x100
println 9x100
println 10x100
println 11x100
println 12x100
println 13x100
println 14x100
println 15x100
println 16x100
println

println 0x100.1
println 2x100.1
println 4x100.1
println 5x100.1
println 6x100.1
println 7x100.1
println 8x100.1
println 9x100.1
println 10x100.1
println 11x100.1
println 12x100.1
println 13x100.1
println 14x100.1
println 15x100.1
println 16x100.1
println

static [2:]ichar bases = ("x2","x3","x4","x5","x6","x7","x8",
"x9","x10","x11","x12","x13","x14","x15","x16")
const n = u64.max

for i in bases.bounds do
fprintln "# in base # is #", n, i:"2", n:bases[i]
od

The above prints 100 interpreted as bases 2 to 16 (16 appears twice as
0x and 16x), then 100.1 in the same bases. Finally it displays the same
number in bases 2 to 16. Output is:

256
4
16
25
36
49
64
81
100
121
144
169
196
225
256

256.062500
4.500000
16.250000
25.200000
36.166667
49.142857
64.125000
81.111111
100.100000
121.090909
144.083333
169.076923
196.071429
225.066667
256.062500

18446744073709551615 in base 2 is 1111111111111111111111111111111111111111111111111111111111111111 18446744073709551615 in base 3 is 11112220022122120101211020120210210211220 18446744073709551615 in base 4 is 33333333333333333333333333333333 18446744073709551615 in base 5 is 2214220303114400424121122430 18446744073709551615 in base 6 is 3520522010102100444244423 18446744073709551615 in base 7 is 45012021522523134134601
18446744073709551615 in base 8 is 1777777777777777777777
18446744073709551615 in base 9 is 145808576354216723756
18446744073709551615 in base 10 is 18446744073709551615
18446744073709551615 in base 11 is 335500516A429071284
18446744073709551615 in base 12 is 839365134A2A240713
18446744073709551615 in base 13 is 219505A9511A867B72
18446744073709551615 in base 14 is 8681049ADB03DB171
18446744073709551615 in base 15 is 2C1D56B648C6CD110
18446744073709551615 in base 16 is FFFFFFFFFFFFFFFF

(I can't display floats in any base, because I for those I have a
dependency on C's sprintf.)

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,

I use base 1'000'000'000 in one of my libraries. But it doesn't have
language support!

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Bart on Tue Nov 9 14:02:05 2021
On 09/11/2021 13:12, Bart wrote:
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.

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.

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?

It probably isn't important to you in your language - things like documentation, specification, standards, updates, versions, consistency, compatibility, maintainability, cooperation, are all pretty minor
concepts. It's a different matter for languages with an ambition
greater than one person.

Since the language needs those functions, it still needs to add them but
now needs headers, templates, generics, ... a whole raft of machinery.

Any serious language needs something on those lines. If you want BASIC,
you know where to find it.

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.

And you'll continue to wonder why people don't take you seriously

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

An unwillingness to use your own features: 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.

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. A good language design has the building blocks in the language
itself, and everything else in libraries. Look at Ada - it doesn't
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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Tue Nov 9 12:19:17 2021
On 09/11/2021 11:47, James Harris wrote:
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...?!

It's not hard actually, as a single digit is written as a base-10 number
from 000000000 to 999999999; leading zeros are needed except for the
first digit.

Constants tend to be long (for my bignum library) so are handled as
strings. But they don't look any different from normal decimal:

123456789876543210

This is two digits 123456789'876543210, and has a value identical to the base-10 version.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to James Harris on Tue Nov 9 14:58:08 2021
On 09/11/2021 10:05, James Harris wrote:
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? ;-)

Not often, no. But if I did, I'd use the letters C, G, A and T, just
like any biologist, and not base 4 digits 0 to 3. And you'd want a long
string of the "digits", not an integer.

That's the point here. It's not that there are no uses for other bases
- base 4 can be used in genetics, as can base 64 (three nucleotides
combined into codons). Base 64 is used for encoding binary files as
email attachments, and plenty of other bases (including weird ones) are
used in electronics, mathematics, and other fields. But you don't write
out numbers in those bases - certainly not floating point numbers.

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".

I haven't used B, and don't know all the history, but that's the rule C inherited.

It's curious as to how popular octal was back then that languages made
it the easiest to type.

Octal was more popular in the days before the computing world
standardised on 8-bit bytes (except in niche DSP systems). It was used
on systems that had 6-bit units for holding a character, and for some
other situations where three-bit grouping makes sense (most notably,
POSIX file permissions). The most common way to write octal in modern languages seems to be 0o123, which works okay as long as people don't
insist on using capitals.

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?

In C23 :-) Okay, 0b integer constants are not yet part of standard C,
but they are included in the current plans for the next standard
(planned for 2023). They have been in C++ since C++14, and have been
supported by many compilers in C and C++ for a lot longer than that.

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.

0xbeef  -->  16'beef'
0b1101  -->  2'1101'

IMO the result is logical, flexible and readable but YMMV. And, yes, it
uses underscore for digit separation.

It's okay - it's better than Ada, IMHO, since the apostrophe is not as
dense a character as the hash in Ada. I'm not convinced that it is
worth having something different from other languages in order to
support bases that no one will ever use, but it's quite clear and readable.

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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Tue Nov 9 14:18:08 2021
On 09/11/2021 13:02, David Brown wrote:
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!

I'm looking at a picture of a HP programmable calculator.

It still appears to have dedicated buttons for many of the operators
that I build in to my languages, although some will be shifted.

Including ABS.

Now, why would that be? Probably for the same reasons I make those
common functions built-in to my 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.

It /is/ a common colour name, example:

global tabledata() colournames, colourvalues =
! BB'GG'RR
....
(purple, $, 0x_5E'0D'73), .... This is from a list of 60 named colours, and of a possible 16777216. It's for convenience, unless you want everyone was to define their own versions of Black and White using 0x000000 and 0xFFFFFF. Generics: [pause to switch to my dynamic language] check An unwillingness to use your own features: check The generics in that dynamic language is for user-code. Since it also interpreted, it would be crazy to implement basic language operations as interpreted bytecode. Ones like ABS have a dedicated bytecode instruction, because it makes sense to execute one instruction instead of half a dozen. 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. Which have likely all been influenced by C. However even Python ranks 'abs' above 'sqrt', since you don't need to import anything in order to use abs. Although it doesn't stop you doing: abs = 42 or: abs = math.sqrt Yeah, this is the drawback of my approach; it's harder to write nonsense! Drag yourself out of your ancient history, I'm not as deeply mired in it as you are. You're still using C for a start. and you'll maybe see it makes little sense to put everything into one pot. I put the basics into one convenient place, instead of having to chase headers and imports to provide 'sqrt'. A good language design has the building blocks in the language itself, and everything else in libraries. That is one approach that many think is a good idea. That way you that can end up with monstrosities like C++ that are impossible for any one person to fully understand, and that take forever to compile and with incomprehensible error messages. I decided not to go down that route... Language-building features and metaprogramming, I'm just not into. Other people who make their own personal languages can implement their own preferences. Look at Ada - it doesn't 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. Yeah. It makes it so easy to use.... Again, I'm not reimplementating Ada. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Tue Nov 9 16:31:00 2021 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/. (I'm not saying that they are necessarily bad, either in their entirety or in particular features - merely that things you think work well in those languages can't be assumed to work for more generally useful languages.) 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to David Brown on Tue Nov 9 16:28:22 2021 On 2021-11-09 14:58, David Brown wrote: It's okay - it's better than Ada, IMHO, since the apostrophe is not as dense a character as the hash in Ada. In Ada you can use colon (:) instead of #. Colon is a replacement character for # and ! is a replacement for |. Apparently, for the case somebody had chopped off parts of your teletype... (:-)) There are funny stories of people using the standard input library to parse something like: 4:4:6 They get mighty surprised as nobody remembers about the replacement characters... (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Tue Nov 9 18:57:15 2021 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. The same is true for programming languages. You could move a bit in this or that direction, favor this or that programming paradigm, but there is not much freedom. P.S. People telling you that your language is 80's are shameless flatterers... (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Tue Nov 9 17:28:21 2021 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 18:33:22 2021 On 09/11/2021 17:57, Dmitry A. Kazakov wrote: 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 misunderstood; it is that big list of major language features which I sarcastically said was so easy. Adding a dozen built-on ops: about a days's work. Adding the ability to define those via user-code, and make them transparently work as though they were built-in: at least a year's work. He doesn't appreciate that point because teams of other people have spent decades making that possible in the big tool-sets that he favours. You know what? Ford model T is pretty easy to build. Would you start building such cars to compete with Elon? That's apparently what David Brown wants! The Model T was famous for nearly everthing being an accessory that you had to buy separately, even things that are a legal necessity now. There are certain expectations people have buying a car today. My 1980s car would have lights, mirrors, fuel guage, speedometer etc. all built-in and not user-modifiable. DB says that is no good; why not? The same is true for programming languages. 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Tue Nov 9 19:14:04 2021 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Tue Nov 9 21:59:53 2021 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. 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. Unfortunately it does involve more or less whole C++ or an equivalent in terms of the elaborated type system and generic/OO programming support to keep sqrt-stuff out of the language in the libraries. [C++ is not that bad, it made some poor choices, especially regarding safety, but its type system is very powerful.] It is interesting to monitor evolution of new languages. They all start "small" and if successful end up as a huge pile of assorted half-digested manure. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Tue Nov 9 21:45:32 2021 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: * It can apply to matrices (more elaborate than sqrt since they can be different sizes) * You may want low accuracy versions of the same type * It can apply to complex numbers * Actually it can also apply (and does in my case) to list*number, string*number, set*set, bignum*bignum, and (in one old language) vector*vector (cross-product) And yet, most languages manage to have a version of multiply built-in that works on its built-in numeric types. How is that possible, given the vast number of possibilities that remain unimplemented? But apparently it is. So tell me again why a language can't do the same with Sqrt? --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From James Harris@21:1/5 to David Brown on Wed Nov 10 07:45:58 2021 On 09/11/2021 15:31, David Brown wrote: 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. It's kind of you to put it that way but surely these discussions are for anyone to benefit from in any way that suits him. I find them helpful for the language I am working on, for sure, but I suspect that lots of others benefit, even some who don't post often or at all. In fact, despite the lack of security with Usenet (leading to spam) and there being other online fora this is the best place I've found on the Internet to discuss language design and related issues. One thing that could make it easier to follow, perhaps, is if people are going to bring up a significant topic they do so in a new thread rather than a reply - though of course it's not always easy to determine when a topic will lead to a long discussion! -- James Harris --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Wed Nov 10 08:24:35 2021 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. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Wed Nov 10 12:00:14 2021 On 09/11/2021 18:28, Bart wrote: 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. 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. (Though I have done far more than my fair share of assembly, and also of C programming which is relatively flat in comparison to more modern languages, and I don't suffer from the same problem.) 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 might be okay - interfaces and separations between parts can lead to inefficiencies, and can be more effort to develop if the alternative is small enough to be made by a single person. 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. Advanced C implementations can have features to help get more efficient results. However, no matter how often you claim I am recommending "make it like C", I am very specifically /not/ recommending making a language like C. If nothing else, it would be a pointless exercise - no one is going to make something that is "mostly like C" but has enough advantages to outweigh the advantages of the existing mass of C code, C tools, and C knowledge. I suppose I could explain /again/, but would you listen this time? 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.) 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. And with /better/ facilities (remember, I am not recommending copying C), you can get all the optimisation you want while having these functions defined outside the base language. (Again, I could explain if I thought you would listen.) 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 Yes. * They should be user-functions like any other, which just reside in some standard library Yes. You seem to think this means dumbing down these functions, making them less efficient or stopping them being usable at compile time. I think it means making the language better so that /any/ such functions can be implemented with maximal efficiency and usability by using the language. If the language itself is not good enough to implement "abs" or "sin" as efficiently and flexibly as you could achieve with a built-in function, then the language is not good enough. * 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? There is no need for link-time optimisation for inlining code. Or did you think "library" meant nothing more than a collection of assembly-level entry point symbols with opaque object code requiring full ABI-compliant function calls? * 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 C++'s "constexpr" is only needed because the rules and features for constants and compile-time evaluation were modified and enhanced over time while maintaining backwards compatibility. That is not an issue for a new language. This is the big new idea which is better than my '1980s' language, which is so easy to implement. 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? 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. Of course James will have to make up his own mind. (Or, true to form, will continue discussing the language for decades to come. But these are sometimes interesting discussions.) 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Wed Nov 10 13:03:41 2021 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. 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. 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.) Mine runs on Windows and yet overloaded ** runs fine. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Wed Nov 10 12:39:12 2021 On 10/11/2021 11:00, David Brown wrote: 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. That is your opinion. And of course you've designed many languages. For /users/ of a language, it usually makes little difference if "abs" is a built-in function or a library function. Yes, my languages are for end-users, not language-builders. For people involved in implementing, porting, expanding, documenting, standardising, testing, it is a very different matter. None of those is impacted by the way I do things, except for expanding. My languages are self-contained. If someone wants to add a feature, they take the source code and modify it. Being fairly small, that is not hard. You seem to have a serious aversion to all kinds of structure and modularisation. You have no idea what the structure of my compilers is like. As for the languages themselves, they've had a proper module system for the last decade (unlike C and C++). And I'm now revising it, based on that experience, to be better build programs out of multi-module components. Get your own house in order first I think. I don't know why - perhaps it is a background in assembly programming where everything is held at very flat levels. Hmm, I suspect you still think those one-file C distributions I used to do were how my programs were actually written: as a single, flat source file! Most of my EXE files are also presented as a single flat file; so the original source code must be a single, flat file too! Maybe you are just used to working on your own, doing everything yourself. Yes, and that can be good as well. Thank god I never ended up using C and/or Unix, and devised my own solutions. Whatever it is, you prefer to have everything together in one lump. For FFS, I've talking about a dozen common functions as built-ins. Is it really that much of a big deal that I have to make my compiler 100 times bigger, 100 times more complex, and 100 times slower, just so they can written in user code to the same standard? I bet you don't write your own compilers! You seem to have no idea what is practical. a little system with few users, Keep on patronising. I was selling £millions of software written in my languages with those built-in operators. Or I could have delayed it 20 years while I developed one of those heavy-duty compilers you favour. 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. Only by recognising that 'sqrt(x)' is THE square root function. That is only possible if the language makes a special case for it, AS THOUGH it was built-in. Which is exactly what I do. * The language to know NOTHING about abs, sqrt, sin etc Yes. Um, no. How about the language knows nothing about + - * / either. Just implement those in user-code as functions. Add in user-defined symbolic operators. Add in operating overloading. Add in whole-program optimisation of source code. Add in function inlining. Add in the ability to take a bit-shuffling algorithm and recognise that the code could be reduced to one machine ADD instruction. Be prepared to wait a long time to compile any program because of the huge prelude needed, and the time to reduce down all that boilerplate. People do write implementations like that. THOSE are the hobbyist or academic languages designed as experiments or proof-of-concepts. Mine have /always/ been pragmatic because they had an actual job to do. (Not now; now it's just for the satisfaction of wiping the floor with products like C or LLVM.) * 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.) OK. You are completely dismissing any language that doesn't have the same feature set as C++. Including C presumably. And dismissing any implementation that doesn't have 60-pass optimisers. So, according to you, only big, sprawling, SLOW implementations count. Dismiss everything else, they're just toys! * 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. Another difficult feature, which doesn't port. * 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? Hyper-optimisatation is quite a hard language feature; gcc might uses dozens of passes to get decent code. I write smaller, simpler compilers, so I can't do that. Self-contained, too, so I can't depend on monstrosities like LLVM. Instead, I design MY LANGUAGE so that it is easier to get reasonable code. One way is to build in many common things that other languages would need writing in user-code, requiring a lot of work to make as easy to use and as fast as my built-in versions. When you design YOUR LANGUAGE, then you can make your own choices. In mine, reducing sqrt(9.0) to 3.0 is utterly trivial. This is the support needed in the compiler to make it possible: when ksqrt then z:=sqrt(x) One line of code. 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? More patronising. Let me guess, you're envious that you never got around to writing a language of your own, so you have to piss all over anyone else's attempts? Being able to find square roots is irrelevant for most programs, Yeah. That's why there's a special button for it on pretty much every calculator! and no one will miss an "abs" function - it is the features of the language that are important. It seems to be important enough to be instantly available in Python. And available in the standard C library in half a dozen variations. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Wed Nov 10 13:02:15 2021 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Wed Nov 10 16:05:27 2021 On 10/11/2021 07:24, Dmitry A. Kazakov wrote: 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. The first computer I made, with a Z80 chip, didn't have them either. Neither did it have floats at all. I had to implement those, plus the maths and trig functions I needed for the programs I wanted to write. That didn't stop multiply appearing to be built-in to my language. 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to David Brown on Wed Nov 10 17:55:41 2021 On 2021-11-10 17:31, David Brown wrote: 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. If I correctly remember, they bought the compiler from a third firm. The original MS C compiler for MS-DOS was a pure abomination. 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). Hey, they probably write Windows 11 code in Basic, still. Although, each new version of Basic is incompatible with the previous one... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Wed Nov 10 17:38:00 2021 On 2021-11-10 17:05, Bart wrote: 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. But I do not want a language with single floating-point type and even less a language with a floating type which accuracy and precision are undefined = defined by some arbitrary target hardware. It is no problem to provide accurate down to the declared precision arithmetic for any floating-point type, but it becomes an unnecessary burden for irrational functions. So leaving that to the libraries is a rational choice. 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. That applies to all operators, all subprograms, all literals, all named objects. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Wed Nov 10 17:31:05 2021 On 10/11/2021 14:02, Bart wrote: 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. 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). - 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. Fair enough, that's not too bad an analogy. 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! What you want is an interpreted scripting language. 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? I know you don't care - you are proud of your ignorance in how the C language and how C implementations work. 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. It means it works for people other than you. 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. 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Wed Nov 10 18:14:22 2021 On 10/11/2021 16:31, David Brown wrote: 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. I want to write a program and use abs(). That is not a very difficult operator to provide. You can write your own versions easily enough, even as macros. Yet languages generally provide it: Pascal, Python and C among many. C is the exception in originally providing it as a bundled user-code function, with multiple versions for different types, using either stdlib.h or math.h or tgmath.h. They may be various reasons why it was done like that in the neolithic period when C first came out, but those are still the requirements now. I believe that using tgmath.h instead of math.h emulates overloading of fabs() for various float types, but I showed 3 compiler implementations that had problems with it in 2021. It IS a consequence of how C decided to do this stuff in the distant past, and still does. As it happens, I know how C deals with abs(), since I've implemented C. 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);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:94:50: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl cacosf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:76:50: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_acos(double _Complex __x) {return cacos(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:69:49: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl cacos(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:80:56: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_acos(long double _Complex __x) {return cacosl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:119:52: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl cacosl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:101:50: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_asin(float _Complex __x) {return casinf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:97:50: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl casinf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:105:50: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_asin(double _Complex __x) {return casin(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:72:49: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl casin(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:109:56: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_asin(long double _Complex __x) {return casinl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:122:52: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl casinl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:130:50: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_atan(float _Complex __x) {return catanf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:99:50: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl catanf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:134:50: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_atan(double _Complex __x) {return catan(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:74:49: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl catan(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:138:56: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_atan(long double _Complex __x) {return catanl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:124:52: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl catanl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:159:52: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_acosh(float _Complex __x) {return cacoshf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:95:51: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl cacoshf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:163:52: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_acosh(double _Complex __x) {return cacosh(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:70:50: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl cacosh(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:167:58: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_acosh(long double _Complex __x) {return cacoshl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:120:53: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl cacoshl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:188:52: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_asinh(float _Complex __x) {return casinhf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:98:51: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl casinhf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:192:52: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_asinh(double _Complex __x) {return casinh(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:73:50: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl casinh(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:196:58: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_asinh(long double _Complex __x) {return casinhl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:123:53: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl casinhl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:217:52: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_atanh(float _Complex __x) {return catanhf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:100:51: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl catanhf(_In_ _Fcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:221:52: error: passing '_Complex double' to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex') __tg_atanh(double _Complex __x) {return catanh(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:75:50: note: passing argument to parameter '_Z' here _ACRTIMP _Dcomplex __cdecl catanh(_In_ _Dcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:225:58: error: passing '_Complex long double' to parameter of incompatible type '_Lcomplex' (aka 'struct _C_ldouble_complex') __tg_atanh(long double _Complex __x) {return catanhl(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:125:53: note: passing argument to parameter '_Z' here _ACRTIMP _Lcomplex __cdecl catanhl(_In_ _Lcomplex _Z); ^ In file included from c.c:1: C:\LLVM\lib\clang\11.0.0\include\tgmath.h:246:48: error: passing '_Complex float' to parameter of incompatible type '_Fcomplex' (aka 'struct _C_float_complex') __tg_cos(float _Complex __x) {return ccosf(__x);} ^~~ C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\complex.h:101:49: note: passing argument to parameter '_Z' here _ACRTIMP _Fcomplex __cdecl ccosf(_In_ _Fcomplex _Z); ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Wed Nov 10 19:56:42 2021 On 10/11/2021 19:14, Bart wrote: 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);} ^~~ 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 --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Wed Nov 10 19:41:33 2021 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. (A search for 'Windows pacman' gave me links to an arcade game.) --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Thu Nov 11 11:53:24 2021 On 10/11/2021 20:41, Bart wrote: 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 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 which is known to have a poor setup that disables warnings by default and has only a limited selection of tools? Go to <https://godbolt.org> - it is, as far as I can see, the tool of choice - dozens of languages (not just C and C++), heaps of compilers (such as clang from 3.0 to 13 and development branches, 32-bit and 64-bit, x86 and ARM - and tcc) and lots of functions. If there is something useful that rextester.com can do that godbolt.org cannot, then use that as an extra. (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 not a complete toolchain, and does not come with a library, assembler or linker (though llvm also provides an assembler and linker). The same applies to gcc. Some pre-built packings of clang come with a library, just as some is the case with gcc. Other packages separate these. But however you get the tools, from packages or if you build from source, you need a compiler, assembler, linker and library in order to have a complete implementation or toolchain. And they need to work together - the standard library and the compiler need to match to some extent (though most of the library can be compiler-independent). 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. So you ignore all information 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. 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. I've recommended using msys2 / mingw-64 to you before. For some things, the "Windows way" is better. For others, the "Linux way" is better. (I use two PC's at the office - one Windows 7, one Linux.) In this situation, as for many software development tasks, the "Linux way" is /hugely/ better. Install msys2, and then use its package manager "pacman" (borrowed from Arch Linux) and you'll have everything working in minutes. I have not used WSL, but I gather it is getting better with each Windows version. If you have that and run "apt install clang" rather than msys2 and "pacman -Ss clang", then that will work fine too - it's the same principle. 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. It's a Windows machine. It is not a virtual machine of any sort. I can run "pacman" and "clang" under a normal command prompt (though I prefer to use msys2's terminal). I can compile programs with "clang" on that Windows system and run them on Windows. It is Windows. /Actual/ Windows, whatever that might mean. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Thu Nov 11 11:41:57 2021 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..." --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Bart on Thu Nov 11 12:16:02 2021 On 11/11/2021 11:41, Bart wrote: 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?). I've got clang lying around as part of LLVM. Here's what happens when I try and compile hello.c: F:\llvm\bin>clang hello.c clang: warning: unable to find a Visual Studio installation; try running Clang from a developer command prompt [-Wmsvc-not-found] hello.c:1:10: fatal error: 'stdio.h' file not found #include <stdio.h> So the ideal way of distributing a compiler is to require a 6000MB download of another compiler? I wonder what that toy compiler will do: F:\llvm\bin>tcc hello.c -run Hello, World! How about that? Or this toy compiler: F:\llvm\bin>bcc hello -run Compiling hello.c to hello.exe Hello, World! I like products that get the job done with no fuss. If it was vitally important to compiler/run some program RIGHT NOW, and all I had was clang, I'd be stuck. A 1700MB compiler (three times the size of gcc) that can't even build a Hello World program? It's like buying a £100m 747 to go shopping with, instead of a £100 bike. Except it doesn't come with any engines so doesn't work anyway! But here's more fun with clang. If I provide a suitable "stdio.h" then F:\llvm\bin>clang hello.c -c produces hello.o. Now I try and link: F:\llvm\bin>lld-link hello.o lld-link: error: <root>: undefined symbol: mainCRTStartup lld-link: error: undefined symbol: printf OK, let's provide a C runtime: F:\llvm\bin>lld-link hello.o \windows\system32\msvcrt.dll lld-link: error: \windows\system32\msvcrt.dll: bad file type. Did you specify a DLL instead of an import library? Yes, I did. So a 63MB linker doesn't understand DLL files? Even the 0.18MB tcc will work with DLLs! What a heap of junk. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Thu Nov 11 16:44:04 2021 On 11/11/2021 12:41, Bart wrote: 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. That does not even make sense. 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. (By "package manager", I don't just mean "pacman" - other package managers such as "apt", "yum", "portage", etc., on Linux, "ports" on BSD, and Windows package managers such as Ninite or NuGet. They all follow similar principles. Wikipedia has a list of package managers for Windows.) So when you use a package manager to install "clang", it will first install any required dependency packages such as libraries, assemblers, etc. If you uninstall a package, then any other packages that depend on it are removed. A quick check shows that on both my Linux mint system, and the pacman-handled packages on Windows, clang depends on all or part of gcc. This is not surprising, of course - when a system has a package manager you no longer need to duplicate everything and packages can share libraries, headers, etc. (And yes, I know a "windows-style" system of self-contained binary lumps can sometimes have its advantages.) So removing gcc - and its libraries and related packages - using the package manager will result in clang also being removed. 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. 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. (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). In the C world, it is /Windows/ that is peculiar because it does not have a system compiler, system libraries, system headers. clang is made and distributed in a very similar way to gcc - though there are not as many third-party projects that package up clang and related bits and pieces as there are for gcc. In the ubiquitous weird car analogy, a C compiler is a car engine. You need the car body, wheels, steering wheel, and everything else in order to make use of it. clang is an engine, and it is usually packaged with llvm (including assembler and linker) which is the car body. gcc is an engine, and it is usually used with a car body from binutils. Both need a library and header - the wheels and steering wheel. People will sometimes use different engines and different sets of wheels and car bodies. Some people like a single ready-to-run package containing everything. Some people like to mix and match. Some people conveniently make mixed packages from parts but designed to make life easier for end-users - jut as car manufacturers put together parts made by other suppliers. This does not make clang "peculiar", unless you insist on pretending it is something that it is not. It is an /engine/ - a C compiler. It is not a car, or a toolchain. (Just like gcc.) If you are using MSVC, you might want clang combined with MSVC's libraries and headers. If you are using msys2, you want it combined with the mingw-64 libraries. Maybe you want other libraries (I don't know what msys2 has conveniently available, but on most Linux systems there are several alternatives to the common glibc). I haven't seen that on any other C compiler for Windows, which are all self-contained. You have seen it with gcc. (And no, "TDM" is not a windows version of gcc - it is a packaged collection of gcc, a library, headers, binutils, and other files.) I call that peculiar. You of are course have to be contrary. Understanding what a "compiler" is does not make me contrary. (Don't misunderstand me - I see the advantage of packaging complete toolchains. For my embedded work, I generally install complete toolchains rather than individual parts. But I know that these are toolchain packages made from a combination of different parts.) (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?). I usually get gcc for Windows in exactly the same way as I get clang - via msys2 (another collection of managed packages, such as WSL, cygwin, gnuwinutils, etc., will do fine). It is basically the same as I usually use on Linux. Occasionally I might have call for doing something else, including building gcc myself - but that is a somewhat unusual thing to do. I agree - obviously - that a compiler is of little use without associated parts. So if you want to use clang, you will almost certainly want the other parts of a full toolchain. How you get all these bits is up to you - valid methods include installing another complete C toolchain (msvc, tdm-gcc, whatever) and re-using the library and headers, or finding libraries and headers for Windows, or using pre-build pre-packaged solutions such as msys2, cygwin, WSL, etc. 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?". Is your problem simply that your favourite gcc package bundle for Windows does not also make a clang package? 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! clang doesn't have many headers - it is not an OS, nor a library. It's associated project "llvm" has an assembler and linker - I'm sure gcc could use these without too much trouble. And I suspect that the people behind the mingw-64 and other such projects are smart enough not to tie themselves up in some strange vicious cycle of dependencies. You don't see a problem there? No, I really don't. I can see that things would be more convenient if someone were to put together a stand-alone bundle of clang and required toolchain parts for Windows, as some people have done fore gcc (though they are frequently outdated or limited). Googling then following instructions for installing msys2 involves more steps than a click-and-drool all-in-one installation package. But it is not rocket science - it is only a problem for people who insist on seeing it as a problem. 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. clang.exe is not a gcc clone. The people behind clang have made a point of copying gcc's flags and extensions when they want the same functionality - there is no point in arbitrarily picking different flag names or syntaxes. But that doesn't make it a 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. No, clang has not changed. But it is possible that MS have used different configuration options when building clang - it is normal to use configuration and build options to tune the behaviour you want such as target OS's and processors, supported languages, and many other features. I haven't built clang myself, but I know there are vast numbers of configuration options for gcc. 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. Again - it is /windows/. Your complaints are meaningless - it is like saying you can't do word processing on Windows because Windows doesn't have a word processor. After all, using LibreOffice or MS Word is cheating - you are not using Windows, you are dragging in stuff from some other software. 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..." Right. Someone has asked a question on the internet - what more proof do you need for your argument? --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Thu Nov 11 18:26:56 2021 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. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Thu Nov 11 20:38:59 2021 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? This group is not about just C or Unix, and should not just be about industrial-scaled languages, implementations and toolchains. Do not be silly. C might be a shining example of a poorly designed language, yet if any language deserves attribution to be "industrial-scale" then C. 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? 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. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Thu Nov 11 20:45:46 2021 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. However the Clang version that was being discussed 'targets' MSYS. I'm not quite sure what that means, except that it is not the same as the one targeting MSVC which is where I reported problems. 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. It was then used for a few years with an OS written in assembler. There was no associated HLL. 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. Although that is common to most Linux-originated programs; they are too deeply mired in that 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. Because I need to explain to a non-technical Windows user why they need to install something neither of us understand in order to run a program that I unwisely chose to build with Clang-msys. 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. 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. According to this table, you will only run into trouble trying to use a 25-year-old Win16 binary on Win64, or running a Win64 binary on 15-year-old 32-bit hardware. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Thu Nov 11 22:26:45 2021 On 2021-11-11 21:45, Bart wrote: 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." Only certain Linux distributions use it. Debian uses dpkg/apt, Fedora does rpm/dsn. That it necessarily has to be built as an executable to run on Windows is no surprise; MSYS is not WSL. Ergo, MSYS pacman is a Windows application. 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 object, this is exactly so with MSVC. You need MSVC redistributable to be able to deploy it. 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. In this case there is an OS and C must provide means for access it, starting with an implementation of fopen. 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?) Statistically none. But there are a million ways that the C language /is/ closely tied to Unix and Unix-like OSes. As it is with any OS it targets. 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. 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. They are not. You can use, say, GCC without either. In fact, lots of compilers are deployed without any of these. The GCC with C and Ada front-ends I am using under Windows does not require anything. 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. It is a false analogy. Windows MIPS won't on i686. If you compare OSes then do Debian vs. Windows and not XENIX, ULTRIX, SysV, HP-AUX bundled together for no reason. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Fri Nov 12 00:04:47 2021 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. Some may be more sophisticated, but that's all they are. Here's an old (2018) version of a compiler for my systems language, transpiled into a single C file, to run under 64-bit Linux: https://raw.githubusercontent.com/sal55/langs/master/mu.c It compiles under Linux as: gcc mu.c -omu -lm -ldl It can generate .asm and .obj files, but not .exe since that needs actual Windows DLLs (msvc); it still targets Win64. Another version that is lost, generateD C intermediates then invoked tcc to produce a runnable ELF file; I could run my 'M' programs on Linux! Remember this discussion is about a language that implements overloaded ** or abs() operators, which mine handle easily, but the famous C language struggles. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Fri Nov 12 08:17:20 2021 On 2021-11-12 01:04, Bart wrote: 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. Then stop complaining about tools. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Fri Nov 12 13:55:40 2021 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. That's great. But wait ... why don't they do that anyway? 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. So 'sh' means the command line interface of Linux presumably? I have almost nothing to do with these 'shells', except using them to launch programs, or to manage files. My requirements are minimal and my expectations are low. 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. This probably explains a lot about the weird organisation of C compilers originating in Linux. Anyway, you can keep your 'sh'. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Fri Nov 12 15:30:02 2021 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, 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. Command /= file. FAT and NTFS are case-insensitive, which has nothing to do with whatever commands of whatever command line interpreter. 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. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Fri Nov 12 16:08:47 2021 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: 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. 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. Who cares whether that is tecnically up to the invoked 'ld' or another executable. In any case, tcc doesn't use a separate linker, and it /also/ generates a.out. This doesn't help the exasperated user who for the millionth time has to type "-oprog" for no good reason. (Personally I haven't used a linker for a few years. I've designed them out.) --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Fri Nov 12 17:59:12 2021 On 2021-11-12 17:08, Bart wrote: 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: 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. 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. 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? Yes, until you define what this means. 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. You asked a question about the compiler, not about the application developing environment. The name of that executable will be a.out on Linux unless you specify otherwise. No, it will not, because if you are talking about the environment/tool-chain, then mine has gprbuild that requires a project file. In gprbuild the name of the executable is by default derived from the name of the source file designated as main. Less lucky people will use make, cmake whatever. Nobody sane would use naked compiler/binder/linker for anything bigger than hello-world. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Fri Nov 12 17:49:08 2021 On 12/11/2021 16:59, Dmitry A. Kazakov wrote: 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. We're talking at cross-purposes then, since MSYS came up in connection with Clang in Windows: * I reported a problem with Clang (LLVM/MSVC version) * David Brown said there was no such problem (but on MSYS version not involving MSVC) I then questioned whether his Clang could exist outside MSYS, in which case why not make it available in that form. (Maybe it does exist; I don't know. There seem to be a few different versions and little clear information about them.) Less lucky people will use make, cmake whatever. Nobody sane would use naked compiler/binder/linker for anything bigger than hello-world. I specifically make tools to be as easy to use as compiling hello-world. Here, mm is my compiler: mm hello Build hello world mm mm Build itself (exes must differ in location) mm bcc Build my C compiler mm qq Build my interpreter tcc mm.c Build mm from a one-file C rendering tcc mm.c -omm -lm -ldl On Linux Linux needs a couple of extra options /and/ it needs -o otherwise tcc copies gcc in naming the output a.out. But still, it is just typing. gprbuild is an extra dependency. That's something you want to avoid when distributing source code. By using C for that purpose, then any Linux system is very likely to have a C compiler (except it is the slow gcc, not the fast tcc). Can gprbuild just be given a .c file? If not that then's an extra obstacle. I decided to make my stuff ultra-simple after endless problems building open source stuff that relied on make (which rarely worked) or cmake, or required a 10GB VS download (plus GIT, plus SVN, plus MSBUILD tools, and the bloody thing still went wrong). --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Andy Walker@21:1/5 to Bart on Fri Nov 12 17:37:44 2021 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. Or "!!" [ie "repeat last command"] in my editor. If you are easily exasperated, programming is really not a suitable career. -- Andy Walker, Nottingham. Andy's music pages: www.cuboid.me.uk/andy/Music Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Praetorius --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Fri Nov 12 19:04:11 2021 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. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Fri Nov 12 19:16:17 2021 On 11/11/2021 19:26, Bart wrote: 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. This build of pacman /is/ native to Windows. The programs installed with it, like clang and gcc, /are/ native to Windows. They are programs compiled and linked specifically to run on Windows, and won't run on anything else without conversion layers such as Wine. 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 don't know why you do that - I think perhaps you have been defining your ideas of the computer world around myths and misunderstandings for so long, you can't cope with anything that contradicts them. (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 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. It has many purposes, including running code (if it is generated for the machine running the site). I find that in practice when looking at code snippets it is almost always more useful /not/ to run the code, but to look at the generated code or results. (Often you can write a test function that calls your real function with constant parameters, and the compiler can do the calculation at compile-time so that you can easily see the result.) But if you want to, you can run the code. rextester is much simpler to use and it only compiles and runs. "Try it and see" is of limited use. A setup that hides the important messages is of even less use. 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. System compilers, libraries and headers are there for the convenience of developers and advanced users, and of programs that might have use of them behind the scenes. Most users don't need to see them, but that's okay. It would be fine if Windows had the system compiler as an optional component like "telnet" and the many other bits and pieces that are part of the system, but are only installed (or enabled) if you choose to do so. But, presumably you're talking about a C compiler and C headers; why C? For most OS's, including Windows, C is the system language - it is the language used for much of the OS itself, its libraries and its interfaces. But sure, if you are using an OS written in C++, or Rust, or something else, then you'd want those tools easily available. 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!) You have this all ass-backwards. Yes, the original development of C and Unix were a combined effort. But C is a widely portable language used on vast numbers of systems - pretty much everything, really. C is not "tied to Unix" - Unix (or *nix, for Unix-like systems) is tied to C. People happily use C in all kinds of circumstances that have nothing at all to do with *nix. Yet, others have developed C implementations to exist outside of Unix. Exactly. C is not dependent or tied to 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. I have been using computers for many decades, some *nix, some not. I have used a large number of C compilers - some for *nix systems, some for Windows, some for DOS, but the majority are for all sorts of embedded devices. And usually my embedded stuff these days has to build under Linux and Windows. I don't live in a "Unix bubble", and never have. You have a bee in your bonnet about any tool that started off on a *nix system. I really don't understand it - when something is the best tool for the job, and it runs smoothly and easily on the OS you want, who cares about its original host OS? 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). You demonstrate again and again that you have little understanding of what a C compiler is, what the phrase "C implementation" means, and a serious lacking of detailed understanding of the language you say you have implemented. All we can conclude is that you have made a rough approximation to a limited C toolchain. Now, that's not a minor achievement by any means, and the tool you have made may be perfectly suited to your own personal needs and interests. However, it does not make you an expert on C compilers. 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. Of course not. And it would be nice not to have these endless repetitions where you branch off from the discussion to say how terrible gcc or clang is and how it is impossible to use it on Windows, then when someone tells you how to get it working you then proceed to tilt against your other favourite windmill - the world is all a Unix conspiracy. 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? Windows. If you can't use Windows, and won't use Linux, maybe you should try a Mac. Notice that Unix has now also managed to corrupt Windows so that it is no longer one product. Sometimes I don't know if you are a fool or a troll. Go and ask the FSF how much they care about Windows. Fortunately by the time Unix has completely taken over the world, I'll be dead. The world runs on *nix today, underneath the surface. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Dmitry A. Kazakov on Fri Nov 12 18:36:25 2021 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? Well that is what I do and what I've done. If you want to piss all over that and have the last word, then fine. 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 --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Andy Walker on Fri Nov 12 18:19:17 2021 On 12/11/2021 17:37, Andy Walker wrote: 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"? Compilers which don't follow that pattern usually take the name of the first module. So in Windows, tcc will create fred.exe. On Linux, tcc will write a.out. 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? If I do this on Windows: bcc fred.c jim.c bcc bart.c bcc andy.c other.c The end result is three files fred.exe, bart.exe, andy.exe. Far more practical. This is it in action; first a shell script to compile and run those programs: bcc fred jim bcc bart bcc andy other fred bart andy Now I run it: C:\c>bcc fred jim Compiling fred.c to fred.asm Compiling jim.c to jim.asm Assembling to fred.exe C:\c>bcc bart Compiling bart.c to bart.exe C:\c>bcc andy other Compiling andy.c to andy.asm Compiling other.c to other.asm Assembling to andy.exe C:\c>fred Jim Fred C:\c>bart Bart C:\c>andy Other Andy Try it with gcc, and all will be called a.exe. 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. Yes, what about the millions of times you're building a one-file throwaway program? Then surely that can be no confusion about what the executable might be called. But I just tried 'make' on Ubuntu, it said it's not installed, which is a surprise. (This is a problem when you want someone else to build your code on their machine with as few hassles as possible.) After installing, then: make hello didn't work. And with: make hello.c it said "No rule to make target 'hello.c'" Or "!!" [ie "repeat last command"] in my editor. If you are easily exasperated, programming is really not a suitable career. It might be the perfect career, then you can make better sofware. Let me ask you a question: if you were making a compiler, or actually any program whose input was FILE.TXT and whose output was another file, what would you call that output file? I will admit that if I was developing a prototype, and had other things to worry about, then I've sometimes just called it OUTPUT. Or maybe, if it's a file for my sole use as developer, such as the output of a parser, I might call it AST. But that would NEVER be the case in a production version intended for other people's use, where the output file is important data specific to the user's input data file. Yet, gcc does exactly that. A bit like C itself, a student project that somehow made it into the real world! (Or maybe I'm being hard on gcc as it probably copied the practice from elsewhere.) --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to David Brown on Fri Nov 12 19:07:15 2021 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 those people are also vocal about the deficiences of Windows, or how poor MS's C implementation, when all that's really wrong is that they are not Unix and not gnu C. 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, And again, the only definition YOU want to accept is one that corresponds to the C compilers you've used. Somebody can take a C reference document and build an implementation however they like. So long as it does the job, allowing people to write and run programs in C, then it really doesn't matter how it is organised. So, frankly, I don't care how gcc is organised or consists of distinct components, or who is responsible for them. That's one way of doing things. It does not dictate how everyone else should. Here: C:\cx\big>bcc sql Compiling sql.c to sql.exe C:\cx\big>sql SQLite version 3.25.3/BCC 2018-11-05 20:37:38 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> Create a program that can turn 250,000 lines of dreadful C code (and do it under half a second) into a runnable binary, then we can talk. My bcc breaks all the 'rules' about how C implementations work; good! What we don't need are a lot more sheep. Windows. If you can't use Windows, and won't use Linux, maybe you should try a Mac. YOU apparently can't use Windows (which became famous in the 90s for being a user-friendly GUI for the masses), without extra aids in the form of add-ons like Cygwin, MSYS or WSL. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From David Brown@21:1/5 to Bart on Fri Nov 12 21:03:16 2021 On 12/11/2021 20:07, Bart wrote: 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. No, I said that /I/ had no problem installing clang on Windows and compiling a file containing nothing but #include <tgmath.h>. If you think that makes you a fool, that's up to you. But I certainly demonstrated that clang - the compiler - can be easily and quickly installed and run on Windows, and it supports <tgmath.h> (from an appropriate library). 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()! msys2 provides a collection of libraries and utility programs, all of which are /native/ Windows programs and libraries compiled specifically to run on Windows. Some of these libraries provide calls that match some of those found on POSIX systems (in many cases, these are just wrappers to the Windows POSIX layer - built into Windows, and forming part of its kernel). They make the job of porting programs from *nix systems to Windows easier - often needing nothing more than a re-compile. Programs built with msys2 tools are, on the whole, stand-alone apart from a few DLL's - just like programs built with MSVC or most other compilers. (I'm guessing the same applies to your compiler - it probably relies on MSVC's distributable DLL's.) Some programs might expect files or directories in particular places, just like any other programs on any systems might do. I find many of the utility programs from msys2 to be convenient and useful. "rm" is better than Windows "del". "less" is better than Windows "more". "bash" is better than Windows "cmd" or the insanity that is "powershell". "ssh" and "scp" are better than, well, Windows doesn't have these out-of-the-box. msys2 is a convenience. You could happily install it (because it is simple and easy) and then copy out individual programs and run them on a bare-install Windows system. I've done that. You could do it with clang or gcc too, though it might be a bit fiddly trying to sort out which libraries and headers you need. (There are projects to help with that, such as crosstools-ng - the prime use of such tools is for making cross-compilers but you can make native self-contained toolchains too.) 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. 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. I don't "get it", because it is simply bollocks. It's not even wrong, it makes so little sense. I'm giving up on this. You can continue to live in your angry, confused little world where the nasty unix and C people are all conspiring against you. --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Andy Walker@21:1/5 to Bart on Fri Nov 12 19:35:57 2021 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 most trivial of projects. Yes, what about the millions of times you're building a one-file 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.] -- Andy Walker, Nottingham. Andy's music pages: www.cuboid.me.uk/andy/Music Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Praetorius --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Dmitry A. Kazakov@21:1/5 to Bart on Fri Nov 12 21:17:24 2021 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. 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. Life stinks... 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! 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. 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. Yes, we are all wrong. But again, you need to demonstrate something more realistic than puny Hello-World to prove your point. 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. Sure. Existence of any tool is an indicator of some deficiency. You need a hammer because our hands are too weak. But again, you need to show a viable alternative. Complaining about a.out is just silly. Claims that you can manage middle-sized project from a command line is rubbish. I've never used anything beyond a bare compiler, and a crude IDE Lack of experience is no argument. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Bart@21:1/5 to Andy Walker on Fri Nov 12 21:02:31 2021 On 12/11/2021 19:35, Andy Walker wrote: 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. Don't get me started on another bugbear! I keep directory usage to minimum. I keep file separated by giving them different names. (I have a 'c' directory where I mess around with lots of minor C programs. There's about 250 .c files there. Yeah, I know, there should really be 250 directories with one file in each.) 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. Because there isn't really a downside of doing that. There /is/ to just writing to 'a'. (Why 'a'? Who knows. It could have been rumpelstiltskin, but that would be fine because it's gcc; every illogical behaviour is always a feature that people who complain about just don't understand. There's always some option or other to fix it.) Supposed bart.c was 1000000 lines There's another stupidity. Who in his right mind writes and compiles a single module of 1000000 lines? Sigh. Call it 100,000 lines then, or 10,000, with -O3 and lots of macro expansions. Just something that would take a somewhat annoying amount of time to do again. gcc on my machine takes 15 seconds for about 40,000 lines, for a machine-generated C file, one that will never be edited. Make a typo/thinko anywhere in that unreadable mass of code and you have to edit a 1000000-line file and recompile. Actually Tiny C would build that in about a second. I pitched the million-line file at gcc. 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. No, it is to highlight potential problems in compilers that might otherwise go unnoticed. I think you're just cross that A68G didn't make it to the first, easy hurdle of compiling 20,000 lines; I think it managed 10,000 lines, taking 1.5 seconds. Since the fastest product (NOT MINE), took 1 second for 2,000,000 lines, some of those slower ones could well do with some attention. Remember this is for compiling, not running, the code. Interpreters are not excused. 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 most trivial of projects. Yes, what about the millions of times you're building a one-file 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]. And you only have one at a time exclusive of all others? OK. 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 Oh, right. I thought you were suggesting 'make' as an alternate way 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. 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.] OK, the .c extension is clearly not enough of a clue! --- SoupGate-Win32 v1.05 * Origin: fsxNet Usenet Gateway (21:1/5) • From Andy Walker@21:1/5 to Bart on Sat Nov 13 22:04:06 2021 On 12/11/2021 21:02, Bart wrote: 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? Well, it's a minor point, but yes; as I would have had to arrange to zap "fred.exe", "bart.exe", ... either on the spot or overnight, or else have an accumulation of unwanted executables [and several unwanted back-ups of them all]. As it is, I know that "a.out" is garbage; if I want to preserve it, I rename it. Would you have had to waste time typing -oa.out to get your prefered output? I guess not. OTOH, if you want /your/ behaviour, then write the following one-line shell script and put it as an executable called "c" in your "bin" directory [or whatever the equivalent is in your environment: gcc "$1".c -o "\$*"

then you can write commands such as "c hello" or "c fred bert.c -O3"
and so on, saving several characters per use. I expect you will
find /some/ reason why it doesn't work for you.

[...]
I think you're just cross that A68G didn't make it to the first, easy
hurdle of compiling 20,000 lines; [...].

Not in the least. When you find a real-life example that
requires 20000 lines of code with no structure at all, let me know.
I suspect that A68G will very happily manage to compile and run

INT a, b := 1, c := 2;
TO 20000 DO a := b + c OD

which is much better code [though still silly] than

INT a, b := 1, c := 2;
a := b + c;
a := b + c;
a := b + c;
... repeated thousands of times ...

Write daft programs, and you can expect daft results.

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
Oh, right. I thought you were suggesting 'make' as an alternate way
to compile programs.

No, it's an alternate way of managing projects, so that you
can decide /once/ how to build, test and install your code, inc [eg]
manual entries, documentation, all necessary permissions, clean-up
and so on, and /then/ sit there typing "make" [not even "make hello"]
for everything to happen.

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.

The C compiler can't create "hello.c" for you. But it knows
to invoke the C compiler in response to "make hello.o", which will
create and maintain "hello.o" /from/ "hello.c".

OK, the .c extension is clearly not enough of a clue!

Of course not. You didn't need or want to make "hello.c",
and there are lots of other things you might possibly have wanted
to do with "hello.c" -- print it, remove it or back it up, count
the number of lines in it, create a cross-reference listing for
it, install it in an archive, .... Ten minutes spent reading
the documentation might have helped. See

https://en.wikipedia.org/wiki/Make_(software)

and the references therein.

--
Andy Walker, Nottingham.
Andy's music pages: www.cuboid.me.uk/andy/Music
Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Bull

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to David Brown on Sun Nov 14 21:25:29 2021
On 12/11/2021 20:03, David Brown wrote:
On 12/11/2021 20:07, Bart wrote:

[Finally got curious to see what insults you had for me this time]

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.

I got my clang here:

The first link on that page for a Win64 binary is:

Someone installing that will find that the bundled clang.exe needs msvc.

When someone has installed msvc and successfully synced it to clang,
then they may well find that there are issues with tgmath.h.

That is all that I reported:

"I've just now tried Clang. That is, Clang running on Windows, part of a
large LLVM installation, and with links into MSBUILD tools."

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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to Dmitry A. Kazakov on Sun Nov 14 21:58:40 2021
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.

Never mind, try this test. The last program I wrote in my script
language happened to be this one:

---------------------------------
function f(n) = {(n.even | n%2 | 3*n+1)}

count := 0
n := 989'345'275'647

while n<>1 do
n := f(n)
++count
od

println "Count =", count
---------------------------------

A Python version would be:

---------------------------------
def f(n):
if n & 1:
return 3*n+1
else:
return n//2

count=0
n=989_345_275_647

while n != 1:
n = f(n)
count+=1

print("Count =",count)
---------------------------------

I'm interested in running this to see what value of 'count' is produced.
But let's say there's a snag: the interpreter to run this program, which
is called 'c.q' only exists as source code.

What do to? Well in my case it's simple enough:

C:\qx>mm qq
Compiling qq.m---------- to qq.exe

C:\qx>qq c
Count = 1348

Compiling qq.exe took just over 0.1 seconds. On Windows. With one 0.5MB dependency (mm.exe).

The challenge for you is this: starting only with the source codes of
CPython, try building from scratch in order to run the above program.

You only need enough of it working to run this example.

Let me know how long it took. Once you've done that, try the same
exercise on Windows.

If you find that too easy, try building the gcc tool-chain from source
first. In my case, building mm.exe will add 0.12 seconds (plus the time
to type the command!).

But just carry on sneering. I'll carry on using my nippy tools.

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.

Maybe you think that in that case, it can't possibly be much more sophisticated?

Then you're misinformed. (And have little experience of using compilers processing 0.5M lines per second and generating 5MB of code per second.)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Dmitry A. Kazakov@21:1/5 to Bart on Mon Nov 15 09:02:20 2021
On 2021-11-14 22:58, Bart wrote:
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.

Stop embarrassing yourself. Install Python under Windows, go to the installation folder and see what it entails.

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.

I somehow missed your post illustrating deployment of a GTK-based project...

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to Bart on Mon Nov 15 09:26:53 2021
On 14/11/2021 22:25, Bart wrote:
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.

There are perhaps three rough groupings of PC software developers (with
a few outliers).

1. Those that think the world is Windows and x86 - specifically the
version of Windows they are using at the time, and the type of x86 they
are using at the time. Portability is irrelevant, you can assume "long"
is 32-bit, and so on. A fair part of this group also assumes users are
using English (maybe even specifically American), as well as making a
range of assumptions about the C or C++ that don't even hold within
their limited world of MSVC, Borland, etc., (such as assuming signed
integer arithmetic wraps).

Porting code by type 1 developers is nearly impossible - it is always windows-only.

2. There are those that assume the world is *nix, and really don't care
about anyone else. Their code is typically portable to a wide range of processors and OS's. Sometimes it is easily ported to Windows with
little more than a re-compile using something like mingw-64 to make a
Windows binary, sometimes it is too dependent on features missing from
Windows (such as "fork" calls, or file-system features, or X) and even
if a Windows port can be made, it will feel very alien. The original developers are unlikely to help making Windows ports, but third-parties
can do so.

3. There are those that make their code cross-platform to start with, or
add it as support later on. Most start in the *nix world here.

On the whole, people from the Windows world write Windows-only software.
People from the *nix world are far more likely to write cross-platform software, even if they started on *nix. Thus MSVC is Windows-only,
while gcc mainline development supports at least two Windows
environments (msys/mingw for making what everyone except perhaps you
would call "native" Windows binaries, and cygwin for when you want a compatibility layer to fill in the bits of POSIX that MS left out).

Almost all of the development tools I use on Linux can also run on
Windows. I usually /prefer/ to run them on Linux, and they are
sometimes more efficient there (since Linux is more efficient for some
kinds of tasks), but they can be run on Windows. On the other hand, I
also use development tools that are Windows only and they do /not/ run
on Linux.

Really, you have the situation completely backwards.

Just look at how many open source programs require you to run
'./configure' as the first step (configure is a shell script for Linux).

I use "./configure" on Linux perhaps a couple of times a year, maximum.
Usually I don't bother compiling from source - I need a good reason for
that. (It's nice that I can, but nicer that I don't have to.) I can't remember the last time I used a configure script on Windows.

("configure" is not a shell script for Linux. Often a "configure"
script is generated by autotools, and is specifically made to work on a
huge range of systems, not just Linux, and often including Windows. But
it does rely on a small number of basic utilities.)

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.

Why do you insist on believing that, no matter how often I tell you
otherwise? Is there a point to discussing this if you are simply going
to deny everything others tell you, and call me a liar?

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to Dmitry A. Kazakov on Mon Nov 15 11:45:21 2021
On 15/11/2021 08:02, Dmitry A. Kazakov wrote:
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.

Both Python and my product are byte-code interpreters capable of running
one of the corresponding programs I posted.

Python's binaries are a 0.1MB python.exe file and a 4.5MB python3.dll
file. But it relies on a vastly more complex support system to do the
simple task of running that program.

It's build system is complex too and differs dramatically between
Windows and Linux.

That is its choice.

Mine is a 0.4MB qq.exe file. Usually I incorporate my meagre libraries
to make a self-contained 0.65MB file.

That can run the program immediately with no other support.

That was MY choice.

You seem to abhor anyone trying to make anything smaller, faster, simpler.

Again, it makes me 0.12 seconds to build the interpreter to run that
program.

CPython can take minutes to hours. You obviously equate that with being
better.

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...

I simply wouldn't use it. What, a 55-DLL, 100MB dependency to go with a
100KB application?

WinAPI is as complicated as that, however it is part of my OS so no one
needs to go and source all the dependencies.

What was your challenge again? I think it was:

"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."

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
)

That bmedit.qa is a text file containing all the .q modules, in a form
the interpreter can run directly. It is created as follows:

C:\myapps>qq -qa bmedit
Writing bmedit.qa

The size of that file is 40KB. It uses libraries in the same language of
250KB, part of qq.exe.

This graphics app, which is 100% interpreted, dynamic bytecode, uses an abstraction layer over WinAPI. That had been designed to be switchable
between WinAPI and whatever delights awaited me in Linux' X11, but I
never got round to that; I never had a suitable Linux64 machine. (But I
now I have in the form of WSL's Ubuntu...)

I did however do that for my console library, so that the same program
using cursor positioning, colour text etc worked on either OS.

So, what else do you want to know? I won't use GTK, but I have played
with SDL2, Cairo, OpenGL and Raylib as well as WinAPI.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Lasse =?iso-8859-1?q?Hiller=F8e?= P@21:1/5 to James Harris on Mon Nov 15 14:21:12 2021
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.)

/Lasse

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to All on Mon Nov 15 21:52:57 2021
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

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 × ?

Lower-case x is just a separator, here, similar to a scheme in which r
is a separator:

16rFE
2r1110

I chose x as the separator in this case purely because it allowed the
number to look more familiar.

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.

6.02214076x10^-23

which is not too bad, is it?!

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Lasse =?iso-8859-1?q?Hiller=F8e?= P@21:1/5 to James Harris on Tue Nov 16 00:10:34 2021
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:

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.

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
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

Says you, who just suggested to "abuse" the likeness of the lowercase x
to ×? :-)

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.

That's utter 🐂💩!

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 - but in normal use, like
handwriting, a lot of symbols are routinely used, and it is time we
suffering from the limits of ASCII, ISO-646 or ISO-8859. * is an
asterisk, not a multiplication symbol.

/Lasse

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Brown@21:1/5 to James Harris on Tue Nov 16 09:36:12 2021
On 15/11/2021 22:52, James Harris wrote:
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.

6.02214076x10^-23

which is not too bad, is it?!

Thunderbird helpfully renders that using superscript for the -23, making
representation, or even the Unicode version 10⁻²³ where the spacing is
not nice. Typographically, there is a significant difference between a character designed to give a numerical power for normal-size letter or
number, such as x², and superscript numbers. The spacing for the
Unicode superscript characters is typically designed to fit the spacing
of normal sized characters. (It may vary be font, however.)

Unicode is very convenient and gives a nice and portable method for a
lot of characters. When combined with a decent keyboard layout (i.e.,
not plain US or UK, but something with dead keys) it makes it easy to
write text that is a significant step up from plain ASCII. You can
write names such as Hillerøe, words like naïve or fête with the correct spelling, you can write π·r² with ease.

But it doesn't cover everything you need in typesetting, and trying to
push it too far gives results that will vary significantly in appearance
in different systems, spoiling the point. And while it's easy for Linux
(or other *nix) folk to pick a flexible keyboard layout and enable the
compose key, many other people are not so lucky. Requiring Unicode for expressing numbers in a programming language seems a step in the wrong direction, IMHO.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to Bart on Tue Nov 16 20:29:55 2021
On 15/11/2021 11:45, Bart wrote:
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
)

This program has a dependency on a DLL that processes files like JPEG.
There is a decoder in this dynamic language, but it's too slow for
production use (eg. 1.2 seconds for the image in that demo).

I use one of two libraries:

* One based on stb_image.h (a 7000-line C library). This can be used
when built with my own 'bcc' C compiler into a DLL.

* Another using jpeg.m, a jpeg-only decoder in my language. This is
built with my 'mm' compiler into a DLL.

I'd taken my eye off DLLs, some files has been lost, and some things had
got messed up. But now the code for JPEG is processed with my own tools
only. Which is rather more satisfying.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Tue Nov 23 18:05:06 2021
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.

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.

I can sense you weakening. ;-)

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Tue Nov 23 19:24:10 2021
On 23/11/2021 18:05, James Harris wrote:
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.

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)

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++.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to All on Tue Nov 23 19:59:24 2021
On 16/11/2021 00:10, Lasse Hillerøe Petersen wrote:
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₁₆

So you'd use "10" as a subscript character for ten, then "1" and "6" as separate subscript characters for sixteen? Are you serious?

Of course, if you use for example the C notation of 0x prefix (not saying
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,

So now programmers need special editors?

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.

Are you recommending ✕ or × for multiplication? Or should the compiler accept both?

* Some Unicode characters look like each other, meaning that code which
used them could have a syntax error while looking perfect to a human

Says you, who just suggested to "abuse" the likeness of the lowercase x
to ×? :-)

Nope. If the text is ASCII there is no likeness to x. See how much
easier it is!

...

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.

Quite an acceptance! :-)

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.

AIUI Unicode has many characters which look like each other but have
different codepoints - such as the different-but-hard-to-tell
multiplication symbols, above. Are you suggesting a compiler accept all characters which in most fonts look like each other as equivalent?

I do not advocate going APL

APL would be easy compared with what you are suggesting...!

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Tue Nov 23 23:12:27 2021
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.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Wed Nov 24 00:20:49 2021
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.

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)

So you /would/ have a class of operators which are specially known to
the language and compiler (it has to be both)?

Then that's what I call building them in.

The point of disagreement might then be in where the translation of
sqrt() to SQRT_SD or whatever would occur. (In mine, that is now the
headache of the backend, which needs to implement a 'sqrt' IL instruction.

Next is that we want to be able to write:

sqrt(x)

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.

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.

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.

If I write:

sqrt(x)

I get this AST immediately after parsing:

void------ 1 assign:
void------ - 1 name: y nullid
void------ - 2 unary: Pcl<ksqrt>
void------ - - 1 name: x nullid

It doesn't know names or types, but knows it's a square root! If I

trqs(x)

I get:

void------ 1 assign:
void------ - 1 name: y nullid
void------ - 2 callfn:
void------ - - 1 name: trqs nullid
void------ - - 2 name: x nullid

It's got a long way to go to match the other.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Wed Nov 24 07:58:45 2021
On 24/11/2021 00:20, Bart wrote:
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)?

Almost but not quite. The language wouldn't know about any of this
stuff! Think of there being three links in this particular part of the
chain:

language (syntax) --> type definition (semantics) --> IR

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.

...

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.

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?

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Wed Nov 24 11:23:30 2021
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.

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

(Note that ** for floats maps to C's pow() anyway; see below.)

I haven't done a version with the Newton-Raphson method, which I have to
use elsewhere for bignum versions.

I now write this code:

real x,y

y := sqrt(x)
y := sqrt(9.0)

y := trqs_1(x)
y := trqs_2(x)
y := trqs_2(9.0)

The generated assembly right now is as follows. The code for the first
two could both be improved further to just one instruction each, but is
still better than calling those functions:

# y=sqrt(x)
movq XMM4, R.x # R.x (a reg) is simplified
sqrtsd XMM4, XMM4
movq R.y, XMM4

# y=sqrt(3)
movq XMM4, [L24] # L24 contains 3.0
movq R.y, XMM4

# y=trqs_1(x)
movq XMM0, R.x
call t.trqs_1
movq R.y, XMM0

# y=trqs_2(x)
movq XMM0, R.x
call t.trqs_2
movq R.y, XMM0

# y=trqs_2(9.0)
movq XMM0, [L25]
call t.trqs_2
movq R.y, XMM0

#function trqs_1

t.trqs_1:
R.t.trqs_1.x = XMM15
push Dframe
mov Dframe, Dstack
sub Dstack, 48
movq [Dframe-8], R.t.trqs_1.x
movq R.t.trqs_1.x, XMM0
movq XMM0, R.t.trqs_1.x
movq XMM1, [L19] # L19 contains 0.5
call pow*

movq R.t.trqs_1.x, [Dframe-8]
pop Dframe
ret

#function trqs_2
t.trqs_2:
R.t.trqs_2.x = XMM15
push Dframe
mov Dframe, Dstack
sub Dstack, 48
movq [Dframe-8], R.t.trqs_2.x
movq R.t.trqs_2.x, XMM0

movq XMM0, R.t.trqs_2.x
movq XMM1, [L21]
call pow*
movq R.t.trqs_2.x, [Dframe-8]

pop Dframe
ret

The intermediate code for those calls is the following:

push t.x r64
sqrt r64
pop t.y r64

push 3.0000000000000000e+000 r64
pop t.y r64

setargs 1 0
push t.x r64
callfn &t.trqs_1 r64
pop t.y r64

setargs 1 0
push t.x r64
callfn &t.trqs_2 r64
pop t.y r64

setargs 1 0
push 9.0000000000000000e+000 r64
callfn &t.trqs_2 r64
pop t.y r64

(The sqrt(9.0) reduction has already been done. That could have been
handled by the IL backend, but is more limiting.

Doing it earlier means being able to reduce a complete AST
subexpression, eg sqrt(9)*2+17 reduces to 23.0, which is much harder at
the IL level. Also, it means being able to do this among other things:

[sqrt(9)*2+17]int data

Array bounds must be a compile-time expression, and known before the IL
is generated.)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Fri Nov 26 16:42:30 2021
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.

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.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Fri Nov 26 18:03:57 2021
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:

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.

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.

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.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Fri Nov 26 21:34:01 2021
On 26/11/2021 18:03, Bart wrote:
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?

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.

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.

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

3. the IR would know what a float power was, at least in principle

?

In the latter case, in which language would IR.power be written?

IR.power could be written in whatever language the rest of the IR
routines were written in. It wouldn't matter too much what it was.
Anything convenient would do as long as it implemented the same calling convention as the routines it had to interact with. But that's not
surprising. All that IR.power would need to do would be to add a node to
a tree which was being built to represent the source being compiled. It
would not have to do anything clever.

What
appears in the user code?

If by user code you mean the source to be compiled by the above scheme
then it could be just as you say below using sqrt. The /type/ float is
what would know that sqrt meant power(0.5).

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.

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.

Once the IR tree is built then in a node such as power(0.5) the 0.5
could be recognised as meaning square root. If the target machine's
square root instruction is faster than its power instruction then a sqrt instruction could be emitted.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to James Harris on Sat Nov 27 00:25:19 2021
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.

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.

It sounds like your IR is at roughly the level of what I call AST3 - a name-resolved/type-processed AST just awaiting conversion to linear code.

Because in linear code, it's harder to reduce a more elaborate
expression like my example.

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.

Actually this is exactly the change I made earlier this year. The IR (a stack-based VM for me), was given a syntax, and could exist in discrete
files, with a separate program used to perform the translate to binary.

Except that, while intended to be portable, I only have one proper
target. (A linear C target, while it could just about work, was
abandoned.) Example:

C:\ax>mm -pcl aa
Compiling aa.m---------- to aa.pcl

C:\ax>pc aa
Processing aa.pcl to aa.exe

In practice, the main part of the 'pc' program is incorporated into
'mm', to that mm usually directly generates .exe files. Either product
can also generate .asm if necessary.

Making this separation was a lot header than it seemed at first!

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Harris@21:1/5 to Bart on Sat Nov 27 09:51:52 2021
On 27/11/2021 00:25, Bart wrote:
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.

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.

The definition if IR.power would be part of the IR module.

Maybe it would be clearer if I were to go through the translation steps.
The goal is to make it easy for programmers to define their own types as
it is to define standard ones. And by a 'type' I essentially mean a
collection of functions.

Consider compiling source code which has both the ** operator and a call
to the sqrt function as in

r ** 2.0
sqrt(r)

1. The /language/ would know the precedence etc of ** but it would not
know what it meant. The language would also recognise that sqrt(....)
was a function call but, again, the language would have no idea what
sqrt meant.

2. If we say that r is of type float then the compiler would check where
type float was defined and would find some code like the following.

type float
function **(float a, float b)
IR.power(float, a, b)
function-end

function sqrt(float a)
IR.power(float, a, 0.5)
function-end

.... other such functions ....
type-end

Note that that defines what ** and sqrt mean by invoking a suitable
routine, in each case, in the IR module.

3. The IR routine IR.power would add a node to the parse tree.

To recap, the language would know the precedence etc of operators and
the form of function calls, the type would know what such operators or functions mean, and the IR would contain the routines which build and manipulate the intermediate representation of the code.

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.

Yes.

But then another part of the implementation decides that E with float operands should mean power.

It depends on what you call "the implementation". The language would not
know what sqrt meant but if the type of its operand was T then the
compiler would look in the definition of T to find a function called
sqrt. IOW it would expect to see

type T
function sqrt....

The important thing here is that type T could be supplied with the
language like a standard library or the programmer could write his own
types. For example, if the language extension is xx the float type could
be defined in a file called

type_float.xx

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'!)

Yes, it would achieve the normal outcome but it would allow users to
deploy the same mechanisms to write their own types. For example, say
that as a programmer I wanted to write a complexf type which used floats
as its components. I could start it with something like

type complexf
function +(complexf a, complexf b)

The actual form would be a bit more wordy than that but it hopefully illustrates the basic idea.

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.

The IR would support many operations but they would all be primitives
from which other operations could be built - as in the example of the IR
not understanding sqrt but it understanding power, an operation in which
square root can be expressed.

--
James Harris

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Bart@21:1/5 to Bart on Fri Dec 3 17:15:21 2021
On 09/11/2021 11:36, Bart wrote:
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:

2#111#e7

means 5 * 2**7. That is why it is E and not 10 in Ada.

(Surely you mean 7 * 2**7 ?)

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
....

I've had to remove literal support for bases other than 2, 10, 16 in my
dynamic language, for integers, and bases other than 10 for floats.

I was refactoring code, and it was just too fiddly.

This is about direct compiler support for such literals; they will still
be available via library functions (TODO). Output in such bases (which
is more useful) will stay.

Support will now be:

Numeric literals in source code:

i64, u64 base 10, 2 and 16 (as 100, 2x100, and 0x100 only)
f64 base 10 only (may rely on strtod())
decimal (float) base 10 only
decimal (int) base 10 only, base 2 and 16 TODO

('Decimal' (my bignum type) literal processing is done at runtime anyway)