In fact, I consider it a bug in the compiler that the following doesn't work:
proc button*[W, H: UILength = UIAbsLength](self: UISystem,
buttonLabel = none(string),
width = W(0.0),
height = H(0.0)) =
when width is UIAbsLength:
echo "width is Abs!", cast[float32](width)
else:
echo "height is Abs!", cast[float32](width)
And here is why: UILength is a generic type consisting only of finite number of
types. It means it's even entirely possible to check every time for
compilability of W(0.0) and H(0.0). But still, Nim uses lazy instantiation and
compile-time duck typing. Which means it should, as a rule, accept any
constructors I give it unless I try to instantiate the proc and break it by
trying to use constructors not in existence. And I think so because the
following works as expected:
proc button*[W, H: UILength](self: UISystem,
buttonLabel = none(string),
width: W, height: H) =
let x = W(0.0)
let y = H(0.0)
So all in all: Nim makes some inconsistencies between declarations and
definitions.
Btw. oh, how much I miss Rust's where... It's a true beautifier of generic
signatures...