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

    Two advantages (AISI):

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

    2. It includes the base so bases other than 10 would be possible, if
    required, but the presence of the base is no impediment as even if it's
    always 10 it helps make the number look more natural.




    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?

    FORTRAN-IV did not have the first. Ada 83 had both.

    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.

    Two advantages (AISI):

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

    In this case you must orient rather on physicists and chemists.

    2. It includes the base so bases other than 10 would be possible, if required, but the presence of the base is no impediment as even if it's always 10 it helps make the number look more natural.

    Just apply the base to the exponent as Ada does:

    2#111#e7

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

    One thing I should mention that may be a bit controversial is that in
    keeping with other operators space matters.

      10^3

    is a literal integer meaning 1000 whereas

      10 ^ 3

    That would be an argument against using ^ for both. Note that the same
    issue apply to unary - and +. This the reason why

    +10

    is not a literal in Ada, it is an expression.

    Note also how this is connected to the approach to the types of the
    literals. You need silly rules like below:

    is an expression which would evaluate to 1000. Space must be on both
    sides of ^ or neither. Both of

      10^ 3
      10 ^3

    would be invalid.

    because you could not consistently fold constant expressions making all
    cases equal. Ada has no such problem, e.g.

    -32768

    is perfectly OK for a 16-bit 2's complement integer regardless the fact
    that the literal 32768 is out of the range.

    Exponentiation would have the same problem as -, though much more
    rarely, of course.

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


    Two advantages (AISI):

    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.

    Yes, like in Ada.

    (I'm omitting C's octals and hexadecimal floating point notations, and I don't think the type suffixes are a good solution.)

    A Unicode alternative would be using the mathematical notation for the base:

    1101₂

    Exponents would be superscript as James suggested:

    0.FF03_8A90_FE1E₁ ₆16⁵

    Not very readable in a fixed font.

    P.S. I actually used such stuff in the UI, e.g. to annotate axes in
    graphs and for measurement units. You really want to see m/s² rather
    than m/(s^2) or whatever.

    --
    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
    hexadecimal fraction?

    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, like in Ada.

    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
    floating-point formats used hexadecimal mantissa.

    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.
    Your two non-decimals would be

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

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


    Other bases
    don't turn up in real code, nor do floating point in anything other than decimal. You'll want a digit separator, however - underscore is
    probably the best choice.

    (I'm omitting C's octals and hexadecimal floating point notations, and I don't think the type suffixes are a good solution.)

    Agreed.


    --
    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
    whenever you discuss your language.


    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.
    Your two non-decimals would be

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

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


    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.

    (https://upload.wikimedia.org/wikipedia/commons/9/9c/Hp35s_Calculator.jpg)

    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:

    https://releases.llvm.org/download.html

    (It's the second google hit for 'download clang windows'. The first is
    about building from source.)

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

    https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/LLVM-11.0.0-win64.exe

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



    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.

    I'd have your Avogadro's constant as

    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
    it is a good idea) your "hexadecimal scientific notation" should _still_
    use ⏨ - as 0x10 = 16. :-)

    * Accessing Unicode characters can be a challenge - e.g. remembering
    U+23E8, for example.

    Have a character menu in the editor where you can pick them out, this is
    not a character issue, but a user interface issue. Use the correct
    symbols, that's why we have them! I find it strange that normal people
    have _no_ problems using all sorts of weird emojis in text messages on
    their smartphones, but to use well-defined, standard symbols in programs
    is soooo haaaard.

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

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

    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 🐂💩!

    I'd have your Avogadro's constant as

    6.02214076x10^-23

    which is not too bad, is it?!

    In an 8-bit world of ISO-8859-1, I'd find it passable but unsatisfying.
    But we live in the world where Unicode exists, has nearly all the symbols
    you could ever want, and now seems to be set on a path to revert the
    evolution of writing back to the hieroglyphs of ancient Egypt with
    emojis. I do not advocate going APL - but in normal use, like
    handwriting, a lot of symbols are routinely used, and it is time we
    started adapting our computer usage to normality, after decades of
    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.

    I'd have your Avogadro's constant as

      6.02214076x10^-23

    which is not too bad, is it?!


    Thunderbird helpfully renders that using superscript for the -23, making
    it look significantly nicer than your traditional plain ASCII
    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)

    and not either sqrt_f32 or sqrt_f64, which means function overloading;
    another item (on a previous list I think). This is not an easy feature,
    esp. with multiple parameters.

    Now it works, the problem is that it generates code that is a call to
    sqrt_f32 or sqrt_64; function inlining is needed. So that sqrt(x) is
    turned into whatever was the body of the function:

    (a) Inline ASM (specifically, sqrt_ss/sqrt_sd x64 instructions)

    (b) A call to a library routine

    (c) An algorithm.

    (a) would probably be OK, but (b) and (c) are going to be awkward to
    turn into the same code as (a). (c) would also require a decent
    optimiser. Actually, quite difficult /unless/ the compiler has special knowledege of SQRT. But if it has, then why is it wasting its timing
    going through the stages above?

    The is a further problem, which is that when you write:

    sqrt(9.0)

    you really want that turned into the literal 3.0. That might be possible
    when the body is (c), and you've implemented 'constexpr', which involves interpreting the algorithm at compile-time time, in the hope it will
    finish in reasonable time.

    I can see that you just want to brush all this aside, things I consider
    MAJOR language features and that are complex to implement.

    With my simple approach, then sqrt(x) is trivially turned into a sqrt_sd instruction for example, and sqrt(9.0) is turned into 3.0.


    Yes it would be nice for a language to be able to do this for arbitrary user-functions. And if it did, it would be tempting to think about
    implementing most of the built-in functions the same way.

    Except that it make the language many times harder to implement, and it
    would run more slowly (for example needing to interpret user-code via
    constexpr all over the place). You'd be implementing a poor version of C++.

    --- 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
    it is a good idea) your "hexadecimal scientific notation" should _still_
    use ⏨ - as 0x10 = 16. :-)

    * Accessing Unicode characters can be a challenge - e.g. remembering
    U+23E8, for example.

    Have a character menu in the editor where you can pick them out,

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

    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!

    ...

    I'd have your Avogadro's constant as

    6.02214076x10^-23

    which is not too bad, is it?!

    In an 8-bit world of ISO-8859-1, I'd find it passable but unsatisfying.

    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)

    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.


    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
    instead write:

    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.

    So your language would know about powers, if not square roots?

    Note that the IR would offer /primitives/. It would not necessarily
    offer each function that the type wanted. But each function of the type
    would be expressible in terms of the IR's primitives - as in this case.

    Remember trqs is just one of 1000 user functions.

    Well, as above I would have sqrt effect square root by telling the IR to raise the operand to the power of 0.5. How would trqs do it?


    OK, so let's say my trqs routine was one of these: (forget overloads for
    now):

    function trqs_1(real x)real =
    pow(x, 0.5) # uses C's pow()
    end

    function trqs_2(real x)real =
    x**0.5 # uses built-in **
    end

    (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]
    add Dstack, 48
    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]

    add Dstack, 48
    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.

    So your language would know about powers, if not square roots?

    No, the language wouldn't know about either. What the language would
    know would be expression syntax - but knowledge of what any
    subexpressions /mean/ would be contained in the /types/, as in the
    example below.


    Note that the IR would offer /primitives/. It would not necessarily
    offer each function that the type wanted. But each function of the
    type would be expressible in terms of the IR's primitives - as in this
    case.

    Remember trqs is just one of 1000 user functions.

    Well, as above I would have sqrt effect square root by telling the IR
    to raise the operand to the power of 0.5. How would trqs do it?


    OK, so let's say my trqs routine was one of these: (forget overloads for now):

      function trqs_1(real x)real =
          pow(x, 0.5)                         # uses C's pow()
      end

      function trqs_2(real x)real =
          x**0.5                              # uses built-in **
      end

    I cannot see how those would add anything to the IR tree. Maybe you have something else in mind but AISI the type definition which would be run
    as part of the front end of the compiler to build the IR tree. The type definition would not evaluate functions but would, instead, tell the IR
    stage what to add to the parse tree. For example,

    type float
    function trsq(float) -> float
    IR.power(0.5)

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


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

    So your language would know about powers, if not square roots?

    No, the language wouldn't know about either. What the language would
    know would be expression syntax - but knowledge of what any
    subexpressions /mean/ would be contained in the /types/, as in the
    example below.


    Note that the IR would offer /primitives/. It would not necessarily
    offer each function that the type wanted. But each function of the
    type would be expressible in terms of the IR's primitives - as in
    this case.

    Remember trqs is just one of 1000 user functions.

    Well, as above I would have sqrt effect square root by telling the IR
    to raise the operand to the power of 0.5. How would trqs do it?


    OK, so let's say my trqs routine was one of these: (forget overloads
    for now):

       function trqs_1(real x)real =
           pow(x, 0.5)                         # uses C's pow()
       end

       function trqs_2(real x)real =
           x**0.5                              # uses built-in **
       end

    I cannot see how those would add anything to the IR tree. Maybe you have something else in mind but AISI the type definition which would be run
    as part of the front end of the compiler to build the IR tree. The type definition would not evaluate functions but would, instead, tell the IR
    stage what to add to the parse tree. For example,

      type float
        function trsq(float) -> float
          IR.power(0.5)

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

    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.

    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.

    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)
    IR.add(float, a.re, b.re)
    IR.add(float, a.im, b.im)

    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)

    Printing numbers via Print, reading via Read:

    i64, u64 base 2 to 16 (Print)
    i64, u64 base 10, 2, 16 (Read; other bases TODO)
    f64 base 10 only (may rely on ssprintf)
    decimal (float) base 10 only
    decimal (int) base 10 only, base 2 and 16 or other bases: TODO

    My static language needs has full support, but it may need to be changed
    to match.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)