I would like that strings can be assigned directly to seq[uint8], as a cstring generally is a valid uint8 sequence.
Something like
var s: seq[uint8]
s = seq[uint8]("Text data for proc with uint8 based parameters".cstring)
The actual fact is, that we have some gtk procs that gets a utf8 array, that is a pointer to first utf8 char and an length argument. In earlier gintro releases I used a faked cstring for this, which is ok in most cases, but maybe not in all, as uint8 array can contain binary zero multiple times.
The basic API design was that the high level proc got a string and passed cstring and length to C lib. Now the correct high level API get a seq[uint8] and passes addr of first entry and length to C lib. That should be fine, but it is unconvenient for the user, as he can not simple pass a string.
I think one solution may be, that I make the parameter of the high level API an or type, this is "s: seq[uint8] or string". Then the low level code remains identical, as both arguments have addr(s[0]) and s.len.
But general, a pure assign of string to seq[uint8] may be useful generally, maybe a plain cast may even work, but I newer would use that.
converter toSeqUint8(s: string): seq[uint8] = cast[seq[uint8]](s)
let s: seq[uint8] = "test"
doAssert s == @[116'u8, 101, 115, 116]
From a type-safety point of view, I think such a conversion should not be the default, while string, seq[byte], seq[uint8] and Taintedstring are all equivalent at a low-level, they should represented completely different semantics.
Implicit conversion should be left at the library developer/end-user discretion, just like Nim doesn't automatically convert integer to bool and allow if 0:.
As shown by @SolitudeSF example and the lenientops module, it's easy to get relaxed semantics for a specific library or domain that requires them.
OK, so a cast does indeed work, and lenientops may also support it (will visit that module soon) but a plain safe type conversion does not work? Strange -- is that just because no one had the time to implement the type conversion yet?
A cast is too unsafe of course, no one can guarantee that Nim compilers from other companies or Nim 4.0 will have compatible binary layout. For lenientops, I guess when I import whole module, I will get all the relaxed math also, which may be not desired. Maybe I can import only seq to string conversion, will investigate that later.
what I meant by lenientops is that it's better to have strong default in system.nim and that extra libraries like lenientops would be better to introduce unsafe auto-conversion between types.
To be clear, lenientops only does conversions for numerical operators at the moment. The safe conversion would be a for loop on the result and source:
for i in src.len:
result[i] = uint8(src[i])
Otherwise anything else relies on the implicit representation being the same either at container+data level (casting the string to seq[uint8]) or at data level (using copyMem).