Skip to content

Commit

Permalink
Remove map iteration from list comprehension (#1726)
Browse files Browse the repository at this point in the history
Close #1722.

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
raviqqe and mergify[bot] authored Dec 26, 2022
1 parent fa7b4f3 commit ca21508
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 1,229 deletions.
16 changes: 8 additions & 8 deletions doc/docs/references/language/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,19 +257,13 @@ if value = xs[key] {

#### List comprehension

It iterates over elements in a given list and creates a new list with elements of a given expression.
It iterates a list and creates another list with elements computed by a given expression.

```pen
[number f(x()) for x in xs]
```

You can iterate key-value pairs in a map.

```pen
[number f(key, value) for key, value in map]
```

You can use multiple `for` clauses to iterate multiple lists and maps.
Multiple `for` clauses iterate multiple lists considering all combinations of their elements.

```pen
[number f(y())
Expand All @@ -278,6 +272,12 @@ You can use multiple `for` clauses to iterate multiple lists and maps.
]
```

Multiple lists in a `for` clause iterate them at once.

```pen
[number f(x(), y()) for x, y in xs, ys]
```

You can use `if` clauses to filter elements.

```pen
Expand Down
5 changes: 1 addition & 4 deletions examples/algorithms/knapsack/knapsack.pen
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ packItems = \(states {number: [Item]}, b Bag, is [Item]) [Item] {
is,
)
} else {
best(
[[Item] v for _, v in states],
[Item],
)
best(values(states), [Item])
}
}

Expand Down
50 changes: 0 additions & 50 deletions lib/format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3390,56 +3390,6 @@ mod tests {
.trim(),
);
}

#[test]
fn format_comprehension() {
assert_eq!(
format(
&ListComprehension::new(
types::Reference::new("none", Position::fake()),
Variable::new("none", Position::fake()),
vec![ListComprehensionBranch::new(
vec!["k".into(), "v".into()],
vec![Variable::new("xs", Position::fake()).into()],
None,
Position::fake(),
)],
Position::fake(),
)
.into()
),
"[none none for k, v in xs]"
);
}

#[test]
fn format_multi_line_comprehension() {
assert_eq!(
format(
&ListComprehension::new(
types::Reference::new("none", Position::fake()),
Variable::new("none", line_position(2)),
vec![ListComprehensionBranch::new(
vec!["k".into(), "v".into()],
vec![Variable::new("xs", Position::fake()).into()],
None,
line_position(2)
)],
line_position(1)
)
.into()
),
indoc!(
"
[none
none
for k, v in xs
]
"
)
.trim()
);
}
}

mod record {
Expand Down
16 changes: 0 additions & 16 deletions lib/hir-mir/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ pub enum CompileError {
InvalidVariantType(Type),
MainFunctionNotFound(Position),
MirTypeCheck(mir::analysis::type_check::TypeCheckError),
MixedIterateesInListComprehension(Position),
MultipleMapsInListComprehension(Position),
NewContextFunctionNotFound(Position),
}

Expand Down Expand Up @@ -49,20 +47,6 @@ impl Display for CompileError {
Self::MirTypeCheck(error) => {
write!(formatter, "failed to check types in MIR: {}", error)
}
Self::MixedIterateesInListComprehension(position) => {
write!(
formatter,
"mixed iteratee types in list comprehension\n{}",
position
)
}
Self::MultipleMapsInListComprehension(position) => {
write!(
formatter,
"multiple maps in list comprehension\n{}",
position
)
}
Self::NewContextFunctionNotFound(position) => {
write!(formatter, "new context function not found\n{}", position)
}
Expand Down
157 changes: 0 additions & 157 deletions lib/hir-mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,68 +1127,6 @@ mod tests {
.unwrap();
}

#[test]
fn compile_with_two_branches_of_list_and_map() {
let list_type =
types::List::new(types::Number::new(Position::fake()), Position::fake());
let map_type = types::Map::new(
types::ByteString::new(Position::fake()),
types::Number::new(Position::fake()),
Position::fake(),
);

compile_module(&Module::empty().set_function_definitions(vec![
FunctionDefinition::fake(
"f",
Lambda::new(
vec![
Argument::new("xs", list_type.clone()),
Argument::new("ys", map_type),
],
list_type,
ListComprehension::new(
types::Number::new(Position::fake()),
AdditionOperation::new(
None,
Call::new(
None,
Variable::new("x", Position::fake()),
vec![],
Position::fake(),
),
Variable::new("v", Position::fake()),
Position::fake(),
),
vec![
ListComprehensionBranch::new(
vec!["x".into()],
vec![ListComprehensionIteratee::new(
None,
Variable::new("xs", Position::fake()),
)],
None,
Position::fake(),
),
ListComprehensionBranch::new(
vec!["k".into(), "v".into()],
vec![ListComprehensionIteratee::new(
None,
Variable::new("ys", Position::fake()),
)],
None,
Position::fake(),
),
],
Position::fake(),
),
Position::fake(),
),
false,
),
]))
.unwrap();
}

#[test]
fn compile_condition_with_list_iteratee() {
let list_type =
Expand Down Expand Up @@ -1227,44 +1165,6 @@ mod tests {
.unwrap();
}

#[test]
fn compile_condition_with_map_iteratee() {
let list_type =
types::List::new(types::Number::new(Position::fake()), Position::fake());
let map_type = types::Map::new(
types::ByteString::new(Position::fake()),
types::Number::new(Position::fake()),
Position::fake(),
);

compile_module(&Module::empty().set_function_definitions(vec![
FunctionDefinition::fake(
"f",
Lambda::new(
vec![Argument::new("xs", map_type)],
list_type.clone(),
ListComprehension::new(
list_type.element().clone(),
Variable::new("v", Position::fake()),
vec![ListComprehensionBranch::new(
vec!["k".into(), "v".into()],
vec![ListComprehensionIteratee::new(
None,
Variable::new("xs", Position::fake()),
)],
Some(Boolean::new(true, Position::fake()).into()),
Position::fake(),
)],
Position::fake(),
),
Position::fake(),
),
false,
),
]))
.unwrap();
}

#[test]
fn compile_parallel() {
let list_type =
Expand Down Expand Up @@ -1512,63 +1412,6 @@ mod tests {
.unwrap();
}

#[test]
fn compile_list_comprehension_with_map() {
let map_type = types::Map::new(
types::ByteString::new(Position::fake()),
types::Number::new(Position::fake()),
Position::fake(),
);

compile_module(&Module::empty().set_function_definitions(vec![
FunctionDefinition::fake(
"f",
Lambda::new(
vec![
Argument::new("k", map_type.key().clone()),
Argument::new("v", map_type.value().clone()),
],
types::None::new(Position::fake()),
None::new(Position::fake()),
Position::fake(),
),
false,
),
FunctionDefinition::fake(
"g",
Lambda::new(
vec![Argument::new("x", map_type.clone())],
types::List::new(types::None::new(Position::fake()), Position::fake()),
ListComprehension::new(
types::None::new(Position::fake()),
Call::new(
None,
Variable::new("f", Position::fake()),
vec![
Variable::new("k", Position::fake()).into(),
Variable::new("v", Position::fake()).into(),
],
Position::fake(),
),
vec![ListComprehensionBranch::new(
vec!["k".into(), "v".into()],
vec![ListComprehensionIteratee::new(
None,
Variable::new("x", Position::fake()),
)],
None,
Position::fake(),
)],
Position::fake(),
),
Position::fake(),
),
false,
),
]))
.unwrap();
}

#[test]
fn compile_value_type_not_comparable() {
let map_type = types::Map::new(
Expand Down
Loading

0 comments on commit ca21508

Please sign in to comment.