Skip to content
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

Custom Ref/Cow to preserve &'static str? #4

Open
epage opened this issue Mar 25, 2022 · 13 comments
Open

Custom Ref/Cow to preserve &'static str? #4

epage opened this issue Mar 25, 2022 · 13 comments
Labels
enhancement New feature or request

Comments

@epage
Copy link

epage commented Mar 25, 2022

This was also one of they key early features for KString so that liquid could pass around data throughout the program and avoid allocations for this data.

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

I'm not sure I understand. LocalStr and SharedStr are literally copying the &'static str ref on clone so it should be approx. the same speed as copying the ref itself (one extra machine word - 24 bytes vs 16 byte fat pointer)

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

Maybe you are talking about onboarding? If you use from_static or local_str!/shared_str! these are compile time wrapper over the literal. Zero cost. They interop with other Local/Shared strings.

@epage
Copy link
Author

epage commented Mar 25, 2022

KStringCow and KStringRef are roughly

enum KStringCow<'s> {
    Owned(Box<str>),
    Literal(&'static str),
    Borrowed(&'s str),
}

enum KStringRef<'s> {
    Literal(&'static str),
    Borrowed(&'s str),
}

This let's me have functions that return references that I can turn back into owned types without losing track of the 'static lifetime.

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

Might need to see an example sometime. For some reason I'm just not getting it. If you borrow, you'd need to have a copy of the owned item or else the borrow wouldn't borrow. If you have a static...well, you have a static.

Are you talking something like my conditional ownership feature? (a side effect of using Rc/Arc) Essentially I advocate passing by &SharedStr as you can always clone() but the clone is just a ref count bump never an allocation/copy (another reason why I like Rc/Arc over Box I should add).

@epage
Copy link
Author

epage commented Mar 25, 2022

In liquid, some data is dynamically generated and some comes from a previous allocation. I could still use a Cow<'s, SharedStr>. I'll have to think about the trade offs of that vs a custom Cow.

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

Ok, if you can point me to a worked example or spot in the source that illustrates this. I'm not sure I 100% follow the use case (because in my mind, FlexStr is the antithesis of Cow in RO scenarios so tryign to understand why you'd want ot bring cow back into it, For example: why not pass &SharedStr instead? If you need an owned copy, clone, else use as is)

@epage
Copy link
Author

epage commented Mar 25, 2022

In "liquid", you can directly access the elements of an Array or the members of an Object. There are also some implicit fields, .first, .last, and .size. Rather than store an extra element in the Object and Array for .size, .size is dynamically generated; there is no data to make a reference to.

See https://github.com/cobalt-org/liquid-rust/blob/master/crates/core/src/model/find.rs#L161

@epage
Copy link
Author

epage commented Mar 25, 2022

but like I said, a Cow<'s, SharedStr> might work

@epage
Copy link
Author

epage commented Mar 25, 2022

For more context on liquid, see https://shopify.github.io/liquid/

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

I was thinking the other way around (passing in, not returning). I can definitely see use cases where you want to return a 'view' into something but don't necessarily want to copy it... or maybe you have conditional ownership (like what you are doing it seems).

Early on I played with ideas like having a 3rd and 4th type for this (I called it BStringy before someone took my stringy name and I went with FlexStr). I also played with the idea of integrating borrowing into my main type as a 4th variant but I didn't want the user to have to have deal with type annotations for non-borrowed use (I know they scare a lot of new Rust users).

I'll do more thinking on what makes sense, but not against bringing that idea back.

@epage
Copy link
Author

epage commented Mar 25, 2022

(I know they scare a lot of new Rust users).

I would assume a new Rust user would generally not be using one of these crates :)

However, a couple items down on my priority list is creating yet-another string type, one focused on ease of use and general performance. The idea is to have as few lifetimes in this API as possible, so each string function would return an owned type. See https://docs.rs/eztd/latest/eztd/struct.String.html and https://epage.github.io/blog/2021/09/learning-rust/

@nu11ptr
Copy link
Owner

nu11ptr commented Mar 25, 2022

You kinda just described my goal with FlexStr :-) Just not done yet. Well, not exactly I guess. I'm going more for easy String replacement with better performance in immutable usage scenarios, not focusing on ease of use particularly.

@nu11ptr nu11ptr added the enhancement New feature or request label Mar 26, 2022
@nu11ptr
Copy link
Owner

nu11ptr commented Mar 26, 2022

I figured out how to support borrowed strings. In hindsight it was obvious. Will be in next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants