| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#11
| |||
| |||
| On Sun, Aug 31, 2008 at 9:58 PM, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: >> If you use hardware-supported 32-bit representation of floats then >> there will be a problem with precision. Some Int values cannot not be >> precisely represented as floats. > > That is up to inherited operations. Basically, if Integer inherits > anything from Float it also does the property of Float being an > interval of [real] numbers, with the consequences of. If Integer can > do this operation better, then it should override. The third > alternative is adding ideal values to the class in the form of NaN or > else an exception propagation. > Sorry, I still don't get how the inheritance thing alone could automagically resolve all the subtle numeric issues. Suppose we have a method that simply returns the sum of two args: m(a, b) { return a + b; } I could understand what happens If both args have the same type. For instance if ints and floats both use 32-bit representation then m(1, 2000000000) will quite obviously result in 2000000001 while m(1.0, 2000000000,0) will result in 2000000000.0 - 32-bit floats do not have enough precision to keep the '1' in the end. Now what will happen if one argument is int and another is float ? m(1, 2000000000.0) will it be 2000000001, or 2000000000,0, or a runtime error? In any case the user might prefer one way or another. In the last example if the user wants to preserve the precision then this could be done by converting float to int. On the other hand for m(1, 1.0e15) conversion to int will not work so it should not be done. So do you reserve the possibility for a user to do the explicit conversion? Or never is never and explicit conversion is always a design problem? Regards, Aleksey |
|
#12
| |||
| |||
| On Tue, 2 Sep 2008 00:54:12 +0700, Aleksey Demakov wrote: > On Sun, Aug 31, 2008 at 9:58 PM, Dmitry A. Kazakov > <mailbox@dmitry-kazakov.de> wrote: >>> If you use hardware-supported 32-bit representation of floats then >>> there will be a problem with precision. Some Int values cannot not be >>> precisely represented as floats. >> >> That is up to inherited operations. Basically, if Integer inherits >> anything from Float it also does the property of Float being an >> interval of [real] numbers, with the consequences of. If Integer can >> do this operation better, then it should override. The third >> alternative is adding ideal values to the class in the form of NaN or >> else an exception propagation. > > Sorry, I still don't get how the inheritance thing alone could > automagically resolve all the subtle numeric issues. It cannot. But the question was about shared vs separate representations, which is not a numerical issue. > Suppose we have a method that simply returns the sum of two args: > > m(a, b) { return a + b; } First of all, this is not a specification of the method. The types of the arguments and of the result are unspecified, as well as the covariance of. So one cannot tell which combinations of arguments and result types are involved. > I could understand what happens If both args have the same type. > For instance if ints and floats both use 32-bit representation then > > m(1, 2000000000) > > will quite obviously result in 2000000001 > > while > > m(1.0, 2000000000,0) > > will result in 2000000000.0 - 32-bit floats do not have enough > precision to keep the '1' in the end. > > Now what will happen if one argument is int and another > is float ? > > m(1, 2000000000.0) That depends on how the question above is answered and of course on the semantics of m. Note that the language is not to specify the semantics of m. As for multimethods, yes there are six combinations of 3 (2 arguments + 1 result) x 2 types. The semantics of m shall unambiguously define all six. But again it is not the language business, except for the predefined operations of course. The language shall merely allow an implementation of the desired semantics for all combinations in question. > will it be 2000000001, or 2000000000,0, or a runtime error? > > In any case the user might prefer one way or another. In > the last example if the user wants to preserve the precision > then this could be done by converting float to int. On the > other hand for m(1, 1.0e15) conversion to int will not work > so it should not be done. The result is involved, provided that m is covariant, or else when Float is the ancestor of Integer and the result is contravariant. As for the semantics (numerical value of the result), see above. > So do you reserve the possibility for a user to do the explicit > conversion? Certainly yes. An explicit conversion is merely a subprogram. But I would also allow user-defined ad-hoc subtypes, so that one could tie two originally independent hierarchies. > Or never is never and explicit conversion is always > a design problem? Close to that. When I analyse the cases where I used conversions, most of them liked suspicious or else were introduced by language limitations. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de |
|
#13
| |||
| |||
| I think we're all getting a bit ahead of ourselfs. The thing is I specify what type gets to be cast and when. The default to 100.0 + 1 would be 101.0, so as you see with flaot and int operation the default type is float. If a programmer wants the operation done in a different way, the person can do: a = 100.0 b = 1; s = "string text"; c = a.ToInt() + b; or c = (int)a + b; or c = a.To(int) + b; d = s + a; // d == "string text100.0" If you don't like the float I can make it double or even long double. That really doesn't matter right now. I'll get to that while implementing operators in the VM. And please do remember that this is meant to be a scripting language with dynamic typing, running on a VM. The will be no low level magic, machine code generation. Just bytecode stuff. If you ever read the PHP or Lua manual you should know what kind of predefined types exist there, what are there limitations and how operators react given certain types. Without operator overloading ClassA + ClassB will always print an error 'cannot do something with this...'. The thing is I just wanted to ask about general preferences when it comes to the syntax. Also I'm interested if anyone can see any penalties when it comes to the per block vs global/local scopes. Maybe performace or any other problems. These are my problems as for now, leave the conversion problem alone As I said earlier it WILL bepredefined so that the user knows what to expect and when. |
|
#14
| |||
| |||
| On Sep 4, 1:59 pm, lican <lica...@gmail.com> wrote: > a = 100.0 > s = "string text"; > d = s + a; // d == "string text100.0" Personally, I'd prefer a different operator for string concatenations (like D's "~"). That way you can prevent the following code from misbehaving: print("The round is: " + round + 1); Instead of calculating round + 1 first, round is translated into a string and 1 is translated into a string, which obviously gives wrong results. Of course one can put parentheses around round + 1, but this kind of bug is pretty much a newbie-trap and this can be avoided with: print("The round is: " ~ round + 1); Just make the priority of ~ low enough that it is called last before = and everything should sort itself out. |
|
#15
| |||
| |||
| On Wed, Sep 3, 2008 at 12:22 AM, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > On Tue, 2 Sep 2008 00:54:12 +0700, Aleksey Demakov wrote: >> Suppose we have a method that simply returns the sum of two args: >> >> m(a, b) { return a + b; } > > First of all, this is not a specification of the method. The types of the > arguments and of the result are unspecified, as well as the covariance of. > So one cannot tell which combinations of arguments and result types are > involved. > We were talking in the context of a scripting language. If you notice the variables in this language are declared as "var a = 5;". No type tag whatsoever. I don't see a reason why for such a language parameters are to be declared with the type tag. But if you wish I could write the method definition like this: Float m(Float a, Float b) { return a + b; } > As for multimethods, yes there are six combinations of 3 (2 arguments + 1 > result) x 2 types. The semantics of m shall unambiguously define all six. > But again it is not the language business, except for the predefined > operations of course. The language shall merely allow an implementation of > the desired semantics for all combinations in question. > What do multimethods have to do with this? You say that a language "with an elaborated types system" should make integer a subtype of float. My understanding of subtyping is that a subtype might go anywhere the supertype could go. I conclude that there is no need for any 6 combinations. The method defined for float arguments should somehow handle int arguments too. > The result is involved, provided that m is covariant, or else when Float is > the ancestor of Integer and the result is contravariant. As for the > semantics (numerical value of the result), see above. > I don't get what "covariant" or "contravariant" mean. I asked a simple question. Please tell me what a language "with an elaborated types system" will do for m(1, 2000000000,0) . Regards, Aleksey |
|
#16
| |||
| |||
| lican <licaner@gmail.com> writes: > If you don't like the float I can make it double or even long double. > That really doesn't matter right now. I'll get to that while > implementing operators in the VM. > > And please do remember that this is meant to be a scripting language > with dynamic typing, running on a VM. Does "scripting language" mean "efficiency does not matter much"? If so, then why bother with floating point? Why not use exact rational arithmetic instead? - Bob |
|
#17
| |||
| |||
| On Sun, 7 Sep 2008 00:02:32 +0700, Aleksey Demakov wrote: > On Wed, Sep 3, 2008 at 12:22 AM, Dmitry A. Kazakov > <mailbox@dmitry-kazakov.de> wrote: >> On Tue, 2 Sep 2008 00:54:12 +0700, Aleksey Demakov wrote: >>> Suppose we have a method that simply returns the sum of two args: >>> >>> m(a, b) { return a + b; } >> >> First of all, this is not a specification of the method. The types of the >> arguments and of the result are unspecified, as well as the covariance of. >> So one cannot tell which combinations of arguments and result types are >> involved. > > We were talking in the context of a scripting language. If you notice > the variables in this language are declared as "var a = 5;". No type > tag whatsoever. The language is typed, thus a must have a type. Whether that type is manifested in the declaration or else inferred from the type of the initializing expression is no matter. > I don't see a reason why for such a language > parameters are to be declared with the type tag. But if you wish I > could write the method definition like this: > > Float m(Float a, Float b) { return a + b; } You should also define covariance. When Integer is derived from Float which parameters (arguments and the result) become Integer and which are not. In other words in which parameters m is a method of Float. Method = covariant. >> As for multimethods, yes there are six combinations of 3 (2 arguments + 1 >> result) x 2 types. The semantics of m shall unambiguously define all six. >> But again it is not the language business, except for the predefined >> operations of course. The language shall merely allow an implementation of >> the desired semantics for all combinations in question. > > What do multimethods have to do with this? You say that a language > "with an elaborated types system" should make integer a subtype > of float. My understanding of subtyping is that a subtype might go > anywhere the supertype could go. Right, but this does not mean that you can pass Integer where Float is expected. That is a type error. Substitutability is achieved: 1. by introducing new instances of polymorphic m. For example, when m is a method in the argument a, that means that m is defined on the class Float and for each type from the class there exists an instance of m with a of this type: .... m (Float a, ...); .... m (Integer a, ...); When Integer inherits m without overriding, then .... m (Integer a, ...); is defined as a composition of Float m and a conversion from Integer to Float. 2. by using operations defined on the whole class. > I conclude that there is no need for > any 6 combinations. The method defined for float arguments should > somehow handle int arguments too. They cannot, it were untyped. It must be either 1 or 2. You have to choose what case m represents in which parameter. >> The result is involved, provided that m is covariant, or else when Float is >> the ancestor of Integer and the result is contravariant. As for the >> semantics (numerical value of the result), see above. > > I don't get what "covariant" or "contravariant" mean. See above. Covariant = method, which is inherited and can be overridden. > I asked a simple > question. Please tell me what a language "with an elaborated types > system" will do for m(1, 2000000000,0) . I will allow the user to define the semantics of above in accordance with the meaning of m. I don't know what m is supposed to do. Does it model addition? In R? N? C? Again, the point is that if m is a method in all arguments and the result then overriding it gives you an opportunity to implement any semantics you want: Integer m (Integer a, Float b) { ... } // When integer expected Float m (Integer a, Float b) { ... } // When float expected -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de |
|
#18
| |||
| |||
| On Sat, Sep 6, 2008 at 2:02 PM, Aleksey Demakov <ademakov@gmail.com> wrote: > > I don't get what "covariant" or "contravariant" mean. I asked a simple > question. Please tell me what a language "with an elaborated types > system" will do for m(1, 2000000000,0) . > Type Theory Discussions always get a bit dense. Discussions of what covariant and contravariant mean are better treated in books. If you like to get deeper into the subject you should check this book Benjamin C. Pierce The MIT Press Types and Programming Languages This book requires some mathematical background in order to be read. IMO it should give you a great introduction to type theory. With repect to > Now what will happen if one argument is int and another > is float ? > > m(1, 2000000000.0) > > will it be 2000000001, or 2000000000,0, or a runtime error? if types are evaluated at runtime the result i would expect it to return the most restrictive type capable of holding the result, in this case an integer (2000000001). Otherwise i would expect it to return float. A Runtime error would not be prudent if you are using IEEE 754 floating point arithmetic. If an overflow occurred you would have +Inf as result (I think) and of course you could check this value to see if and overflow has taken place indeed. I hope I was useful. Regards, Felipe |
|
#19
| |||
| |||
| : I don't get what "covariant" or "contravariant" mean. There is some info on Wikipedia: http://en.wikipedia.org/wiki/Covaria...mputer_science) |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.