modula3 / cm3

Critical Mass Modula-3
http://modula3.github.io/cm3/
Other
139 stars 25 forks source link

There is no PutLongReal? #1079

Closed ghost closed 2 years ago

ghost commented 2 years ago

Because PutReal doesn't work with LONGREAL. The error message is obscure at least (actual not assignable to VALUE formal (2.3.2) (r)) I made no progress until I found an example on the internet (too difficult to find it!). It turned out I have to convert it to FLOAT first before able to feed it to PutReal!

First I think it's module IO that is limited. After I looked at module Wr I found it's not any better!

This is the precious example: https://cs.fit.edu/~ryan/compare/TPK-m3.html

jpgpng commented 2 years ago

@VictorMiasnikov I have the impression that he doesn't know Modula 2 either. Do you think the same as me?

mikanystrom commented 2 years ago

PutReal doesn't work with LONGREAL because of the type assignment rules.

It's definitely an omission that IO doesn't have a PutLongReal, because, as I said before, LONGREAL, not REAL, is the "standard" floating-point format.

The idiomatic way to write numbers is to use Fmt.

So ...

VAR x := 1.0d0; BEGIN Wr.PutText(Stdio.stdout, Fmt.F("the number is %s", Fmt.LongReal(x))) END

There are many ways to make this more convenient, of course. And several interfaces that do that already. But this is the idiomatic, basic way to print numbers.

(And use Fmt.Int and Fmt.Real, etc., for other types.)

  Mika

On Sat, Sep 10, 2022 at 6:33 PM pwd96m4a @.***> wrote:

Because PutReal doesn't work with LONGREAL. The error message is obscure at least. I made no progress until I found an example on the internet (too difficult to find it!). It turned out I have to convert it to FLOAT first before able to feed it to PutReal!

First I think it's module IO that is limited. After I looked at module Wr I found it's not any better!

This is the precious example: https://cs.fit.edu/~ryan/compare/TPK-m3.html

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKYNJPL3PKD7HI4NZU5TSTV5UZF7ANCNFSM6AAAAAAQJSBEI4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

jpgpng commented 2 years ago

Modula 2 doesn't have PutLongReal either. If he came from Modula 2 he should know it. BTW, On GM2, REAL is double and LONGREAL is long double, SHORTREAL is float. I have no idea why with Modula 3 REAL is float and LONGREAL is double. It's a step backward IMO.

https://www.nongnu.org/gm2/12/elementary_data_types.html

VictorMiasnikov commented 2 years ago

12.09.2022, 08:40, "jpgpng" @.***>: Modula 2 doesn't have PutLongReal either. If he came from Modula 2 he should know it. BTW, On GM2, REAL is double and LONGREAL is long double, SHORTREAL is float. I have no idea why with Modula 3 REAL is float and LONGREAL is double. It's a step backward IMO. https://www.nongnu.org/gm2/12/elementary_data_types.html

( M2 LONGREAL is M3 EXTENDED)

I'm not sure that EXTENDED stay be 80bit float.

We have "red color" results in 1.. 2 tests of Modula-3 test suite.

It looks like that EXTENDED did long double.

GCC And Co "kill" it because Intel SSE is only 32 .. 64 bit real.

ghost commented 2 years ago

This is really annoying. The official example failed to build: https://github.com/modula3/cm3/tree/master/examples/files/src

Again, an obscure error message like this: "../src/DirectoryListing.m3", line 53: actual not assignable to VALUE formal (2.3.2) (n)

I go to the reference of Files and found status.size is a range of LongInt: [0L..LAST(LONGINT)] so it's error-ing because you can't feed status.size to IO.PutInt which expects an INTEGER: https://modula3.github.io/cm3/help/gen_html/libm3/src/rw/IO.i3.html

https://modula3.github.io/cm3/help/gen_html/libm3/src/os/Common/File.i3.html

I have no idea how to fix it. So I commented out line 53 and it compiled fine.

You should really really improve the error message of this compiler, it's very obscure, very hard to understand.

ghost commented 2 years ago

The current system is very hard to use. Even you the developers of all of this made a mistake like this. Let alone new users...

ghost commented 2 years ago

@jpgpng On M2 I only use GM2 but never ADW. I don't use M2's IO functions but bypass it to call C standard functions directly.

ghost commented 2 years ago

BTW, WTF is (n) in the error message I wonder? On the first post it's (r) which I guess is real, but what about (n)? If (n) means integer then should it be more right to be (i)? The error message is very useless for me because I can't understand it!

