Skip to content

Implement filter builtin function#63

Open
friendlymatthew wants to merge 2 commits intomainfrom
filter
Open

Implement filter builtin function#63
friendlymatthew wants to merge 2 commits intomainfrom
filter

Conversation

@friendlymatthew
Copy link
Member

This PR implements the filter() builtin function that filters elements from an iterable based on a predicate

Note: the implementation returns a list (following the pattern of other iterator-returning builtins like enumerate() and zip() for simplicyt). Currently, only builtin functions are supported as predicates which matches the existing limitation in sorted() with the key param

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 22, 2026

Merging this PR will not alter performance

✅ 13 untouched benchmarks


Comparing filter (f0746a3) with main (c75f160)

Open in CodSpeed

@friendlymatthew friendlymatthew changed the title Add filter() builtin function Implement filter builtin function Jan 23, 2026
Comment on lines 35 to 64
let (mut positional, kwargs) = args.into_parts();

if !kwargs.is_empty() {
for (k, v) in kwargs {
k.drop_with_heap(heap);
v.drop_with_heap(heap);
}

for v in positional {
v.drop_with_heap(heap);
}

return Err(SimpleException::new_msg(ExcType::TypeError, "filter() does not support keyword arguments").into());
}

// Check we have exactly 2 positional arguments
let positional_len = positional.len();
if positional_len != 2 {
for v in positional {
v.drop_with_heap(heap);
}
return Err(SimpleException::new_msg(
ExcType::TypeError,
format!("filter() expected 2 arguments, got {positional_len}"),
)
.into());
}

let function = positional.next().expect("positional must have 2 elements");
let iterable = positional.next().expect("positional must have 2 elements");
Copy link
Member

Choose a reason for hiding this comment

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

I think you can use get_one_two_args for this.

Copy link
Member Author

@friendlymatthew friendlymatthew Jan 23, 2026

Choose a reason for hiding this comment

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

very nice, we can probably update a bunch of other builtin functions like sorted that manually parse args atm

Copy link
Member

Choose a reason for hiding this comment

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

Yup. Claude can go though and fix them all I guess.

Copy link
Member

Choose a reason for hiding this comment

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

we also need tests for a non-callable discriminator, like filter(4, [1, 2])

Copy link
Member Author

Choose a reason for hiding this comment

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

See crates/monty/test_cases/builtin__filter_not_callable.py

@friendlymatthew friendlymatthew force-pushed the filter branch 2 times, most recently from fe37fa4 to 7629de6 Compare January 23, 2026 19:28
Copy link
Member

@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

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

Looking good, but I forgot we also need support for use defined functions which might require a bit of logic change, look at list.sort for an example.

@friendlymatthew
Copy link
Member Author

Looking good, but I forgot we also need support for use defined functions which might require a bit of logic change, look at list.sort for an example.

I followed list.sort's implementation. Though seems like list.sort doesn't handle user defined functions atm:

Value::DefFunction(_) | Value::ExtFunction(_) | Value::Ref(_) => {
// User-defined or external functions require VM frame management
elem.drop_with_heap(heap);
Err(ExcType::type_error(
"list.sort() key argument must be a builtin function (user-defined functions not yet supported)",
))

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

❌ Patch coverage is 80.80808% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/monty/src/builtins/filter.rs 80.61% 14 Missing and 5 partials ⚠️

📢 Thoughts on this report? Let us know!

@samuelcolvin
Copy link
Member

We need use the new recursion guard, and fix the case of user defined functions.

I don't mind on the order.

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.

2 participants