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...