-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make /
be float division
#2968
Comments
Hello, Is a new operator very efficient against a cast (to_f64) ?
|
Of course I agree on changing, keeping an ambiguous division causes lots of headaches. I've seen people struggling with results and then finding out that in that language. I'm sure that division related bugs are everywhere and I think this is the way to avoid them. If performance is needed => // @Nephos, I think crystal will be better than ruby, but it needs the "right" division :P Here are the reasons (in the context of python): https://www.python.org/dev/peps/pep-0238/. @asterite, Thanks you for opening the discussion |
In crystal the user can have fine control of the numerical types. But when receiving just a number, might not be clear. Having / to be floating point division, and // been the floor of the division would mean to have a unified semantic of the operation despite the numerical types. This favor more concistency IMO. As for the type, Float64 by default sounds reasonable, unless Float32 is involved and no Float64. I think that will honor f32 operations for when the user cares. |
You mean something like:?
|
I think the PEP has one very good reason to do this: def average(elements)
elements.sum / elements.size
end The average should be a float, but this might give an integer back. We can solve this using def average(elements)
elements.sum.fdiv(elements.size)
end So right now we have:
I think that's the main problem: that
I was initially against this change, but @pbrusco insisted so much I decided to open an issue. After considering it for a while I'm starting to like it. But then I thought "Hm, I'm sure this will break a lot of code, as In summary, "floor division" is needed, but there's no reason to have So now I'm very open to make this change :-) |
I never heard of |
Python, Elm and Lua have this operator. Additionally, Visual Basic has it as a backslash. We could choose another character combination, maybe |
As I remember (it's been decades...) pascal used |
Haha, there it was, VB. |
This is not a good thing to me. In Ruby, someone making the mistake when using However, adding a method |
I'm +100 on this. Implicit integer division should die a slow, painful death. I cannot count how many times bugs related to this have screwed me over in C++. |
@ozra
|
For dynamically typed languages it's just silly to have integer division as |
@bcardiff - OK: so F32 return also for F32 on RHS, when not F64 on LHS. |
Vote for not to change. Now we have
And if we do this change, IMO, If we want to divide and get the float, we can just do |
There's a third possibility to remove the inconsistency that's not been mentioned yet and I'm not sure I like it too much either, but it should be on the table for completeness. As it has been said
Now it has also been pointed out that while |
@jhass, yes, the Pascal way :-) |
@david50407 I don't see "divide to Float32" and "divide to Float64" as semantically different operations. There is a precision difference for sure, but is the same as other maths operators. Due to polymorphism and overloads we can support different methods for the same message, but whenever we do this it should be semantically painless for the user. I don't mind if I think that differentiating this operation will bring less errors in the code. The other maths operators are more safe because (unless overflow/underflow) you end up in the same type of numbers. That is what I try to honor with the overload I propose. |
@david50407 The most common division is float division, not floor division. |
@asterite will the new symbol for floor division be a method (can be defined manually by BTW, how about |
Do we really need a new operator? I think |
@david50407 It'll be a new method, similar to other operators, so you could define it in @jhass And although we don't necessarily need a new operator for this, integer division is still very common and it would be tedious to write |
I vote for the change. This change would help those playing scientific computing. For simplicity, I always prefer to write About the second concern of @asterite , In the world where (x : Any) /= Any # => x : Float
(x : Any) //= Any # => x : Int |
+1, in my experience I hardly ever required a floor division, and if I did I'd probably take extra care on the method used to obtain it; imho the pros outweigh the cons. |
I hope the choice of |
I actually implemented this in a branch and tried it out and kind of disliked it... it's like, I'm using integers, I want to divide it by two and I'm forced to use I think it makes more sense in languages like Haskell and Elm where they use Hindley-Minler type inference that deduces things from functions and operators (so in I'll still leave this issue open because the change might happen, I'm just not as convinced as before... |
I'm not sure about this. It seems nice but there are valid concerns. Is the result really worth it? However, I don't see a problem with supporting multiple versions. This requires only a small compiler change and partial adaptation could be split across two or three releases. It should be possible to ensure the code always works with two different compiler versions. |
There is also the option of returing a BigRational, like Perl6 does. |
FWIW, from my perspective, when I use it, I almost never "want" "/" to be
an integer division, since that "loses information" (the remainder). I
always have to remember "I have to cooerce one side or the other to a float
like 1/3.0" or "a/b.to_f" which is painful. Defaulting to float would be
different than Ruby (in a good way IMO) but of course the transition would
be painful (but possibly worth it). I'd be interested in trying it.
Another possibility: maybe could introduce // as an "always to rational"
operation? ... just my $0.02
…On Wed, Jun 27, 2018 at 4:50 AM, Chris Hobbs ***@***.***> wrote:
@straight-shoota <https://github.com/straight-shoota> I don't see how
it'd be possible to make it work unless we migrated *everyone* away from
using / and then back to / again once it changed
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2968 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAw0OEqKzyVlJzOaoXgCXEqoP1meoSIks5uA2OGgaJpZM4JHczg>
.
|
These above are all just guesses. If we change
Believe, I already implemented this feature but never pushed the code. When I did it, you would get compile errors on incorrect usage, and it would work on existing float divisions. There will not be silent errors introduced by this change. Relax :-) |
Oh no… what's next? The I love Ruby language for a small amount of special characters — it's closer to natural language. I could guess about But I saw the comment from @asterite :
But I just don't want to leave it without my opinion (and not only mine, judging by this thread). |
FWIW I noticed that elixir uses "/" for floating point divide and "#div" for integer divide... :) |
The release note of 0.28.0(https://crystal-lang.org/2019/04/17/crystal-0.28.0-released.html) says that a breaking change about |
Ref #8120 |
After reading this thread, one thing that was not mentioned was Real world use case (if you don't believe me): Before #8120:
Works perfect. Output:
After:
Output:
Now, after creating these examples a new problem arose. Local/temp variables will be converted into unions just to match the A lot of potential problems will come to fruition over this change, because |
Just use |
@Gring just use // where you previously used /. It's a really simple change. In fact you can blindly solve compile error from upgrading the crystal version by replacing / with // where the compiler complains. |
Crystal is a statically typed language. In my example, the ivars/variables are explicitly set to a type. Why is that type changing? It just doesn't make sense to me. Something is not right
This does not happen with Ruby. If this stays, I urge the developers to please, PLEASE mention this somewhere in GitBook/docs/wherever so new developers know in advance. That's all I ask, thank you |
The type of your variable isn't changing, when you do a / b you're
basically calling a function and using the output value.
FWIW Python's done this same thing with division for years, it's not nearly
as bizarre or surprising as you might think.
…On Sun, Oct 6, 2019, 9:21 AM girng ***@***.***> wrote:
Crystal is a statically typed language. Our ivars/variables are explicitly
set to a type. Why is that type changing? It just doesn't make sense to me.
Something is not right
Crystal’s syntax is *heavily inspired by Ruby’s*, so it feels natural to
read and easy to write, and has the added benefit of a lower learning curve
for experienced Ruby devs.
This does not happen with Ruby.
If this stays, I urge the developers to please, PLEASE mention this
somewhere in GitBook/docs/wherever so new developers know in advance.
That's all I ask, thank you
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2968?email_source=notifications&email_token=AAM4YSK2PP5EKVSFMRVHVZ3QNHX7JA5CNFSM4CI5ZTQKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAOLGLY#issuecomment-538751791>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAM4YSPR6C66GY23YBV2XNDQNHX7JANCNFSM4CI5ZTQA>
.
|
|
Could you please answer why can't you use // in your example? |
"Why are you spelling Conventions and history of an operator are super important, especially in this case because I bet a lot of new devs coming to Crystal have a Ruby background (and expect Why Crystal?
lol see what I mean? |
I vote favor of // Crystal is not replacement of ruby or c |
Note: p 3.tdiv 2 #=> 1
p 3.fdiv 2 #=> 1.5 The @girng, have you a proposal for integer, division, I guess In fact, the question is either if Crystal is more newbie-friendly or pro-friendly. |
My argument is, the language should not convert our types in the background. If a developer wants a Even if you don't agree, objectively speaking, changing of types should ALWAYS be initiated by the developer. There should not be any "magic" that converts types in the background. See my example above, this is just a recipe for disaster |
But it doesn't convert any types, as I said str = 'a'
str += "b" if str
p str #=> "ab"
p typeof(str) #=> (Char | String) |
I don't want to argue because when I do, I become really rude and you guys are very friendly and helpful so it would be out of line. I will leave it at that and stand by my previous posts |
@girng when you do 1.fdiv(2) you get a Float64. That's not different than / doing now the same thing. In fact in Ruby you have to use fdiv for float division. In Crystal we chose to have two different operators. |
In ruby:
Output:
|
Similar to Python 3, we could have
/
return a float, and add another operator, maybe//
(though that means an empty regex right now, but we could alternatively use%r()
for that).So:
I'm not 100% sure about this, mainly because:
Float64
?x /= 2
changes the type ofx
, while previously it doesn't, but one could usex //= 2
nowI'm cc-ing @pbrusco because he originally proposed this :-)
Thoughts?
The text was updated successfully, but these errors were encountered: