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

Use span to simplify looping #34

Merged
merged 1 commit into from
Aug 1, 2024

Conversation

amomchilov
Copy link

@amomchilov amomchilov commented Aug 1, 2024

Motivation

C lacks a standard abstraction for representing a buffer/array, so you're always just slinging around a separate pointer and size.

In C++, we have std::vector, which brings us nice things like being able to range-for over it (for (auto& thing : things) { ... }). However, std::vector owns its buffer, and there's no way to create one from a C buffer without a copy.

To bridge the two worlds, C++ 20 offers std::span which gives you back an object with an iterable view over memory that it doesn't own. This let you easily wrap a pre-existing pointer+size, and get an iterable view over it. We're on C++ 17, so we can't use it, but there's absl::span, which can fill the gap.

Test plan

This is a pure refactor, and this codepath is already tested.

@amomchilov amomchilov marked this pull request as ready for review August 1, 2024 19:34
@amomchilov amomchilov requested review from egiurleo, a team and KaanOzkan August 1, 2024 19:57
@amomchilov amomchilov self-assigned this Aug 1, 2024
Comment on lines -234 to 239
pm_node_t *node = stmts->body.nodes[i];
for (auto& node : stmts) {
unique_ptr<parser::Node> convertedStmt = convertPrismToSorbet(node, parser, gs);
sorbetStmts.emplace_back(std::move(convertedStmt));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could also do:

std::transform(stmts.begin(), stmts.end(), back_inserter(sorbetStmts), [](auto& node) { 
  return convertPrismToSorbet(node, parser, gs);
});

right? The return value optimization should move the return value into the sorbet statements node.

Copy link
Author

@amomchilov amomchilov Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm usually a huge fan of stream operations like map, but how did C++ manage to make map so verbose/heavy that even I almost think the manual for loop is nicer. It doesn't even call .reserve() for you. 😭

Anyways, std::transform seemed to be pretty rare in the codebase (only 2 usages). Is there some style preference against it? There's also absl::c_transform, which has 3 usages. Overall it looks like it was avoided, for some reason

Copy link
Author

@amomchilov amomchilov Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW would that lambda need a capture list for pm_parser_t *parser and core::GlobalState &gs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, probably avoided because it is so ugly compared to for loop, as you said.


for (int i = 0; i < stmts->body.size; i++) {
pm_node_t *node = stmts->body.nodes[i];
for (auto& node : stmts) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

@egiurleo egiurleo merged commit 4e8cfc7 into proj-parsing-w-prism-in-sorbet Aug 1, 2024
1 check passed
@egiurleo egiurleo deleted the Alex/absl-span branch August 1, 2024 21:41
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.

4 participants