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

Remove Vec requirement #392

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

therealbnut
Copy link

@therealbnut therealbnut commented Dec 12, 2024

Hi,

I've wanted to be able to store repeated values into a structure of my choosing, instead of a Vec.

This change does that, without needing a temporary intermediate Vec. I believe it will also improve performance as expressions like $(expression ** delim) will currently create a temporary Vec.

Two examples from the tests of how this may improve some usage:

-        = v:( "a" / "\n" )* { v.len() }
+        = v:( "a" / "\n" )* {
+            // Does not store the items.
+            let counter: ItemCounter = v;
+            counter.count()
+        }
     pub rule keyvals() -> HashMap<i64, i64>
-        = kvs:keyval() ++ "\n" {
-            kvs.iter().cloned().collect::<HashMap<i64, i64>>()
-        }
+        = kvs:keyval() ++ "\n" { kvs }

Currently this works by requiring the collection the values are stored into to implement Default and Extend. It may sometimes be necessary to be explicit about the type like the ItemCounter example above. It also may not be able to infer the type of the Extend<T>'s T if it implements it for multiple types, in which case the new-type pattern might be necessary. I don't imagine that will be common though.

Another pattern that might be useful is to be able to instantiate the collection type with some context. I'm not sure of a good way to do this at the moment. I looked into returning an iterator, but you still need to be able to evaluate whether parsing fails before the iterator is evaluated.

@therealbnut
Copy link
Author

therealbnut commented Dec 12, 2024

Instead of Default it may be useful to have our own trait which can be instantiated from the rule parameters (if there are any). Examples of where this might be useful is for something like string interning, or putting the AST in contiguous memory storage for cache efficiency. I'm not sure how you'd achieve this without something like specialisation though. I'll think on this more.

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

Successfully merging this pull request may close these issues.

1 participant