Skip to content

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

✅ 11 untouched benchmarks


Comparing filter (7629de6) with main (6c96230)

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

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.

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.

3 participants