-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Currently, stringref is the main entry point of all string creations and related high level methods. On the other side, there is a bunch of specialized functions in the views. Once you have a view instance you cannot go back to stringref so one needs to keep stringref as the main reference to carry around. With that every specialized operation requires calling a view creation function to get the view and then calling the function on them like get_codeunit.
I found this setup quite odd and asked why we don't simply have 2 types; string_wtf8 and string_wtf16 with conversion functions in between them. Jakob pointed out that it is designed this way so that we can keep/encourage a portable representation around strings.
When I changed my mental model to think of stringref as the portable abstraction, I still find the current style odd. One calls new_wtf16 or new_wtf16_arrayetc. and ends up withstringref` where you need to create a view for wtf16. This not very intuitive and the portable representation leaks in a lot places where one doesn't care.
It feels a lot more natural to me to have string_wtf8 and string_wtf16 as the entry points with all necessary APIs (e.g. string_wtf16.new, string_wtf16.encode, string_wtf16.eq etc.) and having an instruction like string_wtf16.as_portable that returns a string_portable when you need to cross the module boundary. And it seems to me in this model, the engine could still perform the delayed encoding/decoding and other similar optimizations that can be done in the original design.
This can also help with avoiding other naming inconsistencies around these types.
Anyway I wanted to move the discussion here and hear your thoughts.