Define a UnitPoint{<:Real} parametric struct type which has x and y fields of type T and which has an inner constructor that normalizes its arguments by diving them by hypot(x, y) upon construction, guaranteeing that the resulting point is on the unit circle.
my attempt below (it’s called UnitPoint3 because the previous attempts seems to prevent me from redefining a struct, so anyone who knows how to redefine a struct can lend a hand thanks).
struct UnitPoint3{T<:Real}
x :: T
y :: T
function UnitPoint3(x::T,y::T)
distance = hypot(x,y)
return new(x / distance, y / distance)
end
end
Now this code gave an error syntax: too few type parameters specified in "new{...}"
How should I fix this? Is there a more step by step intro to the type system?
struct UnitPoint3{T<:Real}
x :: T
y :: T
function UnitPoint3{T}(x,y) where {T<:Real}
distance = hypot(x,y)
return new(x / distance, y / distance)
end
end
That version of the introductory materials is a brand new iteration of the content, and we’re still working on improving them. Indeed some of the exercises are far too difficult without more description. Sorry you got tripped up by it! @ffevotte’s solution is a good one.
Just to answer your other question: it’s unfortunately not possible to redefine a struct. You can re-evaluate it as long as you don’t change it significantly, but of course as you’re trying different things of course you want to significantly change the definition. The workaround you found (just iteratively changing names) is one I’ve used in the past — once I get a form I like I just rename everything back to the name I originally wanted and restart. Another workaround is to use modules since they can be replaced, but that can get tricky fast as you can end up with objects that are still the old type but have (what looks to be) the same name.
I tried your solution and indeed it worked for UnitPoint3{Float64}(1,1), but it errored when I tried UnitPoint3{Int64}(1,1) with a message InexactError: Int64(Int64, 0.7071067811865475)
if this is the intended behavior, then wouldn’t this parameterization limit the struct rather than make it more general?
function unitized(x::T, y::T) where {T<:Real}
h = hypot(x, y)
return x/h, y/h
end
struct UnitPoint{T<:Real}
x::T
y::T
function UnitPoint(x::T, y::T) where {T<:Real}
ux, uy = unitized(x, y)
return new{float(T)}(ux, uy)
end
end