jpgpng commented 2 years ago

How to do type casting in Modula 3? On Modula 2 there is the Cast function of module SYSTEM. Does Modula 3 have a SYSTEM module like Modula 2?

jpgpng commented 2 years ago

I found Modula 3 also has the VAL (listed on reserved identifiers). But the parameters' order is reversed. On Modula 2, it's VAL(TYPE, ...) but on Modula 3 it's VAL(..., TYPE) (... could be variable or expression, at least on Modula 2). I admit I'm not quite understand the usage of VAL on Modula 3. When I used the VAL(TYPE, ...) Modula 2 syntax the compiler gave this error:

"../src/DirectoryListing.m3", line 53: VAL: first argument must be an integer "../src/DirectoryListing.m3", line 53: VAL: second argument must be a type

So it seems the VAL of Modula 3 can only be used to convert from INTEGER to other types, it's somewhat equivalent to Modula 2's INT(...) and it's not as powerful as the VAL on Modula 2. If it's so then what is the preferred way to do type casting on Modula 3?

jpgpng commented 2 years ago

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose:

https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

jpgpng commented 2 years ago

From what I have read, it seems Modula 3 (and Oberon) doesn't offer anyway to do type casting as the document for Oberon said it will break garbage collection. It's a hard problem now. Doesn't offer anyway to do type casting. But being strong typed, the compiler always complains about type mismatch. How could we resolve it? Isn't this a self contradiction?

RodneyBates commented 2 years ago

On 9/12/22 06:11, pwd96m4a wrote:

This is really annoying. The official example failed to build: https://github.com/modula3/cm3/tree/master/examples/files/src

Again, an obscure error message like this: "../src/DirectoryListing.m3", line 53: actual not assignable to VALUE formal (2.3.2) (n)

Do you know the meanings of "actual" and "formal"?

A formal parameter is the name given for the parameter in the declaration of a procedure, in your example, "n" in IO.i3:   PROCEDURE PutInt(n: INTEGER; wr: Wr.T := NIL);                    ^

