Is this by design?
Hi @w32zhong !
For a quick fix, you can use
list = [1, 2, 3]
print(list.__str__())
print(list.__repr__())
For a longer answer:
So unfortunately this is a limitation from the compiler/language around what is called “conditional conformance”.
The function print expects its arguments to all implement the Writeable trait, however List does not implement Writeable. Why? If you look at the List struct, you’ll see that write_to (the required function for Writeable) is implemented - however the problem is this function is only enabled when T (the type that List holds), implements Representable.
We need some way in the language to express:
struct List[T: AnyType](
Writeable if T implements Representable,
# ...
)
This however is not possible ATM - but it is something we hope to have in the language soon!
Wait. Maybe I am still unfamiliar with the relevant knowledge to grasp the reason here.
I checked the docs: List | Modular
The List.__str__ also requires the list element to be “Representable”:
__str__[U: Representable & Copyable & Movable, //](self: List[U]) -> String
So why
print(list.__str__())
is okay then?
Why not just add Writable trait to the List? Because this won’t pass the compile-time check?
Since Writeable requires the write_to method and the current definition of it for List looks like this:
fn write_to[
U: Representable & Copyable & Movable, //
](self: List[U, *_], mut writer: Some[Writer]):
...
Meaning the write_to method only exists for a List who’s contained type implement Representable → and not every type implements Representable.
This is okay because you’re directly calling the __str__ function from the List and not through the Stringable trait.
In your specific case, this is okay because [1, 2, 3] is a List[Int] and the Int type implements Representable.
Thanks for this detailed explanation!
I see the point that the trait constraint is compile-time, but calling list.__str__() is dynamic type binding. Please let me know if this understanding is incorrect.
Pretty much! Though one small thing: calling __str__() isn’t dynamic since the function is known by the compiler so its fully static in the sense there is no runtime overhead of needing to do a v-table lookup ![]()
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.
