-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: ADR for string as alias or type #3
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion option 2 is the best path forward, not hiding what's underneath makes sure the developer is conscious of what they're doing.
In the future we could tackle this level of abstraction at a library level.
I feel like option 2 is hiding what's underneath. In this case A lot of the strengths of option 2 make assumptions about string opcodes available in the AVM, which I think is rather unlikely. It's not clear to me when you'd want to do this on-chain and I think any use case would be an edge case rather than the norm. I look at it similar to the AVM JSON opcodes. This is why I think option 1 makes sense and if we ever want to have a string class we make it available and people can construct it from bytes, but it should not be the "default" class for strings because the operations will be expensive (even if implemented as an opcode) and should be avoided by most developers. An example for why it'd be nice to have an alias rather than a separate class Option 1hasUnitName(unitName: str, asset: Asset) {
return asset.unitName === unitName
} Option 2hasUnitName(unitName: str, asset: Asset) {
return asset.unitName.bytes === unitName
} A developer naturally thinks of unit names as stings, but it would be erroneous to represent them as such because it's not enforced. Thus they might be confused why they need to I know this stuff seems inconsequential but similar things have been a point of friction in both PyTeal/Beaker and Algorand Python |
You can't get the length of a UTF-8 string, let alone index it, on the AVM without it being an O(N) operation in terms of op codes. Logically, a UTF-8 string of 3 characters(*) has a length of 3, but the number of bytes to encode that can be anywhere from 3 to 12, and there's no simple way to compute that without iterating. (*) even this is simplifying things by assuming each character means code-point, rather than grapheme. |
1a35a59
to
e5e54b5
Compare
Yes that is exactly my point. We won't be implementing character-based functions, thus there is no functional difference between the bytes class and the string class regardless of which option we choose. Also this ADR seems to be duplicating |
There's a bit of crossover, I think |
Then we should modify that ADR to only focus on bytes. We basically now have two ADRs for the same thing. Some of the information is in that ADR and some in this and it's rather confusing.
@robdmoore, @Loedn, and myself discussed this and reached a general consensus that a modified prototype is acceptable. We can simply not support the character-based functions and add additional functions for byte-based operations. Even byte-based functions are also seldomly used on-chain with strings. |
…ng a separate ADR to document that choice
Tristan was walking me through yesterday and showed what it looked like to have strings with no prototype modification. I'm not opposed to prototype modification, but it's definitely fair to consider having it vs not needing it given the downside of prototype modification is you need to have a side-effect import. Given we believe people seldomly do byte stuff with strings, the extra (fairly idiomatic JavaScript) It's also really easy to add prototype stuff after initial implementation too so we can see how it feels? |
No description provided.