(And, BTW, re. your later post, that is the meaning of the  "n" in the error message.  This would have been clearer if the  mismatched formal had a longer-than-one character name.  But  there's not much the error message could about that.)

An actual parameter is the expression supplied in a call, e.g., "status.size" in the call:   IO.PutInt (status.size)              ^^^^^^^^^^^

Assignability is defined in 2.3.1, with reference to 2.2.10 on subtypes

I go to the reference of Files and found status.size is a range of LongInt: [0L..LAST(LONGINT)] so it's error-ing because you can't feed status.size to IO.PutInt which expects an INTEGER: https://modula3.github.io/cm3/help/gen_html/libm3/src/rw/IO.i3.html

You have correctly understood the error message.

https://modula3.github.io/cm3/help/gen_html/libm3/src/os/Common/File.i3.html

I have no idea how to fix it. So I commented out line 53 and it compiled fine.

IO and RTIO are both limited interfaces designed for simple cases. Wr and Fmt are the more general mechanism, and the best way to do output.  That said, I see a PutLongInt in IO, which, without trying it, I would expect to work here.

This example has suffered bitrot.  Originally, in the days of max 32-bit integers, there was no LONGINT in Modula-3.  It got added specifically to support files of length greater than 2^31-1, but has other uses, if you want to write code that can run on a 32-bit implementation.  File and IO apparently got updated to use LONGINT, but this example did not.

You should really really improve the error message of this compiler, it's very obscure, very hard to understand.

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1243582738, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNE6ZNZOTGBOTE5P3R3V54FWPANCNFSM6AAAAAAQJSBEI4. You are receiving this because you are subscribed to this thread.Message ID: @.***>

RodneyBates commented 2 years ago

On 9/12/22 07:01, jpgpng wrote:

     How to do type casting in Modula 3? On Modula 2 there is the Cast      function of module SYSTEM. Does Modula 3 have a SYSTEM module like      Modula 2?

And also:

     From what I have read, it seems Modula 3 (and Oberon) doesn't offer      anyway to do type casting as the document for Oberon said it will      break garbage collection. It's hard now. Doesn't offer anyway to do      type casting. But being strong typed, the compiler always complains      about type mismatch. How to resolve?

This is a significant topic in programming language design.

There are two fundamentally different meanings to the ambiguous term "cast".  One takes a programming-language level view and is defined by a mapping of values of one type into another, e.g., 1 (integer) and 1.0 (real).  The mapping is defined by the language, and is, ideally at least, implementation-independent.  In general, a compiler may have to do some runtime computation to implement this.  I will call this "type conversion".

The other is machine-code level and just reinterprets the bits according to the implementation's representation of a different type than the variable's declared type.  I believe Wirth calls this "type transfer" in Modula-2.

C confuses the issue with a single syntactic construct (a "cast")that can be either one, depending on the pair of types involved.  C++ keeps this, but adds some unambiguous alternatives with names like "reinterpret_cast", if I recall correctly.

So in Modula-3, the type transfer function is LOOPHOLE.  It can undermine garbage collection, and knowing when requires a machine-level understanding of type representations and the workings of the GC.  That is why LOOPHOLE is legal only in a module declared UNSAFE.

As for type conversions, Modula-3 has several.  FLOAT will convert an integer or any floating type to any floating type.  FLOOR, CEILING, ROUND, and TRUNC convert a floating type to INTEGER, with different rounding rules.  (Hmm, did anybody add conversions of floats to LONGINT?  They're not in the original language definition.)  ORD converts any ordinal type to INTEGER, and VAL does the reverse.

And then we have assignability.  This is unusual or maybe unique in Modula-3.  In most languages, things that are likely to be given different bit representations by a compiler, are given different high-level types, the plainest example being different sizes of integers.  These must be converted, either by explicit conversion or implicitly.

Implied conversions create unfortunate tar pits of rules involving when they are done, types and representation of intermediate results, etc. The possibilities are many, and a lot can happen that is entirely invisible in the source code.  Have you understood or even tried reading the many pages of implied type conversion rules of C++ or Java?  If, as I do, you write code caring about intermediate overflows, working at full ranges, etc, this a nightmare.

Modula-3 explicitly states that it has no implied type conversions. However, similar results follow in certain cases.  If two types are "assignable", they can be mixed in source code with no "conversion", but the implementation may need to alter the representation only, at the machine level.  The type combinations where this can happen are defined in 2.3.1.

The meanings of this are defined by the fact that certain values are members of more that one type.  So when such a representation change happens, it has no high-level significance because the high-level value does not change.  So if a variable has type [0..2], it can be assigned to a variable of type INTEGER, because each of its values 0, 1, and 2 are values of INTEGER too.  There is probably a change of representation, because a compiler would probably put [0..2] in a byte or such, but this does not change the meaning of the assignment.

Some cases require runtime value checks to ensure the value is a member of the new type.  A more interesting case is assignment between fixed and open array types.

jpgpng commented 2 years ago

I do not agree that these functions are type casting functions. Type casting is only a by product of them. For example, you don't have anything to cast from LONGINT to INTEGER, don't you? There is also no functions to cast from LONGREAL to REAL.

Because lack of type casting and also lack of method overloading, this is the reason why you used generics too much. Even a simple function like Sqrt has it own Sqrt interface and one has to instantiate it to the corresponding type, e.g: RealSqrt to only to use the function Sqrt on a REAL value. You think it as type safety and it's part of your language design, but people come from other languages (even Modula 2) will find it weird and overly complicated. Yes, M2 doesn't support method overloading either (so does C, M2 maps well to C and both are native language, Modula 3 and Oberon are GC-ed language), but M2 has type casting. M2 is very similar to C except doesn't have a powerful macros system like C.

ghost commented 2 years ago

Anyway, who could tell me how to use the interface Sqrt mentioned there?

https://modula3.github.io/cm3/help/interfaces.html#math

https://modula3.github.io/cm3/help/gen_html/libm3/src/sqrt/Sqrt.ig.html

I'm sure with you there is no such thing as Sqrt.ig. Is the document outdated? Or it's for a different implementation of M3?

libm3/sqrt doesn't have any file whose names have "Sqrt" in it. There are only two files: FloatExtras.ig and FloatExtras.mg. Inside these files there is also no mention of "Sqrt" either.

Since the interface (from the extension it's generic interface), doesn't exists. So does it instantiated interfaces:

https://modula3.github.io/cm3/help/gen_html/libm3/derived/RealSqrt.i3.html

https://modula3.github.io/cm3/help/gen_html/libm3/derived/LongSqrt.i3.html

What kind of document is this? A document you can't trust! Wasted for me many days trying to figure out how to use it, always thinking that I must do sth wrong but the fact is it's simply the document that sucks and these interfaces just don't exists!

mikanystrom commented 2 years ago

That's a square-root implementation, all right.

But why don't you just use Math.sqrt like a normal person?

Not saying you have to, it's a real question. Math.sqrt gives you a double-precision square root of a double-precision number. The Sqrt thing computes square roots from first principles. It's not out of date or anything, but Math.sqrt is what you want if you want to take square roots (normally).

On Mon, Sep 12, 2022 at 4:29 PM pwd96m4a @.***> wrote:

Anyway, who could tell me how to use the interface Sqrt mentioned there?

https://modula3.github.io/cm3/help/interfaces.html#math

https://modula3.github.io/cm3/help/gen_html/libm3/src/sqrt/Sqrt.ig.html

I'm sure with you there is no such thing as Sqrt.ig. Is the document outdated? Or it's for a different implementation of M3?

libm3/sqrt doesn't have any file whose names have "Sqrt" in it. There are only two files: FloatExtras.ig and FloatExtras.mg. Inside these files there is also no mention of "Sqrt" either.

Since the interface (from the extension it's generic interface), doesn't exists. So does it instantiated interfaces:

https://modula3.github.io/cm3/help/gen_html/libm3/derived/RealSqrt.i3.html

https://modula3.github.io/cm3/help/gen_html/libm3/derived/LongSqrt.i3.html

What kind of document is this? A document you can't trust! Wasted for me many days trying to figure out how to use it, always thinking that I must do sth wrong but the fact is it's simply the document that sucks and these interfaces just don't exists!

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244707840, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKYNJNYIAU5I5ILIO736M3V564ENANCNFSM6AAAAAAQJSBEI4 . You are receiving this because you commented.Message ID: @.***>

mikanystrom commented 2 years ago

??

I think you're mixing up concepts here.

You can convert between REAL and LONGREAL as much as you like. You just have to do the conversion literally.

e.g.

VAR a, b : REAL; BEGIN a := FLOAT (Math.sqrt(FLOAT(b, LONGREAL))) END

if that's what you want. And the semantics are exactly the same as

float a, b; a = sqrt(b);

(which involves an implicit type conversion from float to double for b and another type conversion from double to float for the result of sqrt)

Now in some cases you can use the generics to avoid type conversions, yes, but you don't have to. You can still type-convert if that's what you want. You certainly don't have to use generics if you don't want to!

The thing is, though, doing type conversion to and from the types you use for operations does not give the same answer as using generics to do the operations directly on the type you want.

I am not sure I understand the distinction between "GC-ed" and "native" languages, either...you can take a C function, rewrite it in M3, and get precisely the same assembly out of the compiler.

On Mon, Sep 12, 2022 at 4:11 PM jpgpng @.***> wrote:

I do not agree that these functions are type casting functions. Type casting is only a by product of them. For example, you don't have anything to cast from LONGINT to INTEGER, don't you? There is also no functions to cast from LONGREAL to REAL.

Because lack of type casting and also lack of method overloading, this is the reason why you used generics too much. Even a simple function like Sqrt has it own Sqrt interface and one has to instantiate it to the corresponding type, e.g: RealSqrt to only to use the function Sqrt on a REAL value. You think it as type safety and it's part of your language design, but people come from other languages (even Modula 2) will find it weird and overly complicated. Yes, M2 doesn't support method overloading either (so does C, M2 maps well to C and both are native language, Modula 3 and Oberon are GC-ed language), but M2 has type casting. M2 is very similar to C except doesn't have a powerful macros system like C.

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244694413, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKYNJMMKQ3VWRWP2POAQF3V562CPANCNFSM6AAAAAAQJSBEI4 . You are receiving this because you commented.Message ID: @.***>

jpgpng commented 2 years ago

That's a square-root implementation, all right. But why don't you just use Math.sqrt like a normal person? Not saying you have to, it's a real question. Math.sqrt gives you a double-precision square root of a double-precision number. The Sqrt thing computes square roots from first principles. It's not out of date or anything, but Math.sqrt is what you want if you want to take square roots (normally).

It seems it's really deprecated. On my cm3 build (mingw64 based) there is no Sqrt.i too. But it's there in the source tree:

https://github.com/modula3/cm3/tree/master/m3-libs/libm3/src/sqrt

So for some reasons, it was not build and included in my installation.

jpgpng commented 2 years ago

Sqrt is in https://github.com/modula3/cm3/blob/master/m3-libs/m3core/src/float/Common/Float.ig though.

jpgpng commented 2 years ago

@mikanystrom I forgot about FLOAT. But you still can't cast from LONGINT to INTEGER. On Modula 2, we have INT(...) to do so. There is no such thing on Modula 3. And INTEGER(...) is invalid as INTEGER is a data type and not a function!

jpgpng commented 2 years ago

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose:

https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

It seems you could use VAL to convert between LONGINT and INTEGER. But this usage of VAL is absurd. Modula 3 messed up the well known VAL of Modula 2!

mikanystrom commented 2 years ago

VAL isn't "messed up". It just is what it is. And so yes you can convert between LONGINT and INTEGER. And you can write the code you're trying to write, and move on....

But a few comments to that:

  1. If you're looking for a "cast" in Modula-3, you're doing something wrong. You should think of, and use, Modula-3 as a "safe" language, like Java. (I'll address UNSAFE in a bit.) There are no "casts" in such a language. There are only checked type transfers. If you use it like that, you may come to understand what a brilliant design it is. Here's a language that runs directly on your machine (not inside a JVM) and gives you all the same safety guarantees that Java does, and higher performance, and a much richer type system (native records, enumerations, subranges..) in 50 pages of specification. Oh and powerful generics that aren't tied only to objects and classes. It's really pretty remarkable, especially for the era (M3 predates Java by a few years). Plus there has been very little spec churn. Since src-rr-52, only really LONGINT (see below). (Compare that to Java!)

  2. UNSAFE Modula-3: I consider this another language entirely. Again let's consider Java. Java can't be implemented in Java. Java can't be used to write a device driver. The small UNSAFE subset of Modula-3 allows you to do all this, including any unchecked type transfers or whatever you want to do. But it's not something you should be reaching for on a daily basis. (Unless these tasks are your main job.) Most regular applications don't require a single line of UNSAFE code (just like many applications can be coded just fine in Java).

In summary, if you think of Modula-3 as a friendlier, better Java, it comes out as an absolutely brilliant design, and an outstanding achievement. It has no equal that I know of. (I don't know anything much about Oberon, but I'm having dinner at ethz tonight as it happens.) Sorry if it breaks some Modula-2 idiom. But it's not intending to be backward compatible.

  1. LONGINT. There's almost no need to use this today unless it's in an interface you're interacting with. It was a stopgap measure to allow 32-bit machines easy access to large files. On a 64-bit machine, INTEGER is usually the same size! I was against the introduction of LONGINT at the time---I think the value of not changing the language spec would have outweighed the temporary utility of LONGINT. But clearly not everyone agreed, and it's done. Generally you can pretty much ignore it, though, except for the few times you have to uh seek in a file?

    Mika

On Tue, Sep 13, 2022, 3:08 AM jpgpng @.***> wrote:

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose:

https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

It seems you could use VAL to convert between LONGINT and INTEGER. But this usage of VAL is absurd. Modula 3 messed up the well known VAL of Modula 2!

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244767305, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKYNJO4AJVN2Z2GZLHKDPTV57H2NANCNFSM6AAAAAAQJSBEI4 . You are receiving this because you were mentioned.Message ID: @.***>

RodneyBates commented 2 years ago

On 9/12/22 18:11, jpgpng wrote:

I do not agree that these functions are type casting functions. Type casting is only a by product of them. For example, you don't have anything to cast from LONGINT to INTEGER, don't you? There is also no functions to cast from LONGREAL to REAL.

Yes, there is.  2.6.10, towards the end:

FLOAT (x: Integer; T: Type := REAL): T (x: Float; T: Type := REAL): T

FLOAT(x, T) is a floating-point value of type T that is equal to or very near x. The type T must be a floating-point type; it defaults to REAL. The exact semantics depend on the thread's current rounding mode, as defined in the required interface FloatMode.

Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244694413, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNDI4TSBZZG667UTYB3V562CPANCNFSM6AAAAAAQJSBEI4. You are receiving this because you commented.Message ID: @.***>

RodneyBates commented 2 years ago

On 9/12/22 18:29, pwd96m4a wrote:

Anyway, who could tell me how to use the interface Sqrt mentioned there?

https://modula3.github.io/cm3/help/interfaces.html#math

https://modula3.github.io/cm3/help/gen_html/libm3/src/sqrt/Sqrt.ig.html

I'm sure with you there is no such thing as Sqrt.ig. Is the document outdated? Or it's for a different implementation of M3?

Here it is:

@.***:~/proj/m3/git-merge/cm3/master$ find . -name Sqrt.ig ./m3-libs/libm3/src/sqrt/Sqrt.ig

libm3/sqrt doesn't have any file whose names have "Sqrt" in it. There are only two files: FloatExtras.ig and FloatExtras.mg. Inside these files there is also no mention of "Sqrt" either.

Since the interface (from the extension it's generic interface), doesn't exists. So does it instantiated interfaces:

https://modula3.github.io/cm3/help/gen_html/libm3/derived/RealSqrt.i3.html

https://modula3.github.io/cm3/help/gen_html/libm3/derived/LongSqrt.i3.html

What kind of document is this? A document you can't trust! Wasted for me many days trying to figure out how to use it, always thinking that I must do sth wrong but the fact is it's simply the document that sucks and these interfaces just don't exists!

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244707840, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNEZ7TLHC5RNW7J4F2TV564ENANCNFSM6AAAAAAQJSBEI4. You are receiving this because you commented.Message ID: @.***>

VictorMiasnikov commented 2 years ago

What kind of document is this? A document you can't trust!

Ok... It looks like we have outdated "html documentation". How regenerate it?

13.09.2022, 17:43, "Rodney M. Bates" @.***>:

On 9/12/22 18:29, pwd96m4a wrote:

Anyway, who could tell me how to use the interface Sqrt mentioned there?

https://modula3.github.io/cm3/help/interfaces.html#math

https://modula3.github.io/cm3/help/gen_html/libm3/src/sqrt/Sqrt.ig.html

I'm sure with you there is no such thing as Sqrt.ig. Is the document outdated? Or it's for a different implementation of M3?

Here it is:

@.***:~/proj/m3/git-merge/cm3/master$ find . -name Sqrt.ig ./m3-libs/libm3/src/sqrt/Sqrt.ig

libm3/sqrt doesn't have any file whose names have "Sqrt" in it. There are only two files: FloatExtras.ig and FloatExtras.mg. Inside these files there is also no mention of "Sqrt" either.

Since the interface (from the extension it's generic interface), doesn't exists. So does it instantiated interfaces:

https://modula3.github.io/cm3/help/gen_html/libm3/derived/RealSqrt.i3.html

https://modula3.github.io/cm3/help/gen_html/libm3/derived/LongSqrt.i3.html

What kind of document is this? A document you can't trust! Wasted for me many days trying to figure out how to use it, always thinking that I must do sth wrong but the fact is it's simply the document that sucks and these interfaces just don't exists!

VictorMiasnikov commented 2 years ago

Small remark: INTEGER type don't equal LONGINT on AMD64_NT target.

} 13.09.2022, 10:47, "Mika Nyström" @.>: Thank for excellent post! It is very interesting. ( I'm on smartphone =} write small msg. -( ) 13.09.2022, 10:47, "Mika Nyström" @.>: VAL isn't "messed up". It just is what it is. And so yes you can convert between LONGINT and INTEGER. And you can write the code you're trying to write, and move on....

But a few comments to that:

  1. If you're looking for a "cast" in Modula-3, you're doing something wrong. You should think of, and use, Modula-3 as a "safe" language, like Java. (I'll address UNSAFE in a bit.) There are no "casts" in such a language. There are only checked type transfers. If you use it like that, you may come to understand what a brilliant design it is. Here's a language that runs directly on your machine (not inside a JVM) and gives you all the same safety guarantees that Java does, and higher performance, and a much richer type system (native records, enumerations, subranges..) in 50 pages of specification. Oh and powerful generics that aren't tied only to objects and classes. It's really pretty remarkable, especially for the era (M3 predates Java by a few years). Plus there has been very little spec churn. Since src-rr-52, only really LONGINT (see below). (Compare that to Java!)

  2. UNSAFE Modula-3: I consider this another language entirely. Again let's consider Java. Java can't be implemented in Java. Java can't be used to write a device driver. The small UNSAFE subset of Modula-3 allows you to do all this, including any unchecked type transfers or whatever you want to do. But it's not something you should be reaching for on a daily basis. (Unless these tasks are your main job.) Most regular applications don't require a single line of UNSAFE code (just like many applications can be coded just fine in Java).

In summary, if you think of Modula-3 as a friendlier, better Java, it comes out as an absolutely brilliant design, and an outstanding achievement. It has no equal that I know of. (I don't know anything much about Oberon, but I'm having dinner at ethz tonight as it happens.) Sorry if it breaks some Modula-2 idiom. But it's not intending to be backward compatible.

  1. LONGINT. There's almost no need to use this today unless it's in an interface you're interacting with. It was a stopgap measure to allow 32-bit machines easy access to large files. On a 64-bit machine, INTEGER is usually the same size! I was against the introduction of LONGINT at the time---I think the value of not changing the language spec would have outweighed the temporary utility of LONGINT. But clearly not everyone agreed, and it's done. Generally you can pretty much ignore it, though, except for the few times you have to uh seek in a file?

    Mika

On Tue, Sep 13, 2022, 3:08 AM jpgpng @.***> wrote:

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose:

https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

It seems you could use VAL to convert between LONGINT and INTEGER. But this usage of VAL is absurd. Modula 3 messed up the well known VAL of Modula 2!

VictorMiasnikov commented 2 years ago

"While I remember":

We have m2tom3. It's Modula-2 to Modula-3 converter. You can use it.

13.09.2022, 04:08, "jpgpng" @.***>:

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose: https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

It seems you could use VAL to convert between LONGINT and INTEGER. But this usage of VAL is absurd. Modula 3 messed up the well known VAL of Modula 2!

VictorMiasnikov commented 2 years ago

} On my cm3 build (mingw64 based) there is no Sqrt.i too.

I hope my cm3 5.19.X binaries has Sqrt() inside.

I will search inside .a files by HEX editor and(or) NC clone Far Manager 3.X

13.09.2022, 04:01, "jpgpng" @.***>:

That's a square-root implementation, all right. But why don't you just use Math.sqrt like a normal person? Not saying you have to, it's a real question. Math.sqrt gives you a double-precision square root of a double-precision number. The Sqrt thing computes square roots from first principles. It's not out of date or anything, but Math.sqrt is what you want if you want to take square roots (normally).

It seems it's really deprecated. On my cm3 build (mingw64 based) there is no Sqrt.i too. But it's there in the source tree: https://github.com/modula3/cm3/tree/master/m3-libs/libm3/src/sqrt So for some reasons, it was not build and included in my installation.

VictorMiasnikov commented 2 years ago

} Modula 3 and Oberon are GC-ed language

O. is "pure GC-ed language" ( may be)

But:

Modula-3 have both Garbage Collector POINTER(s) and UNTRACED POINTER(s).

And this is used in OS SPIN. ( or "did used (...) )

13.09.2022, 02:11, "jpgpng" @.***>: I do not agree that these functions are type casting functions. Type casting is only a by product of them. For example, you don't have anything to cast from LONGINT to INTEGER, don't you? There is also no functions to cast from LONGREAL to REAL. Because lack of type casting and also lack of method overloading, this is the reason why you used generics too much. Even a simple function like Sqrt has it own Sqrt interface and one has to instantiate it to the corresponding type, e.g: RealSqrt to only to use the function Sqrt on a REAL value. You think it as type safety and it's part of your language design, but people come from other languages (even Modula 2) will find it weird and overly complicated. Yes, M2 doesn't support method overloading either (so does C, M2 maps well to C and both are native language, Modula 3 and Oberon are GC-ed language), but M2 has type casting. M2 is very similar to C except doesn't have a powerful macros system like C.

RodneyBates commented 2 years ago

On 9/13/22 02:47, Mika Nyström wrote:

VAL isn't "messed up". It just is what it is. And so yes you can convert between LONGINT and INTEGER. And you can write the code you're trying to write, and move on....

But a few comments to that:

  1. If you're looking for a "cast" in Modula-3, you're doing something wrong. You should think of, and use, Modula-3 as a "safe" language, like Java. (I'll address UNSAFE in a bit.) There are no "casts" in such a language. There are only checked type transfers. If you use it like that, you may come to understand what a brilliant design it is. Here's a language that runs directly on your machine (not inside a JVM) and gives you all the same safety guarantees that Java does, and higher performance, and a much richer type system (native records, enumerations, subranges..) in 50 pages of specification. Oh and powerful generics that aren't tied only to objects and classes. It's really pretty remarkable, especially for the era (M3 predates Java by a few years). Plus there has been very little spec churn. Since src-rr-52, only really LONGINT (see below). (Compare that to Java!)

  2. UNSAFE Modula-3: I consider this another language entirely. Again let's consider Java. Java can't be implemented in Java. Java can't be used to write a device driver. The small UNSAFE subset of Modula-3 allows you to do all this, including any unchecked type transfers or whatever you want to do. But it's not something you should be reaching for on a daily basis. (Unless these tasks are your main job.) Most regular applications don't require a single line of UNSAFE code (just like many applications can be coded just fine in Java).

I often have a need to do just a few small UNSAFE things in code that overall, is not at all the kind that one would use UNSAFE for. An example is, I want to display a pointer value in hexadecimal as part of a dump of application-specific data structure.  I will create a separate interface/module pair, usually named UnsafeUtils, with tiny functions that do things like LOOPHOLE a pointer to an integer.  I keep the unsafe code to a bare minimum, relying on the safe subset for the majority of code.

In summary, if you think of Modula-3 as a friendlier, better Java, it comes out as an absolutely brilliant design, and an outstanding achievement. It has no equal that I know of. (I don't know anything much about Oberon, but I'm having dinner at ethz tonight as it happens.) Sorry if it breaks some Modula-2 idiom. But it's not intending to be backward compatible.

  1. LONGINT. There's almost no need to use this today unless it's in an interface you're interacting with. It was a stopgap measure to allow 32-bit machines easy access to large files. On a 64-bit machine, INTEGER is usually the same size! I was against the introduction of LONGINT at the time---I think the value of not changing the language spec would have outweighed the temporary utility of LONGINT. But clearly not everyone agreed, and it's done. Generally you can pretty much ignore it, though, except for the few times you have to uh seek in a file?

Mika

On Tue, Sep 13, 2022, 3:08 AM jpgpng @.***> wrote:

It seems VAL on Modula 3 is completely different than VAL on Modula 2 and it serves a very different purpose:

https://modula3.github.io/cm3/reference/complete/html/2_6_13Type_operations.html

It seems you could use VAL to convert between LONGINT and INTEGER. But this usage of VAL is absurd. Modula 3 messed up the well known VAL of Modula 2!

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1244767305, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKYNJO4AJVN2Z2GZLHKDPTV57H2NANCNFSM6AAAAAAQJSBEI4 . You are receiving this because you were mentioned.Message ID: @.***>

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1079#issuecomment-1245029188, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNAGJBYZUZECRC3AIW3V6AWSPANCNFSM6AAAAAAQJSBEI4. You are receiving this because you commented.Message ID: @.***>

RodneyBates commented 2 years ago

Just to avoid misunderstanding, INTEGER and LONGINT are never the same type, even when they have the same value range.  Nor are they mutually assignable.  So if you want that, you must code an explicit type conversion.

Because both types have arithmetic operators that produce new results from old ones, doing otherwise would open up a tangled web of rules about intermediate results, complicated to apply to get desired results, while invisible in the code.  Moreover, I suspect it would likely lead to abandoning Modula-3's principle that type analysis does not depend on where operation results are used.

In contrast, CHAR and WIDECHAR are mutually assignable, which produces no such problems, since there are no overloaded operators producing results of either type.

On 9/13/22 11:57, VictorMiasnikov wrote:

Small remark: INTEGER type don't equal LONGINT on AMD64_NT target.Thank for excellent post! It is very interesting.( I'm on smartphone =} write small msg. -( )13.09.2022, 10:47, "Mika Nyström" @.***>: VAL isn't "messed up". It just is what it is. And so yes you can convert between LONGINT and INTEGER. And you can write the code you're trying to write, and move on....

VictorMiasnikov commented 2 years ago

On 9/13/22 11:57, Victor Miasnikov wrote: Small remark: INTEGER type don't equal LONGINT on AMD64_NT target.

Just to avoid misunderstanding, INTEGER and LONGINT are never the same type

I think more about this:

--- .\64BITS\BasicCtypes.i3 Tue Apr 26 15:05:08 2022
+++ .\WIN64\BasicCtypes.i3  Wed Sep 14 12:05:59 2022
@@ -7,21 +7,21 @@

 INTERFACE BasicCtypes;

-IMPORT Word, Long;
+IMPORT Long;

 TYPE
   (* the four signed integer types *)
   signed_char        = [-16_7f-1 .. 16_7f];
   short_int          = [-16_7fff-1 .. 16_7fff];
   int                = [-16_7fffffff-1 .. 16_7fffffff];
-  long_int           = [-16_7fffffffffffffff -1  .. 16_7fffffffffffffff ];
+  long_int           = [-16_7fffffff-1 .. 16_7fffffff];
   long_long          = [-16_7fffffffffffffffL-1L .. 16_7fffffffffffffffL];

   (* the four unsigned integer types *)
   unsigned_char      = [16_0 .. 16_ff];
   unsigned_short_int = [16_0 .. 16_ffff];
   unsigned_int       = [16_0 .. 16_ffffffff];
-  unsigned_long_int  = Word.T;
+  unsigned_long_int  = [16_0 .. 16_ffffffff];
   unsigned_long_long = Long.T;

   (* the three floating types *)