Julia: Revise `zero` and define `zerounit`?

Created on 30 Nov 2017  路  13Comments  路  Source: JuliaLang/julia

We may want to revise zero to match how one works. This would also mean we would need to create a zerounit.

julia> using Dates

julia> one(Minute)
1

julia> oneunit(Minute)
1 minute

julia> zero(Minute)
0 minutes

julia> zerounit(Minute)
ERROR: UndefVarError: zerounit not defined

Most helpful comment

But zero should be the additive identity, so zero == zerounit, right? So (if anything) it is the zeronounit function that is missing.

All 13 comments

Related: #24595 :).

But zero should be the additive identity, so zero == zerounit, right? So (if anything) it is the zeronounit function that is missing.

You can always do zero(one(T)) if you want zero without units, but this is not an additive identity for T.

The asymmetry and minor ambiguity in one/oneunit and ?/zero supports the symmetric pairs onemul/oneadd and zeromul/zeroadd discussed previously. No ambiguity or inconsistency of any kind there :). Best!

I was mainly noting the style inconsistency. My ideal world would have Dates.Minute(0) == 0 be true

(Partly summarising from slack:)

Note that one does not always exist when zero does, so zero(one(T)) is not a full solution. But a unitless zero cannot be multiplied or added to unitful quantities, so it is hard to come up with examples where this would be needed. After a long time I came up with the first situation where I actually did.
In this case to get a unitless white noise vector, which is to be scaled with a unitful scale. Because the scale carries a unit, the white noise vector, shouldn't. This could be conveniently written as randn!(zeronounit(x)). Perhaps the only case.

Post scriptum: I think this could be closed in favour of #22216

Note that one does not always exist when zero does, so zero(one(T)) is not a full solution.

But a "unitless" zero is only meaningful when you have multiplication, in which case you should have one, no?

This is not related to units, but from a purely abstract point of view:

  • zero(x) is the identity element under the operator +.
  • one(x) is the identity element under the operator *.
  • oneunit(x) is the generative element under the operator +.
  • zeronounit(x) would be the absorbing element under the operator *.

Assuming one(x) exists, zero(one(x)) would be synonymous with zeronounit(x). However, it is not at all inconceivable that an identity element under multiplication would not exist for an arbitrarily defined object, while the absorbing element would. For instance, numbers on the interval [0, 1) that only allow multiplication onto themselves.

I do not think zeronounit is a good name for the absorbing element, though.

I would differentiate that zeronounit may be an ugly name, but would be a good name in so far that this is the name different people came up independently when running into this.

Assuming one(x) exists, zero(one(x)) would be synonymous with zeronounit(x).

I don't think that theorem is true. Try with a Float64. hint The absorbing element for Float64s under * isn't 0.0.

The absorbing element for Float64s under * isn't 0.0.

0.0 also isn't the additive identity for Float64, technically.

If I can ask a concrete-algebra question, what would you do with the absorbing element of a type? I can only imagine using it to multiply an instance of the type.

y = zeronounit(x) * x

but in that case you might as well just do

y = zero(x)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

manor picture manor  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments

sbromberger picture sbromberger  路  3Comments

wilburtownsend picture wilburtownsend  路  3Comments

dpsanders picture dpsanders  路  3Comments