-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Introduce UInt1
type to replace misuse of Bool
#18367
Comments
If we decide to commit to |
|
Here's an example: |
Then in the interest of maintaining as much type stability as possible, wouldn't it make more sense to continue to error on |
|
Am I understand this right? I suspect making
However this is probably bad. I am in-favor of breaking lots of code, to get the language right, prior to hitting v1.0 |
@ararslan I cannot stress enough that |
@oxinabox I propose that To calculate the accuracy of a binary classifier, you can just convert the |
For @oxinabox's specific case there, you can pass a function/type constructor as the first argument to |
+1 for I also kind-of like having
I assume that is meant to be a zero, not a one. We could specialize (As an aside, in other contexts I've also been wanting a singleton |
@TotalVerb, the problem is that This is why |
Maybe this plays nicer with my suggestion of |
@andyferris, honestly, it seems like an opaque |
How often does one take the sum of non-numbers? Nobody is actually writing |
I would venture a guess that it's rather common amongst people coming to Julia from R. That said, I don't think I think another important question we should ask is: how often does one take the sum of If |
@tkelman, it's not that uncommon to sum arrays of arrays of numbers, for example. And note that we throw an error for Giving something that is definitely wrong 5% of the time is worse than giving an error 100% of the time, in my opinion. @ararslan, Julia is a still a dynamic language. In many other contexts, we allow objects of type |
Anyway, this discussion is a bit derailed. Whether a |
@stevengj It is precisely because all those are closed that I'm discussing this here. Furthermore, I'm reminded of julia> map(() -> 2)
2 which is a generalization to the empty case that has a similar objection—it is an incorrect generalization in some cases; perhaps I would have expected |
Also, I disagree that this discussion is irrelevant to |
A naïve implementation of the immutable Flatten
xs
end
length(itr::Flatten) = sum(length, itr.xs) # seems reasonable enough? Then |
The |
I disagree that it is very different. It is just as conceivable to imagine |
I'm not convinced that we need or want |
But we need a type that can be promoted upward to any other type. Currently we're using |
What do we need it for? There's not a lot of use cases that aren't inherently type unstable. |
For instance, |
Yeah, I'm not entirely sure those are a good idea anymore. Having an |
I disagree. Should we have three |
Also, even with an |
I spend the last day writing a function in LLVM IR that operates on 2bits (packed in 64bits). This meant working with |
I am experimenting right now with relaxing the requirement on |
It's not necessary to change how My motivation there was to test algorithms that use integers while being able to test the algorithms for all possible inputs. Using integers with fewer bits makes it easier (faster) to iterate over all of them, especially if an algorithm expects multiple arguments. |
(Apologies for not remembering that I already implemented a |
Notwithstanding the technical points that have been raised, I think the big conceptual issue remains: Is a If a I think it would be preferable to have numeric types and logical types treated rather distinctly, e.g. to deprecate support of arithmetic operators ( |
I agree with most of your points. But Also, I really think GF(2) is too important to leave out of |
@TotalVerb Yes, I agree that GF(2) is very important and should be provided in the standard distribution. But the question is, should this be the default behavior of Bools? I think both An approach I think would be satisfactory for most people would be the following: Have the standard distribution come with two modules, with descriptive names such as |
I oppose the idea of having two different modules. |
@TotalVerb I agree that having a sensible default would be preferable, provided it doesn't cause confusion or make it too awkward to achieve the other behavior when desired. Especially in this case, since both behaviors seem about equally reasonable and useful. As someone fairly new to Julia, I can think of only four ways to support both behaviors:
Each option has its advantages and disadvantages, but 1 and 4 seem to me to be the least undesirable. |
My opinion is that any time you have two sensible behaviours for a type, and are tempted to allow the user to choose behaviour, then that type is a type-pun: it's serving the purpose of two types. Hence I'm more comfortable with option 3. |
That's a fair point. So, suppose there is a boolean type for GF(2) arithmetic. Then would it be useful to have a second type for "regular" arithmetic, if it just ends up getting promoting in most operations? Or even a third type with logical (as opposed to algebraic) semantics? |
What about zero(::Type{Any}) = UInt1(0)*I
one(::Type{Any}) = UInt1(1)*I That is return a |
@dlfivefifty, |
Right, but it will support the most common case of |
I guess only square Matrices as |
I think it's safe to say we decided not to do this for v1.0 |
This will solve a whole bunch of problems.
UInt1
is a lot more intuitive thanBool
as a identity element forpromote_type
.true + true === 2
won't be inconsistent with every other unsigned type; we can haveUInt1(1) + UInt1(1) === UInt1(0)
as expected.Bool
can be made non-numeric. (cc @StefanKarpinski)I think the current system is really not ideal; it's worse than a method pun: it's punning a type for two very different things.
The text was updated successfully, but these errors were encountered: